今天一天的时间,成功使用flume把日志扇入ElasticSearch中,并运行Kibana实现日志的初步展示,记录于此。
1:ES集群的搭建不予赘述,可参考:如何搭建ES集群
2:Flume与ES协同
这一部分堪称是重中之重,主要的时间就是花费在这上面了。
flume的sink里,其实是有ElasticSearchSink的,我的打算,也是想直接使用其实现功能即可,后发现,ES使用的版本过高,但又不想照网上那样说的恢复到以前的1.x版本,于是,自己想办法把flume内的flume-ng-elasticsearch-sink的jar包修改后重新打了一份,成功运行起来。
废话少说,进入正题。
JDK版本:1.8.0_111
Flume版本:1.6.0;很多人可能疑惑如何找到flume的版本,可以参照lib目录下那些jar包,很容易看到自己的flume版本的。
ElasticSearch:5.6.2。
下面是详细步骤:
1:flume-ng-elasticsearch-sink-1.6.0.jar
这个包,就在flume下的lib内,负责的就是ElasticSearchSink的功能,从官网上找到对应的flume版本,将源代码全部下载下来。
我是从github上下载的,参照我的版本,找到了flume-1.6对应的branch,全部代码拷贝下来之后,作为maven工程导入到开发工具,我用的是Eclipse。
导入之后,目录结构应该大致如此,修改build-path为1.8即可。
导入完毕之后,不会主动报错,但是我们必须按照自己的配置来,让它报错,从报错的地方一点点去改。
首先,修改pom.xml文件。
4.0.0
flume-ng-sinks
org.apache.flume
1.6.0
org.apache.flume.flume-ng-sinks
flume-ng-elasticsearch-sink
Flume NG ElasticSearch Sink
org.apache.rat
apache-rat-plugin
org.apache.flume
flume-ng-sdk
org.apache.flume
flume-ng-core
org.slf4j
slf4j-api
org.elasticsearch
elasticsearch
5.6.2
org.elasticsearch.client
transport
5.6.2
org.apache.httpcomponents
httpclient
junit
junit
test
org.slf4j
slf4j-log4j12
test
commons-lang
commons-lang
com.google.guava
guava
org.apache.httpcomponents
httpclient
org.mockito
mockito-all
test
com.alibaba
fastjson
1.2.44
里面我改动过的地方,都有注释;因为我需要连接的ES是5.6.2版本的,所以把对应的牵涉到ES的版本,全部更换为了5.6.2。
2:修改之后,大片大片的开始报错了,这里,test报的错不用管它,打包时候skip tests即可。
下面的步骤顺序不是固定的,但是所有步骤进行下来,最终应该是全正确的。
1:ContentBuilderUtil类会报错:不太记得改动的地方了,直接附上源码
* Licensed to the Apache Software Foundation (ASF) under one
package org.apache.flume.sink.elasticsearch;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
* Utility methods for using ElasticSearch {@link XContentBuilder}
*/
public class ContentBuilderUtil {
private static final Charset charset = Charset.defaultCharset();
private ContentBuilderUtil() {
}
public static void appendField(XContentBuilder builder, String field,
byte[] data) throws IOException {
XContentType contentType = XContentFactory.xContentType(data);
if (contentType == null) {
addSimpleField(builder, field, data);
} else {
addComplexField(builder, field, contentType, data);
}
}
public static void addSimpleField(XContentBuilder builder,
String fieldName, byte[] data) throws IOException {
builder.field(fieldName, new String(data, charset));
}
public static void addComplexField(XContentBuilder builder,
String fieldName, XContentType contentType, byte[] data)
throws IOException {
XContentParser parser = XContentFactory.xContent(contentType)
.createParser(NamedXContentRegistry.EMPTY, data);
parser.nextToken();
// Add the field name, but not the value.
builder.field(fieldName);
try {
// This will add the whole parsed content as the value of the field.
builder.copyCurrentStructure(parser);
} catch (Exception ex) {
// If we get an exception here the most likely cause is nested JSON
// that
// can't be figured out in the body. At this point just push it
// through
// as is, we have already added the field so don't do it again
builder.endObject();
builder.field(fieldName, new String(data, charset));
} finally {
if (parser != null) {
parser.close();
}
}
}
}
2:ElasticSearchEventSerializer会报错
* Licensed to the Apache Software Foundation (ASF) under one
package org.apache.flume.sink.elasticsearch;
import java.io.IOException;
/**
* Interface for an event serializer which serializes the headers and body of an
* event to write them to ElasticSearch. This is configurable, so any config
* params required should be taken through this.
*/
public interface ElasticSearchEventSerializer extends Configurable,
ConfigurableComponent {
public static final Charset charset = Charset.defaultCharset();
/**
* Return an {@link BytesStream} made up of the serialized flume event
*
* @param event
* The flume event to serialize
* @return A {@link BytesStream} used to write to ElasticSearch
* @throws IOException
* If an error occurs during serialization
*/
abstract XContentBuilder getContentBuilder(Event event) throws IOException;
}
3:ElasticSearchLogStashEventSerializer
* Licensed to the Apache Software Foundation (ASF) under one
package org.apache.flume.sink.elasticsearch;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
* Serialize flume events into the same format LogStash uses
*
* This can be used to send events to ElasticSearch and use clients such as
* Kabana which expect Logstash formated indexes
*
* * {
* "@timestamp": "2010-12-21T21:48:33.309258Z",
* "@tags": [ "array", "of", "tags" ],
* "@type": "string",
* "@source": "source of the event, usually a URL."
* "@source_host": ""
* "@source_path": ""
* "@fields":{
* # a set of fields for this event
* "user": "jordan",
* "command": "shutdown -r":
* }
* "@message": "the original plain-text message"
* }
*
*
* If the following headers are present, they will map to the above logstash
* output as long as the logstash fields are not already present.
*
* * timestamp: long -> @timestamp:Date
* host: String -> @source_host: String
* src_path: String -> @source_path: String
* type: String -> @type: String
* source: String -> @source: String
*
*
* @see https
* ://github.com/logstash/logstash/wiki/logstash%27s-internal-message-
* format
*/
public class ElasticSearchLogStashEventSerializer implements
ElasticSearchEventSerializer {
@Override
public XContentBuilder getContentBuilder(Event event) throws IOException {
XContentBuilder builder = jsonBuilder().startObject();
appendBody(builder, event);
appendHeaders(builder, event);
return builder;
}
private void appendBody(XContentBuilder builder, Event event)
throws IOException, UnsupportedEncodingException {
byte[] body = event.getBody();
ContentBuilderUtil.appendField(builder, "@message", body);
}
private void appendHeaders(XContentBuilder builder, Event event)
throws IOException {
Map headers = new HashMap(
event.getHeaders());
String timestamp = headers.get("timestamp");
if (!StringUtils.isBlank(timestamp)
&& StringUtils.isBlank(headers.get("@timestamp"))) {
long timestampMs = Long.parseLong(timestamp);
builder.field("@timestamp", new Date(timestampMs));
}
String source = headers.get("source");
if (!StringUtils.isBlank(source)
&& StringUtils.isBlank(headers.get("@source"))) {
ContentBuilderUtil.appendField(builder, "@source",
source.getBytes(charset));
}
String type = headers.get("type");
if (!StringUtils.isBlank(type)
&& StringUtils.isBlank(headers.get("@type"))) {
ContentBuilderUtil.appendField(builder, "@type",
type.getBytes(charset));
}
String host = headers.get("host");
if (!StringUtils.isBlank(host)
&& StringUtils.isBlank(headers.get("@source_host"))) {
ContentBuilderUtil.appendField(builder, "@source_host",
host.getBytes(charset));
}
String srcPath = headers.get("src_path");
if (!StringUtils.isBlank(srcPath)
&& StringUtils.isBlank(headers.get("@source_path"))) {
ContentBuilderUtil.appendField(builder, "@source_path",
srcPath.getBytes(charset));
}
builder.startObject("@fields");
for (String key : headers.keySet()) {
byte[] val = headers.get(key).getBytes(charset);
ContentBuilderUtil.appendField(builder, key, val);
}
builder.endObject();
}
@Override
public void configure(Context context) {
// NO-OP...
}
@Override
public void configure(ComponentConfiguration conf) {
// NO-OP...
}
}
4:ElasticSearchTransportClient
* Licensed to the Apache Software Foundation (ASF) under one
package org.apache.flume.sink.elasticsearch.client;
import static org.apache.flume.sink.elasticsearch.ElasticSearchSinkConstants.DEFAULT_PORT;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Map;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.EventDeliveryException;
import org.apache.flume.sink.elasticsearch.ElasticSearchEventSerializer;
import org.apache.flume.sink.elasticsearch.ElasticSearchIndexRequestBuilderFactory;
import org.apache.flume.sink.elasticsearch.IndexNameBuilder;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.mortbay.util.ajax.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
public class ElasticSearchTransportClient implements ElasticSearchClient {
public static final Logger logger = LoggerFactory
.getLogger(ElasticSearchTransportClient.class);
private InetSocketTransportAddress[] serverAddresses;
private ElasticSearchEventSerializer serializer;
private ElasticSearchIndexRequestBuilderFactory indexRequestBuilderFactory;
private BulkRequestBuilder bulkRequestBuilder;
private Client client;
@VisibleForTesting
InetSocketTransportAddress[] getServerAddresses() {
return serverAddresses;
}
@VisibleForTesting
void setBulkRequestBuilder(BulkRequestBuilder bulkRequestBuilder) {
this.bulkRequestBuilder = bulkRequestBuilder;
}
/**
* Transport client for external cluster
*
* @param hostNames
* @param clusterName
* @param serializer
*/
public ElasticSearchTransportClient(String[] hostNames, String clusterName,
ElasticSearchEventSerializer serializer) {
configureHostnames(hostNames);
this.serializer = serializer;
openClient(clusterName);
}
public ElasticSearchTransportClient(String[] hostNames, String clusterName,
ElasticSearchIndexRequestBuilderFactory indexBuilder) {
configureHostnames(hostNames);
this.indexRequestBuilderFactory = indexBuilder;
openClient(clusterName);
}
/**
* Local transport client only for testing
*
* @param indexBuilderFactory
*/
// public ElasticSearchTransportClient(
// ElasticSearchIndexRequestBuilderFactory indexBuilderFactory) {
// this.indexRequestBuilderFactory = indexBuilderFactory;
// openLocalDiscoveryClient();
// }
/**
* Local transport client only for testing
*
* @param serializer
*/
// public ElasticSearchTransportClient(ElasticSearchEventSerializer
// serializer) {
// this.serializer = serializer;
// openLocalDiscoveryClient();
// }
/**
* Used for testing
*
* @param client
* ElasticSearch Client
* @param serializer
* Event Serializer
*/
public ElasticSearchTransportClient(Client client,
ElasticSearchEventSerializer serializer) {
this.client = client;
this.serializer = serializer;
}
/**
* Used for testing
*
* @param client
* ElasticSearch Client
* @param serializer
* Event Serializer
*/
public ElasticSearchTransportClient(Client client,
ElasticSearchIndexRequestBuilderFactory requestBuilderFactory)
throws IOException {
this.client = client;
requestBuilderFactory.createIndexRequest(client, null, null, null);
}
private void configureHostnames(String[] hostNames) {
logger.warn(Arrays.toString(hostNames));
serverAddresses = new InetSocketTransportAddress[hostNames.length];
for (int i = 0; i < hostNames.length; i++) {
String[] hostPort = hostNames[i].trim().split(":");
String host = hostPort[0].trim();
int port = hostPort.length == 2 ? Integer.parseInt(hostPort[1]
.trim()) : DEFAULT_PORT;
// 此处加以修改了
try {
serverAddresses[i] = new InetSocketTransportAddress(
InetAddress.getByName(host), port);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
@Override
public void close() {
if (client != null) {
client.close();
}
client = null;
}
/**
*
* @description:将输出的异常转换为字符串
* @author:yuzhao.yang
* @param:
* @return:
* @time:2017年6月7日 上午10:27:00
*/
public String transfer(Exception e) throws Exception {
// e.printStackTrace();
ByteArrayOutputStream buf = new ByteArrayOutputStream();
e.printStackTrace(new PrintWriter(buf, true));
String expMessage = buf.toString();
buf.close();
if (null != expMessage) {
return expMessage;
} else {
return null;
}
}
@Override
public void addEvent(Event event, IndexNameBuilder indexNameBuilder,
String indexType, long ttlMs) throws Exception {
if (bulkRequestBuilder == null) {
bulkRequestBuilder = client.prepareBulk();
}
IndexRequestBuilder indexRequestBuilder = null;
if (indexRequestBuilderFactory == null) {
Map map = null;
try {
String body = new String(event.getBody());
logger.error("数据结果:" + body);
map = (Map) JSON.parse(body);
} catch (Exception e) {
logger.error("getContentBuilder异常:" + transfer(e));
}
indexRequestBuilder = client.prepareIndex(
indexNameBuilder.getIndexName(event), indexType).setSource(
map);
} else {
indexRequestBuilder = indexRequestBuilderFactory
.createIndexRequest(client,
indexNameBuilder.getIndexPrefix(event), indexType,
event);
}
if (ttlMs > 0) {
indexRequestBuilder.setTTL(ttlMs);
}
bulkRequestBuilder.add(indexRequestBuilder);
}
@Override
public void execute() throws Exception {
try {
BulkResponse bulkResponse = bulkRequestBuilder.execute()
.actionGet();
if (bulkResponse.hasFailures()) {
throw new EventDeliveryException(
bulkResponse.buildFailureMessage());
}
} finally {
bulkRequestBuilder = client.prepareBulk();
}
}
/**
* Open client to elaticsearch cluster
*
* @param clusterName
*/
private void openClient(String clusterName) {
Settings settings = Settings.builder().put("cluster.name", clusterName)
.build();
// TransportClient transportClient = new TransportClient(settings);
// for (InetSocketTransportAddress host : serverAddresses) {
// transportClient.addTransportAddress(host);
// }
TransportClient transportClient = null;
for (InetSocketTransportAddress host : serverAddresses) {
if (null == transportClient) {
transportClient = new PreBuiltTransportClient(settings)
.addTransportAddress(host);
} else {
transportClient = transportClient.addTransportAddress(host);
}
}
if (client != null) {
client.close();
}
client = transportClient;
}
/*
* FOR TESTING ONLY...
*
* Opens a local discovery node for talking to an elasticsearch server
* running in the same JVM
*/
// private void openLocalDiscoveryClient() {
// logger.info("Using ElasticSearch AutoDiscovery mode");
// Node node = NodeBuilder.nodeBuilder().client(true).local(true).node();
// if (client != null) {
// client.close();
// }
// client = node.client();
// }
@Override
public void configure(Context context) {
// To change body of implemented methods use File | Settings | File
// Templates.
}
}
这个类,我主要是在addEvent内部做出了一点修改,因为直接使用XContentBuilder总是报错,于是使用了map格式来进行数据转换。
其他基本没什么需要修改得了。
可能有些修改不太记得了,这里,我把修改后的代码放在了github上:修改后的代码地址
这里需要注意:我的数据是map格式的,所以针对transportclient做出了如上图的修改,其他数据格式不同的,可以思考一下自己的实现方式。
代码修改完成之后,直接打包,虽然pom.xml没有打包插件,但是按照默认的打包逻辑进行就可以了,会自动下载maven插件进行打包的。
打包后体积很小,因为很多jar包并没有打入进去,所以,接下来我们还要针对flume下的jar包进行修改和替换,这里,直接附上我的flume下的所有jar包记录,方便大家使用:
apache-log4j-extras-1.1.jar flume-ng-kafka-sink-1.6.0.jar kite-data-core-1.0.0.jar parquet-avro-1.4.1.jar
async-1.4.0.jar flume-ng-log4jappender-1.6.0.jar kite-data-hbase-1.0.0.jar parquet-column-1.4.1.jar
asynchbase-1.5.0.jar flume-ng-morphline-solr-sink-1.6.0.jar kite-data-hive-1.0.0.jar parquet-common-1.4.1.jar
avro-1.7.4.jar flume-ng-node-1.6.0.jar kite-hadoop-compatibility-1.0.0.jar parquet-encoding-1.4.1.jar
avro-ipc-1.7.4.jar flume-ng-sdk-1.6.0.jar lang-mustache-client-5.6.2.jar parquet-format-2.0.0.jar
commons-cli-1.2.jar flume-scribe-source-1.6.0.jar libthrift-0.9.0.jar parquet-generator-1.4.1.jar
commons-codec-1.8.jar flume-spillable-memory-channel-1.6.0.jar log4j-1.2.17.jar parquet-hadoop-1.4.1.jar
commons-collections-3.2.1.jar flume-thrift-source-1.6.0.jar log4j-api-2.9.1.jar parquet-hive-bundle-1.4.1.jar
commons-compress-1.4.1.jar flume-tools-1.6.0.jar lucene-analyzers-common-6.6.1.jar parquet-jackson-1.4.1.jar
commons-dbcp-1.4.jar flume-twitter-source-1.6.0.jar lucene-backward-codecs-6.6.1.jar percolator-client-5.6.2.jar
commons-io-2.1.jar gson-2.2.2.jar lucene-core-6.6.1.jar plugin-cli-5.6.2.jar
commons-jexl-2.1.1.jar guava-11.0.2.jar lucene-grouping-6.6.1.jar protobuf-java-2.5.0.jar
commons-lang-2.5.jar HdrHistogram-2.1.9.jar lucene-highlighter-6.6.1.jar reindex-client-5.6.2.jar
commons-logging-1.1.1.jar hppc-0.7.1.jar lucene-join-6.6.1.jar scala-library-2.10.1.jar
commons-pool-1.5.4.jar httpclient-4.2.1.jar lucene-memory-6.6.1.jar securesm-1.1.jar
curator-client-2.6.0.jar httpcore-4.1.3.jar lucene-misc-6.6.1.jar serializer-2.7.2.jar
curator-framework-2.6.0.jar irclib-1.10.jar lucene-queries-6.6.1.jar servlet-api-2.5-20110124.jar
curator-recipes-2.6.0.jar jackson-annotations-2.3.0.jar lucene-queryparser-6.6.1.jar slf4j-api-1.6.1.jar
derby-10.8.2.2.jar jackson-core-2.8.6.jar lucene-sandbox-6.6.1.jar slf4j-log4j12-1.6.1.jar
elasticsearch-5.6.2.jar jackson-core-asl-1.9.3.jar lucene-spatial3d-6.6.1.jar snakeyaml-1.15.jar
flume-avro-source-1.6.0.jar jackson-databind-2.3.1.jar lucene-spatial-6.6.1.jar snappy-java-1.1.0.jar
flume-dataset-sink-1.6.0.jar jackson-dataformat-cbor-2.8.6.jar lucene-spatial-extras-6.6.1.jar spatial4j-0.6.jar
flume-file-channel-1.6.0.jar jackson-dataformat-smile-2.8.6.jar lucene-suggest-6.6.1.jar t-digest-3.0.jar
flume-hdfs-sink-1.6.0.jar jackson-dataformat-yaml-2.8.6.jar mapdb-0.9.9.jar transport-5.6.2.jar
flume-hive-sink-1.6.0.jar jackson-mapper-asl-1.9.3.jar metrics-core-2.2.0.jar transport-netty3-client-5.6.2.jar
flume-irc-sink-1.6.0.jar java-version-checker-5.6.2.jar mina-core-2.0.4.jar transport-netty4-client-5.6.2.jar
flume-jdbc-channel-1.6.0.jar jetty-6.1.26.jar netty-3.5.12.Final.jar twitter4j-core-3.0.3.jar
flume-jms-source-1.6.0.jar jetty-util-6.1.26.jar netty-buffer-4.1.13.Final.jar twitter4j-media-support-3.0.3.jar
flume-kafka-channel-1.6.0.jar jna-4.4.0-1.jar netty-codec-4.1.13.Final.jar twitter4j-stream-3.0.3.jar
flume-kafka-source-1.6.0.jar joda-time-2.1.jar netty-common-4.1.13.Final.jar velocity-1.7.jar
flume-ng-auth-1.6.0.jar joda-time-2.9.5.jar netty-handler-4.1.13.Final.jar xalan-2.7.2.jar
flume-ng-configuration-1.6.0.jar jopt-simple-3.2.jar netty-resolver-4.1.13.Final.jar xercesImpl-2.9.1.jar
flume-ng-core-1.6.0.jar jopt-simple-5.0.2.jar netty-transport-4.1.13.Final.jar xml-apis-1.3.04.jar
flume-ng-elasticsearch-sink-1.6.0.jar jsr305-1.3.9.jar opencsv-2.3.jar xz-1.0.jar
flume-ng-embedded-agent-1.6.0.jar jts-1.13.jar paranamer-2.3.jar zkclient-0.3.jar
flume-ng-hbase-sink-1.6.0.jar kafka_2.10-0.8.1.1.jar parent-join-client-5.6.2.jar
我这里首先把ElasticSearch下lib目录内的所有jar包都放了过来,然后对于自己的项目,把那些不重复的jar包全部抛了过去,最终正常运行起来。
查看日志,发现数据的确成功输送到了ES中,完美解决。
3:Kibana简单使用
我这里,使用的是:kibana-5.6.2-linux-x86_64,大家可以直接在ES官网中找到下载;解压,修改配置文件,这里把配置文件附上:
# Kibana is served by a back end server. This setting specifies the port to use.
server.port: 5601
# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "0.0.0.0"
# Enables you to specify a path to mount Kibana at if you are running behind a proxy. This only affects
# the URLs generated by Kibana, your proxy is expected to remove the basePath value before forwarding requests
# to Kibana. This setting cannot end in a slash.
#server.basePath: ""
# The maximum payload size in bytes for incoming server requests.
#server.maxPayloadBytes: 1048576
# The Kibana server's name. This is used for display purposes.
#server.name: "your-hostname"
# The URL of the Elasticsearch instance to use for all your queries.
elasticsearch.url: "http://192.168.100.34:9200"
# When this setting's value is true Kibana uses the hostname specified in the server.host
# setting. When the value of this setting is false, Kibana uses the hostname of the host
# that connects to this Kibana instance.
#elasticsearch.preserveHost: true
# Kibana uses an index in Elasticsearch to store saved searches, visualizations and
# dashboards. Kibana creates a new index if the index doesn't already exist.
kibana.index: ".kibana"
# The default application to load.
#kibana.defaultAppId: "discover"
# If your Elasticsearch is protected with basic authentication, these settings provide
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
# is proxied through the Kibana server.
#elasticsearch.username: "user"
#elasticsearch.password: "pass"
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
# These settings enable SSL for outgoing requests from the Kibana server to the browser.
#server.ssl.enabled: false
#server.ssl.certificate: /path/to/your/server.crt
#server.ssl.key: /path/to/your/server.key
# Optional settings that provide the paths to the PEM-format SSL certificate and key files.
# These files validate that your Elasticsearch backend uses the same key files.
#elasticsearch.ssl.certificate: /path/to/your/client.crt
#elasticsearch.ssl.key: /path/to/your/client.key
# Optional setting that enables you to specify a path to the PEM file for the certificate
# authority for your Elasticsearch instance.
#elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ]
# To disregard the validity of SSL certificates, change this setting's value to 'none'.
#elasticsearch.ssl.verificationMode: full
# Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of
# the elasticsearch.requestTimeout setting.
#elasticsearch.pingTimeout: 1500
# Time in milliseconds to wait for responses from the back end or Elasticsearch. This value
# must be a positive integer.
#elasticsearch.requestTimeout: 30000
# List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side
# headers, set this value to [] (an empty list).
#elasticsearch.requestHeadersWhitelist: [ authorization ]
# Header names and values that are sent to Elasticsearch. Any custom headers cannot be overwritten
# by client-side headers, regardless of the elasticsearch.requestHeadersWhitelist configuration.
#elasticsearch.customHeaders: {}
# Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable.
#elasticsearch.shardTimeout: 0
# Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying.
#elasticsearch.startupTimeout: 5000
# Specifies the path where Kibana creates the process ID file.
#pid.file: /var/run/kibana.pid
# Enables you specify a file where Kibana stores log output.
#logging.dest: stdout
# Set the value of this setting to true to suppress all logging output.
#logging.silent: false
# Set the value of this setting to true to suppress all logging output other than error messages.
#logging.quiet: false
# Set the value of this setting to true to log all events, including system usage information
# and all requests.
#logging.verbose: false
# Set the interval in milliseconds to sample system and process performance
# metrics. Minimum is 100ms. Defaults to 5000.
#ops.interval: 5000
# The default locale. This locale can be used in certain circumstances to substitute any missing
# translations.
#i18n.defaultLocale: "en"
主要是server.host和elasticsearch.url稍微修改了下,很容易看懂。
启动,成功。
浏览器通过:hostIp:5601。
恭喜你,看到了Kibana的启动界面,至于kibana的使用,那就是另一篇文章的事情了。