Deploy_elk_5.1.1_on_centos_6.8
OS: CentOS release 6.8 (Final)
ELK Version: 5.1.1
架构如图(需3台server):
配置ELK源
# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
# vim /etc/zypp/repos.d/elasticsearch.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
安装 filebeat
# yum install -y filebeat
## 启动/停止:
# chkconfig --add filebeat
# service filebeat start
# service filebeat stop
配置filebeat, 将nginx,catalina等日志发送到Redis
# grep -v '^#' /etc/filebeat/filebeat.yml | grep -v '^$' |grep -v ' #'
filebeat.prospectors:
- input_type: log
paths:
- /var/log/nginx/spt/*.log
exclude_files: [".gz$"]
- input_type: log
paths:
- /opt/apache-tomcat/logs/catalina.201*.out
- input_type: log
paths:
- /opt/apache-tomcat/logs/localhost_access_log.201*.txt
output.redis:
enabled: true
hosts: ["172.16.2.5:6379"] # Redis server
key: spt-web # 要对应Logstash端的redis配置处的key
datatype: channel
timeout: 5s
path.data: /data/elk_data/filebeat
logging.to_files: true
logging.files:
安装Redis服务
# yum install -y redis
## 启动/停止:
# chkconfig -add redis
# service redis start
# service redis stop
由于此redis服务在独立的一台服务器上,所以修改其监听的地址:
# vim /etc/redis.conf
port 6379
bind 127.0.0.1 172.16.2.5 192.168.2.42
安装Logstash
NOTE: Logstash requires Java 8. Java 9 is not supported. Use the official Oracle distribution or an open-source distribution such as OpenJDK.
# yum install -y logstash
测试
1)基本的输入输出
# /usr/share/logstash/bin/logstash -e 'input { stdin{} } output { stdout{} }'
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs to console
The stdin plugin is now waiting for input:
16:24:55.329 [[main]-pipeline-manager] INFO logstash.pipeline - Starting pipeline {"id"=>"main", "pipeline.workers"=>8, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>1000}
16:24:55.355 [[main]-pipeline-manager] INFO logstash.pipeline - Pipeline main started
16:24:55.452 [Api Webserver] INFO logstash.agent - Successfully started Logstash API endpoint {:port=>9600}
2016-12-08T08:25:04.788Z docker.spt.com hello
hello jeremy
2016-12-08T08:25:13.955Z docker.spt.com hello jeremy
2016-12-08T08:25:15.649Z docker.spt.com
2016-12-08T08:25:15.754Z docker.spt.com
"hello jeremy"
2016-12-08T08:25:19.705Z docker.spt.com "hello jeremy"
2)使用rubydebug详细输出
# /usr/share/logstash/bin/logstash -e 'input { stdin{} } output { stdout{ codec => rubydebug} }'
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs to console
The stdin plugin is now waiting for input:
16:26:26.361 [[main]-pipeline-manager] INFO logstash.pipeline - Starting pipeline {"id"=>"main", "pipeline.workers"=>8, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>1000}
16:26:26.369 [[main]-pipeline-manager] INFO logstash.pipeline - Pipeline main started
16:26:26.451 [Api Webserver] INFO logstash.agent - Successfully started Logstash API endpoint {:port=>9600}
{
"@timestamp" => 2016-12-08T08:26:58.550Z,
"@version" => "1",
"host" => "docker.spt.com",
"message" => "",
"tags" => []
}
jeremy
{
"@timestamp" => 2016-12-08T08:27:05.844Z,
"@version" => "1",
"host" => "docker.spt.com",
"message" => "jeremy",
"tags" => []
}
"hello jeremy"
{
"@timestamp" => 2016-12-08T08:27:22.020Z,
"@version" => "1",
"host" => "docker.spt.com",
"message" => "\"hello jeremy\"",
"tags" => []
}
3)创建logstash配置文件,测试从redis服务读取数据:
# vim /etc/logstash/conf.d/redis_spt-web.conf
input {
redis {
data_type => "pattern_channel"
#data_type => "list"
key => "spt-web"
host => "192.168.2.42"
port => 6379
threads => 5
}
}
output { # 将数据直接输出到stdout
stdout {}
}
启动logstash,同时确保filebeat端的服务已启动并做了如上filebeat输出数据到redis的配置
# /usr/share/logstash/bin/logstash -f redis_spt-web.conf
此时,当前终端应该会在刷从redis读出的数据
配置Logstash长期运行:
关于logstash长期运行,可以用screen会话做,也可以用supervisor。如下是配置supervisor来管理logstash的启停:
# yum -y install supervisor
## 启动/停止:
# chkconfig --add supervisord
# service supervisord start
# service supervisord stop
在supervisord.conf文件中添加Logstash配置
# vim /etc/supervisord.conf
...
[program:logstash_01]
environment=LS_HEAP_SIZE=5000m
directory=/usr/share/logstash
command=/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/syslog.conf -w 10 -l /var/log/logstash/syslog.log
#[program:logstash_02]
#environment=LS_HEAP_SIZE=5000m
#directory=/usr/share/logstash
#command=/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/logstash_02.conf -w 10 -l /var/log/logstash/logstash_02.log
启动supervisord
# service supervisord start
检查Logstash进程
# ps aux |grep -v grep | grep logstash
root 7496 10.8 6.1 3664448 491504 ? Sl 14:46 0:53 /usr/bin/java -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -Djava.awt.headless=true -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -Xmx1g -Xms256m -Xss2048k -Djffi.boot.library.path=/usr/share/logstash/vendor/jruby/lib/jni -Xbootclasspath/a:/usr/share/logstash/vendor/jruby/lib/jruby.jar -classpath : -Djruby.home=/usr/share/logstash/vendor/jruby -Djruby.lib=/usr/share/logstash/vendor/jruby/lib -Djruby.script=jruby -Djruby.shell=/bin/sh org.jruby.Main --1.9 /usr/share/logstash/lib/bootstrap/environment.rb logstash/runner.rb -f /etc/logstash/conf.d/logstash_01.conf -w 10 -l /var/log/logstash/logstash_01.log
安装ElasticSearch
Elasticsearch requires Java 8 or later. Use the official Oracle distribution or an open-source distribution such as OpenJDK.
# yum install -y elasticsearch
## 启动/停止:
# chkconfig --add elasticsearch
# service elasticsearch start
# service elasticsearch stop
配置Elasticsearch
The RPM also has a system configuration file (/etc/sysconfig/elasticsearch), which allows you to set the following parameters:
RPM方式安装的目录结构:
默认ES读取配置文件为:/etc/elasticsearch/elasticsearch.yml
# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: spt-elk
node.name: node-1
path.data: /data/elk_data/es
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 127.0.0.1
http.port: 9200
测试:
# curl -X GET http://localhos:9200
{
"name" : "node-1",
"cluster_name" : "spt-elk",
"cluster_uuid" : "fBSlJILQS8yWej1bQhRFAw",
"version" : {
"number" : "5.0.2",
"build_hash" : "f6b4951",
"build_date" : "2016-11-24T10:07:18.101Z",
"build_snapshot" : false,
"lucene_version" : "6.2.1"
},
"tagline" : "You Know, for Search"
}
安装Kibana
# yum install -y kibana
## 启动/停止:
# chkconfig --add kibana
# service kibana start
# service kibana stop
方式安装的目录结构
配置Kibana
kibana安装完后,几乎不需要修改配置文件。默认的配置连接的elasticsearch就是http://localhost:9200
安装nginx,代理kibana
# yum install -y nginx
# vim /etc/nginx/conf.d/kibana.conf
server {
listen 80;
server_name ls.spt.com;
# auth_basic "Restricted Access";
# auth_basic_user_file /etc/nginx/htpasswd.users;
location / {
proxy_pass http://localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
重启nginx
添加ls.spt.com
相关解析,访问kibana页面,创建索引
优化filebeat对多行日志的处理
多行日志:如tomcat,java程序的日志等
参考官方文档:
Managing Multiline Messages
tomcat的日志输出如下:
2016-12-20 15:34:20,762 [nioEventLoopGroup-3-5] INFO com.autrade.stage.netty.StageClientHandler - Remote data back: #groupId: 1973064082
java.lang.NullPointerException
at com.autrade.spt.gate.controller.SptGateControllerBase.tryThrowExceptionForJson(SptGateControllerBase.java:79)
at com.autrade.spt.gate.controller.SptRemotingServiceController.handleService(SptRemotingServiceController.java:101)
at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
2016-12-20 15:34:20,767 [nioEventLoopGroup-3-5] INFO com.autrade.stage.netty.StageClientHandler - Remote data back: #groupId: 1973064082
java.lang.NullPointerException
at com.autrade.spt.gate.controller.SptGateControllerBase.tryThrowExceptionForJson(SptGateControllerBase.java:79)
at com.autrade.spt.gate.controller.SptRemotingServiceController.handleService(SptRemotingServiceController.java:101)
at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
2016-12-20 15:34:20,770 [http-bio-8090-exec-1298] INFO com.autrade.stage.remoting.RemoteWrapper - [THD 3876]: borrowed conn from /172.16.1.3:9717
2016-12-20 15:48:16,303 INFO [org.jasig.cas.CentralAuthenticationServiceImpl] - <ServiceTicket [ST-1154-0V5islag7lX5iX5JSVNm-cas] does not exist.>
针对这种日志格式,修改filebeat.yml
...
- input_type: log
paths:
- /opt/apache-tomcat/logs/catalina.201*.out
multiline.pattern: '^[[:alpha:]]|^[[:space:]]'
multiline.negate: false
multiline.match: after
multiline.timeout: 10s
...
重启filebeat服务
End !