大多情况下,我们可能都习惯了使用linux指令查看日志,很多时候一句简简单单的tail、grep能定位绝大多数问题。但是面临复杂的目录结构和分布式系统产生的“分布式日志文件”,如果还要我们一个一个去查日志,就会耗费很多没必要的时间。可以利用ELK这套组件快速搭建一个日志系统。注意此文仅针对可能很多情况下格式不确定的业务日志,对于某些组件日志我们有更好的可视化实践方式,可以参考此系列的其他文章。
应用场景和实施方案
对于一个日志系统,我们要确认我们的诉求,在不同的场景下采用不同的收集方式:
是否是分布式系统需要合并多个节点的日志。如果需要,则需要用分布式组件收集并合并日志,这也是一个日志系统最基本的要求;
所采集的日志是是否要归档并持久化存储以便于随时查看。如果需要,则需要一个持久化的容器来压缩和保存这些日志;
现有的命令行查看日志的方式是否能满足我们的要求,是否需要日志可视化系统。如果需要,我们需要用ELK全部组件来实现日志可视化;
日志的查看权限是否要加以限制。如果需要,我们要限制服务本身的日志访问并搭建一个符合要求的日志代理系统。
以上的处理方式可以说是按需求不同程度自上至下复杂度递增的,可以根据需要程度选择不同的实施方案,需要注意的是,很多情况下业务日志的可视化都很不尽人意,因为对技术人员而言,shell指令很多时候反而更加好用。可视化系统的低效率(相比shell,它是必然效率更低的)和局限性(为了某些规范数据丢掉了原有的日志格式)很多时候不适合业务日志,此时搭建一个日志代理系统可能更符合要求。
基于Filebeat收集日志
日志的采集可以采用Filebeat,轻量快速、内存消耗小,假设我们有多个节点的服务,在每个服务中不熟一份filebeat,编辑filebeat的配置文件,发送给下游的logstash,这里节选配置部分:
#=========================== Filebeat inputs ============================= filebeat.inputs: # Each - is an input. Most options can be set at the input level, so # you can use different inputs for various configurations. # Below are the input specific configurations. - type: log # Change to true to enable this input configuration. enabled: true # Paths that should be crawled and fetched. Glob based paths. paths: - /home/ubuntu/*/log.out #要收集的日志目录 # Exclude lines. A list of regular expressions to match. It drops the lines that are # matching any regular expression from the list. #exclude_lines: ['^DBG'] # Include lines. A list of regular expressions to match. It exports the lines that are # matching any regular expression from the list. #include_lines: ['^ERR', '^WARN'] # Exclude files. A list of regular expressions to match. Filebeat drops the files that # are matching any regular expression from the list. By default, no files are dropped. exclude_files: ['/home/ubuntu/test/log.out'] #指定排除的文件列表,可以是正则 tail_files: true #从当前文件末尾继续读 tags: ["test"] # Optional additional fields. These fields can be freely picked # to add additional information to the crawled log files for filtering #fields: # level: debug # review: 1 ### Multiline options # Multiline can be used for log messages spanning multiple lines. This is common # for Java Stack Traces or C-Line Continuation # The regexp Pattern that has to be matched. The example pattern matches all lines starting with [ #multiline.pattern: ^\[ # Defines if the pattern set under pattern should be negated or not. Default is false. #multiline.negate: false # Match can be set to "after" or "before". It is used to define if lines should be append to a pattern # that was (not) matched before or after or as long as a pattern is not matched based on negate. # Note: After is the equivalent to previous and before is the equivalent to to next in Logstash #multiline.match: after #================================ Outputs ===================================== #----------------------------- Logstash output -------------------------------- output.logstash: # The Logstash hosts hosts: ["135.0.0.1:5044"] #指定logstash的端口 # Optional SSL. By default is off. # List of root certificates for HTTPS server verifications #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] # Certificate for SSL client authentication #ssl.certificate: "/etc/pki/client/cert.pem" # Client Certificate Key #ssl.key: "/etc/pki/client/cert.key"
基于Logstash接收&处理收集日志
创建Logstash的配置文件,并启动Logstash,随后启动Filebeat,配置文件中,指定监听的端口和整合后的文件存储路径:
input { beats { port => 5044 #监听5044端口 } } output { #指定 file { #文件存储目录,参考了原来的存储目录 #resource是filebeat所传输的文件原目录,所以分布式系统中,只要各节点文件路径一样,便会整合起来 path => "/weblog/%{source}" codec => line { format => "%{message}" #因为留存的的是文件,所以以原内容保存 } } }
这里没有定义日志到es的存储而是仅仅存储在了文件中,我们可以前往相应的文件目录直接使用Shell指令查看。
注意,因为多个Filebeat实例间不能保证发送的顺序性,所以其实我们所看到的日志文件在小范围时间内可能是乱序的(单个节点日志文件的顺序性倒是保证了),在查看时可能需要兼顾这一点。