ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
通过上面对ELK简单的介绍,我们知道了ELK字面意义包含的每个开源框架的功能。市面上很多开发只要提到ELK能够一致说出它是一个日志分析架构技术栈总称,但实际上ELK不仅仅适用于日志分析,它还可以支持其它任何数据分析和收集的场景,日志分析和收集只是更具有代表性。并非唯一性。我们本教程主要也是围绕通过ELK如何搭建一个生产级的日志分析平台来讲解ELK的使用。
参考文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.1/getting-started-install.html (注:页面右边菜单栏Release notes 可看到各版本信息,目前最新版本7.5)
参考文档: https://www.elastic.co/guide/en/elasticsearch/reference/7.1/settings.html
集群模式:
分别配置每个节点的elasticsearch.yml
cluster.name: francis-es # es集群名字
node.name: node01 # es节点名字,node01/node02/node03
node.master: true # 指定该节点是否有资格被选举成为master,默认是true
node.data: true # 指定该节点是否存储索引数据,默认为true
network.host: 192.168.2.101 # ip地址,192.168.2.101/192.168.2.102/192.168.2.103
http.port: 9200 # es服务的端口号
discovery.zen.ping.unicast.hosts: [“192.168.2.101”, “192.168.2.102”, “192.168.2.103”] # 配置自动发现
discovery.zen.minimum_master_nodes: 2 # 最少N个有master资格的节点,默认为1
可选配置:
index.number_of_shards: 5
设置默认索引分片个数,默认为5片。
index.number_of_replicas: 1
设置默认索引副本个数,默认为1个副本。
path.conf: /path/to/conf
设置配置文件的存储路径,默认是es根目录下的config文件夹。
path.data: /path/to/data
设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开,例:
path.data: /path/to/data1,/path/to/data2
path.work: /path/to/work
设置临时文件的存储路径,默认是es根目录下的work文件夹。
path.logs: /path/to/logs
设置日志文件的存储路径,默认是es根目录下的logs文件夹
path.plugins: /path/to/plugins
设置插件的存放路径,默认是es根目录下的plugins文件夹
bootstrap.mlockall: true
设置为true来锁住内存。因为当jvm开始swapping时es的效率 会降低,所以要保证它不swap,可以把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。 同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过ulimit -l unlimited
命令。
network.bind_host: 192.168.2.101
设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。
network.publish_host: 192.168.2.101
设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。
network.host: 192.168.2.101
这个参数是用来同时设置bind_host和publish_host上面两个参数。
transport.tcp.port: 9300
设置节点间交互的tcp端口,默认是9300。
transport.tcp.compress: true
设置是否压缩tcp传输时的数据,默认为false,不压缩。
http.port: 9200
设置对外服务的http端口,默认为9200。
http.max_content_length: 100mb
设置内容的最大容量,默认100mb
http.enabled: false
是否使用http协议对外提供服务,默认为true,开启。
gateway.type: local
gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的HDFS,和amazon的s3服务器,其它文件系统的设置方法下次再详细说。
gateway.recover_after_nodes: 1
设置集群中N个节点启动时进行数据恢复,默认为1。
gateway.recover_after_time: 5m
设置初始化数据恢复进程的超时时间,默认是5分钟。
gateway.expected_nodes: 2
设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。
cluster.routing.allocation.node_initial_primaries_recoveries: 4
初始化数据恢复时,并发恢复线程的个数,默认为4。
cluster.routing.allocation.node_concurrent_recoveries: 2
添加删除节点或负载均衡时并发恢复线程的个数,默认为4。
indices.recovery.max_size_per_sec: 0
设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。
indices.recovery.concurrent_streams: 5
设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。
discovery.zen.minimum_master_nodes: 1
设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
discovery.zen.ping.timeout: 3s
设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。
discovery.zen.ping.multicast.enabled: false
设置是否打开多播发现节点,默认是true。
discovery.zen.ping.unicast.hosts: [“host1”, “host2:port”, “host3[portX-portY]”]
设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
4. 可在安装目录的config/目录下编辑jvm.options设置es所需的堆内存,默认1G
5. 官方建议不要随意动这些配置,具体参考: https://www.elastic.co/guide/en/elasticsearch/guide/master/_don_8217_t_touch_these_settings.html
6. 如果安装elasticsearch-head插件,需要在config/elasticsearch.yml中配置如下内容:
http.cors.enabled: true
http.cors.allow-origin: “*” # 解决跨域问题
启动:
停止:
问题1:
max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
解决方法:
问题2:
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
解决方法:
问题3:
Java HotSpot™ 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error=‘Cannot allocate memory’ (errno=12)
解决方法:
问题4:
max number of threads [3818] for user [es] is too low, increase to at least [4096]
解决办法:
问题5:
the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
解决方法:
问题6:
Exception in thread “main” java.nio.file.AccessDeniedException: /usr/local/elasticsearch /config/jvm.options
解决办法:
这种是权限问题,一般这种权限问题执行: chown -R francis:francis /usr/local/elasticsearch 即可解决
elasticsearch-head插件是ES的Web管理端,可通过此插件来管理ES集群等。
elasticsearch-head插件要求Node.js环境,官网: https://nodejs.org/en/download/
参考文档: https://github.com/mobz/elasticsearch-head/
#解决跨域问题
http.cors.enabled: true
http.cors.allow-origin: ""
7. 重启es
8. npm install -g grunt-cli
9. npm install [email protected] --ignore-scripts (不执行可能会报错)
10. npm install
11. vim /usr/local/elasticsearch-head/_site/app.js
12. 命令行模式下搜索:this.base_uri,修改为:this.base_uri = this.config.base_uri || this.prefs.get(“app-base_uri”) || “http://192.168.2.101:9200”;
13. vim /usr/local/elasticsearch-head/Gruntfile.js
在port: 9100 上面加一行配置:
hostname: ‘192.168.2.101’, #注意后面有个逗号,后者hostname: ‘’
14. npm run start
15. 浏览器打开: http://192.168.2.101:9100/
参考文档:https://www.elastic.co/guide/en/beats/filebeat/7.1/filebeat-installation.html
filebeat.inputs:
- type: log
enabled: true
paths:
- /log/francis/build/*.json # 采集logbak框架打印的json日志,推荐这种方式
#- /log/francis/*.log # 也可配置采集.log日志,日志路径为项目中所配置的路径
setup.kibana:
host: "192.168.2.101:5601"
output.logstash:
hosts: ["192.168.2.101:5044"]
setup.template.settings:
index.number_of_shards: 3
默认输出到elasticsearch,需要将output.elasticsearch 部分注释掉
启动:
停止:
假设有日志文件/app/logs/francis/francis.json和/app/logs/nginx/access.log,我们需要对两个目录下的文件作出不同处理
filebeat.inputs:
- type: log
enabled: true
paths:
-/app/logs/francis/francis.json
tags: [“francis”] #数组,可以输入多个,后续可以利用tags作出不同处理
fields:
filetype: json # 可以用来区分文件类型,作用和tags相似
fields_under_root: true
- type: log
enabled: true
paths:
- /app/logs/nginx/access.log
tags: [“nginx”]
fields: # 自定义字段
filetype: syslog
fields_under_root: true # 设置为true,意为将自定义字段设为文档中的顶级字段
output.logstash:
enabled: true
hosts: ["192.168.2.101:5044"]
input {
beats {
host => "0.0.0.0"
port => 5044
}
}
filter {
if [filetype] == "json" {
json {
source => "message"
remove_field => ["beat","offset","tags"]
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
}
if [filetype] == "syslog" {
#处理逻辑
}
if “francis”in [tags] {
#处理逻辑
}
}
output {
if [filetype] == "syslog" {
elasticsearch {
hosts => ["192.168.2.101:9200"]
index => "test-nginx-%{+YYYY.MM.dd}"
}
} else if [filetype] == "json" {
elasticsearch {
hosts => ["192.168.2.101:9200"]
index => "test-francis -%{+YYYY.MM.dd}"
}
}
}
注:在后续Kibana上建立Index Pattern时,如果index pattern一栏输入test-*,那么上述两个index都能匹配上,如果所有应用打印日志的格式一致时,可以使用这种方式,避免重复建立index pattern,查看时可以根据应用名来筛选本应用的日志,这个可以根据实际需求而定。
参考文档: https://www.elastic.co/guide/en/logstash/7.1/installing-logstash.html
进入配置文件目录: cd /usr/local/logstash/config,两种格式日志解析一种即可,推荐解析json格式日志
input {
#beat插件,监听5044端口
beats {
port => "5044"
}
}
filter {
#我们filebeat采集的是json格式的文件,然后会把日志存于message字段中,我们使用json插件解析message字段
json {
source => "message"
}
#将@timestamp替换为打印日志的时间,默认是采集日志的时间
date{
match => ["logTime ", "YYYY-MM-dd HH:mm:ss.SSS", "ISO8601"]
}
#使用mutate插件,将message的内容替换为rest+ stackTrace,rest等字段跟logbak-spring.xml中配置的保持一致就行了,字段命名可以跟示例不同
mutate {
replace => { "message" => "%{rest}%{stackTrace}" }
}
#使用插件删除你不想要显示在kibana中的字段
mutate {
remove_field => [ “logTime”, "rest", "stackTrace", "@version", "agent", "host", "input", "ecs", "log" ]
}
}
#输出到es
output {
elasticsearch {
# 可以输入多个es地址
hosts => ["http://192.168.2.101:9200"]
#存于es中的索引,在kibana中创建索引的时候,你可以输入test-*、test-francis-*等来匹配这个索引,默认logstash-%{+YYYY.MM.dd}
index => "test-francis-%{+YYYY.MM.dd}"
}
}
input {
#beat插件,监听5044端口
beats {
port => "5044"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
}
}
output {
#输出到控制台,这里不再示例输出到es
stdout{codec=>rubydebug}
}
multiline.pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:'
multiline.negate: false
multiline.match: after
java.lang.NullPointerException: null
at com.example.demo.controller.StudentController.error(StudentController.java:38)
at com.example.demo.controller.StudentController F a s t C l a s s B y S p r i n g C G L I B FastClassBySpringCGLIB FastClassBySpringCGLIB7356fabf.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy C g l i b M e t h o d I n v o c a t i o n . i n v o k e J o i n p o i n t ( C g l i b A o p P r o x y . j a v a : 769 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . R e f l e c t i v e M e t h o d I n v o c a t i o n . p r o c e e d ( R e f l e c t i v e M e t h o d I n v o c a t i o n . j a v a : 163 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . C g l i b A o p P r o x y CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)atorg.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)atorg.springframework.aop.framework.CglibAopProxyCglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy C g l i b M e t h o d I n v o c a t i o n . p r o c e e d ( C g l i b A o p P r o x y . j a v a : 747 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . a d a p t e r . A f t e r R e t u r n i n g A d v i c e I n t e r c e p t o r . i n v o k e ( A f t e r R e t u r n i n g A d v i c e I n t e r c e p t o r . j a v a : 55 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . R e f l e c t i v e M e t h o d I n v o c a t i o n . p r o c e e d ( R e f l e c t i v e M e t h o d I n v o c a t i o n . j a v a : 186 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . C g l i b A o p P r o x y CglibMethodInvocation.proceed(CglibAopProxy.java:747) at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy CglibMethodInvocation.proceed(CglibAopProxy.java:747)atorg.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)atorg.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)atorg.springframework.aop.framework.CglibAopProxyCglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy C g l i b M e t h o d I n v o c a t i o n . p r o c e e d ( C g l i b A o p P r o x y . j a v a : 747 ) a t o r g . s p r i n g f r a m e w o r k . a o p . i n t e r c e p t o r . E x p o s e I n v o c a t i o n I n t e r c e p t o r . i n v o k e ( E x p o s e I n v o c a t i o n I n t e r c e p t o r . j a v a : 93 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . R e f l e c t i v e M e t h o d I n v o c a t i o n . p r o c e e d ( R e f l e c t i v e M e t h o d I n v o c a t i o n . j a v a : 186 ) a t o r g . s p r i n g f r a m e w o r k . a o p . f r a m e w o r k . C g l i b A o p P r o x y CglibMethodInvocation.proceed(CglibAopProxy.java:747) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy CglibMethodInvocation.proceed(CglibAopProxy.java:747)atorg.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)atorg.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)atorg.springframework.aop.framework.CglibAopProxyCglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.framework.CglibAopProxy D y n a m i c A d v i s e d I n t e r c e p t o r . i n t e r c e p t ( C g l i b A o p P r o x y . j a v a : 689 ) a t c o m . e x a m p l e . d e m o . c o n t r o l l e r . S t u d e n t C o n t r o l l e r DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) at com.example.demo.controller.StudentController DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)atcom.example.demo.controller.StudentController E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB 9 b 98 b b b 8. e r r o r ( < g e n e r a t e d > ) a t s u n . r e f l e c t . N a t i v e M e t h o d A c c e s s o r I m p l . i n v o k e 0 ( N a t i v e M e t h o d ) a t s u n . r e f l e c t . N a t i v e M e t h o d A c c e s s o r I m p l . i n v o k e ( N a t i v e M e t h o d A c c e s s o r I m p l . j a v a : 62 ) a t s u n . r e f l e c t . D e l e g a t i n g M e t h o d A c c e s s o r I m p l . i n v o k e ( D e l e g a t i n g M e t h o d A c c e s s o r I m p l . j a v a : 43 ) a t j a v a . l a n g . r e f l e c t . M e t h o d . i n v o k e ( M e t h o d . j a v a : 498 ) a t o r g . s p r i n g f r a m e w o r k . w e b . m e t h o d . s u p p o r t . I n v o c a b l e H a n d l e r M e t h o d . d o I n v o k e ( I n v o c a b l e H a n d l e r M e t h o d . j a v a : 190 ) a t o r g . s p r i n g f r a m e w o r k . w e b . m e t h o d . s u p p o r t . I n v o c a b l e H a n d l e r M e t h o d . i n v o k e F o r R e q u e s t ( I n v o c a b l e H a n d l e r M e t h o d . j a v a : 138 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . a n n o t a t i o n . S e r v l e t I n v o c a b l e H a n d l e r M e t h o d . i n v o k e A n d H a n d l e ( S e r v l e t I n v o c a b l e H a n d l e r M e t h o d . j a v a : 106 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . a n n o t a t i o n . R e q u e s t M a p p i n g H a n d l e r A d a p t e r . i n v o k e H a n d l e r M e t h o d ( R e q u e s t M a p p i n g H a n d l e r A d a p t e r . j a v a : 888 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . a n n o t a t i o n . R e q u e s t M a p p i n g H a n d l e r A d a p t e r . h a n d l e I n t e r n a l ( R e q u e s t M a p p i n g H a n d l e r A d a p t e r . j a v a : 793 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . A b s t r a c t H a n d l e r M e t h o d A d a p t e r . h a n d l e ( A b s t r a c t H a n d l e r M e t h o d A d a p t e r . j a v a : 87 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t . d o D i s p a t c h ( D i s p a t c h e r S e r v l e t . j a v a : 1040 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t . d o S e r v i c e ( D i s p a t c h e r S e r v l e t . j a v a : 943 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . F r a m e w o r k S e r v l e t . p r o c e s s R e q u e s t ( F r a m e w o r k S e r v l e t . j a v a : 1006 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . F r a m e w o r k S e r v l e t . d o G e t ( F r a m e w o r k S e r v l e t . j a v a : 898 ) a t j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t . s e r v i c e ( H t t p S e r v l e t . j a v a : 634 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . F r a m e w o r k S e r v l e t . s e r v i c e ( F r a m e w o r k S e r v l e t . j a v a : 883 ) a t j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t . s e r v i c e ( H t t p S e r v l e t . j a v a : 741 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . i n t e r n a l D o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 231 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . d o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 166 ) a t o r g . s p r i n g f r a m e w o r k . c l o u d . s l e u t h . i n s t r u m e n t . w e b . E x c e p t i o n L o g g i n g F i l t e r . d o F i l t e r ( E x c e p t i o n L o g g i n g F i l t e r . j a v a : 50 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . i n t e r n a l D o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 193 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . d o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 166 ) a t b r a v e . s e r v l e t . T r a c i n g F i l t e r . d o F i l t e r ( T r a c i n g F i l t e r . j a v a : 65 ) a t o r g . s p r i n g f r a m e w o r k . c l o u d . s l e u t h . i n s t r u m e n t . w e b . T r a c e W e b S e r v l e t A u t o C o n f i g u r a t i o n 9b98bbb8.error(
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:394)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:253)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:175)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol C o n n e c t i o n H a n d l e r . p r o c e s s ( A b s t r a c t P r o t o c o l . j a v a : 861 ) a t o r g . a p a c h e . t o m c a t . u t i l . n e t . N i o E n d p o i n t ConnectionHandler.process(AbstractProtocol.java:861) at org.apache.tomcat.util.net.NioEndpoint ConnectionHandler.process(AbstractProtocol.java:861)atorg.apache.tomcat.util.net.NioEndpointSocketProcessor.doRun(NioEndpoint.java:1579)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor W o r k e r . r u n ( T h r e a d P o o l E x e c u t o r . j a v a : 624 ) a t o r g . a p a c h e . t o m c a t . u t i l . t h r e a d s . T a s k T h r e a d Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread Worker.run(ThreadPoolExecutor.java:624)atorg.apache.tomcat.util.threads.TaskThreadWrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
启动:
停止:
参考文档: https://www.elastic.co/guide/en/kibana/current/introduction.html
参考文档: https://www.elastic.co/guide/en/kibana/current/start-stop.html
启动:
停止:
引入以下配置,日志中出现traceId等需要用到spring-cloud-sleuth
net.logstash.logback
logstash-logback-encoder
5.0
runtime
logback-core
ch.qos.logback
org.springframework.cloud
spring-cloud-starter-sleuth
2.1.6.RELEASE
org.projectlombok
lombok
1.16.6
org.springframework.cloud
spring-cloud-dependencies
Greenwich.SR3
pom
import
6.2. 配置logback-spring.xml
DEBUG
${CONSOLE_LOG_PATTERN}
UTF-8
${LOG_HOME}/francis.log
${LOG_HOME}/francis.%d{yyyy-MM-dd}.gz
7
${CONSOLE_LOG_PATTERN}
UTF-8
${LOG_HOME}/${LOG_FILE}.json
${LOG_HOME}/${LOG_FILE}.json.%d{yyyy-MM-dd}.gz
7
UTC
{
"logLevel": "%level",
"appName": "${springAppName:-}",
"traceId": "%X{X-B3-TraceId:-}",
"spanId": "%X{X-B3-SpanId:-}",
"parentId": "%X{X-B3-ParentSpanId:-}",
"exportable": "%X{X-Span-Export:-}",
"pid": "${PID:-}",
"thread": "%thread",
"className": "%logger{40}",
"rest": "%message",
"stackTrace": "%exception{10}" # 错误日志的堆栈信息,显示10行
}
https://github.com/francisoyc/elk