ElasticSearch学习笔记之二:Filebeat日志收集

1. nginx日志收集

1.1 原生日志

  • E:Elasticsearch
  • F:Filebeat
  • K:Kibana
yml 复制代码
[root@host3 ~]# vim 04-nginx-to-es.yml 
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/nginx/access.log*
  tags: ["host3","nginx","access"]		# 打上标签,便于后期输出

- type: log
  paths:
    - /var/log/nginx/error.log*
  tags: ["host3","nginx","error"]
  fields:
    hostname: host3.test.com
    service: http
  fields_under_root: true       # 将fields字段提到最高级别

output.elasticsearch:
  hosts: ["http://192.168.19.101:9200","http://192.168.19.102:9200","http://192.168.19.103:9200"]
  indices:
    - index: "host3-nginx-access-%{+yyyy.MM.dd}"
      when.contains:
        tags: "access"
    - index: "host3-nginx-error-%{+yyyy.MM.dd}"
      when.contains:
        tags: "error"

# 关闭索引的生命周期,若开启则上面的index配置会被忽略
setup.ilm.enabled: false
# 设置索引模板的名称
setup.template.name: "host3-nginx"
# 设置索引模板的匹配模式
setup.template.pattern: "host3-nginx-*"
# 覆盖已有的索引模板
setup.template.overwrite: false
setup.template.settings:
  index.number_of_shards: 3
  index.number_of_replicas: 1

1.2 JSON格式日志

从nginx端输出的日志就已经分割好了,filebeat只需要接收并提取json格式的信息,发送给Elasticsearch

首先要修改输入端,调整nginx日志输出格式

[root@host3 ~]# vim /etc/nginx/nginx.conf

http {
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  filebeat_json  '{"@timestap":"$time_iso8601",'
                                '"host":"$server_addr",'
                                '"clientip":"$remote_addr",'
                                '"size":$body_bytes_sent,'
                                '"responstime":$request_time,'
                                '"upstreamtime":"$upstream_response_time",'
                                '"upstreamhost":"$upstream_addr",'
                                '"http_host":"$host",'
                                '"uri":"$uri",'
                                '"domain":"$host",'
                                '"xff":"$http_x_forward_for",'
                                '"referer":"$http_referer",'
                                '"tcp_xff":"$proxy_protocol_addr",'
                                '"http_user_agent":"$http_user_agent",'
                                '"status":"$status"}';

    #access_log  /var/log/nginx/access.log  main;
    access_log  /var/log/nginx/access.log  filebeat_json;
    ...
}

测试下日志格式是否正确

[root@host3 ~]# tail -n1 /var/log/nginx/access.log 
{"@timestap":"2022-09-12T17:09:39+08:00","host":"192.168.19.103","clientip":"192.168.19.1","size":0,"responstime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"192.168.19.103","uri":"/index.html","domain":"192.168.19.103","xff":"-","referer":"-","tcp_xff":"-","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36","status":"304"}

可以使用上例中的配置文件,但是得到的日志同样是把抓取的日志都放到message里面,这就失去了调整格式的意义,因此我们需要将消息中的字段全部打散成多个键值,然后放到Elasticsearch中,在Kibana中查看时,可以查看任意的键值。

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/nginx/access.log*
  tags: ["host3","nginx","access"]
  json.keys_under_root: true

在Kibana中查看:

1.3 filebeat实现日志格式化

采用filebeat的模块将日志分割成json格式,不修改nginx的原生日志格式

模块的存放位置

[root@host3 ~]# ls /etc/filebeat/modules.d/
activemq.yml.disabled          haproxy.yml.disabled          osquery.yml.disabled
apache.yml.disabled            ibmmq.yml.disabled            panw.yml.disabled
auditd.yml.disabled            icinga.yml.disabled           pensando.yml.disabled
awsfargate.yml.disabled        iis.yml.disabled              postgresql.yml.disabled
aws.yml.disabled               imperva.yml.disabled          proofpoint.yml.disabled

修改配置文件:

yml 复制代码
# 去掉原来所有的input内容
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml   # 指定模块配置文件的路径,path.config是filebeat的安装目录
  reload.enabled: true                   # 开启热加载功能,默认为false

查看所有的可用模块

[root@host3 ~]# filebeat -c ~/05-nginx-to-es.yml modules list
Enabled:

Disabled:
activemq
apache
auditd
aws
...

启用模块

[root@host3 ~]# filebeat -c ~/05-nginx-to-es.yml modules enable nginx
Enabled nginx
[root@host3 ~]# filebeat -c ~/05-nginx-to-es.yml modules list
Enabled:
nginx

模块开启后需要配置nginx模块对应的配置文件:

[root@host3 ~]# vim /etc/filebeat/modules.d/nginx.yml 

- module: nginx
  # Access logs
  access:
    enabled: true
    var.paths: ["/var/log/nginx/access.log*"]
    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    #var.paths:

  # Error logs
  error:
    enabled: true
    var.paths: ["/var/log/nginx/error.log*"]

Kibana中查看:

2. Tomcat日志

2.1 使用模块

[root@host3 ~]# filebeat -c ~/06-tomcat-to-es.yml modules enable tomcat
Enabled tomcat

[root@host3 ~]# vim /etc/filebeat/modules.d/tomcat.yml

- module: tomcat
  log:
    enabled: true

    # Set which input to use between udp (default), tcp or file.
     var.input: file
    # var.syslog_host: localhost
    # var.syslog_port: 9501

    # Set paths for the log files when file input is used.
    # var.paths:
       - /var/log/tomcat/*.txt

2.2 调整原生日志

将原生日志调整为json格式输出

xml 复制代码
[root@host3 ~]# vim /etc/tomcat/server.xml

<!--日志的配置通常在最后部分-->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="{&quot;requestTime&quot;:&quot;%t&quot;,&quot;clientIP&quot;:&quot;%h&quot;,&quot;threadID&quot;:&quot;%I&quot;,&quot;protocol&quot;:&quot;%H&quot;,&quot;requestMethod&quot;:&quot;%r&quot;,&quot;requestStatus&quot;:&quot;%s&quot;,&quot;sendBytes&quot;:&quot;%b&quot;,&quot;queryString&quot;:&quot;%q&quot;,&quot;responseTime&quot;:&quot;%Dms&quot;,&quot;partner&quot;:&quot;%{Referer}i&quot;,&quot;agentVersion&quot;:&quot;%{User-Agent}i&quot;}"
        />
        <!--注意prefix和suffix需要根据实际情况调整-->
[root@host3 ~]# tail -n1 /var/log/tomcat/localhost_access_log2022-09-13.txt 
{"requestTime":"[13/Sep/2022:15:13:07 +0800]","clientIP":"192.168.19.102","threadID":"http-bio-8080-exec-1","protocol":"HTTP/1.1","requestMethod":"GET / HTTP/1.1","requestStatus":"404","sendBytes":"-","queryString":"","responseTime":"0ms","partner":"-","agentVersion":"curl/7.29.0"}

Kibana中查看:

字段解释:

%a   这是记录访问者的IP,
%A   这是记录本地服务器的IP,
%b   发送信息的字节数,不包括http头,如果字节数为0的话,显示为-
%B   发送信息的字节数,不包括http头。
%h   服务器的名称。如果resolveHosts为false的话,这里就是IP地址了,
%H   访问者的协议,这里是HTTP/1.0
%l   官方解释:Remote logical username from identd (可能这样翻译:记录浏览者进行身份验证时提供的名字)(always returns '-')
%m   访问的方式,是GET还是POST
%p   本地接收访问的端口 
%q   比如你访问的是aaa.jsp?bbb=ccc,那么这里就显示?bbb=ccc,就是querystring的意思
%r   First line of the request (method and request URI) 请求的方法和URL
%s   http的响应状态码 
%S   用户的session ID,这个session ID大家可以另外查一下详细的解释,反正每次都会生成不同的session ID
%t   请求时间
%u   得到了验证的访问者,否则就是"-"
%U   访问的URL地址,我这里是/rightmainima/leftbott4.swf
%v   服务器名称,可能就是你url里面写的那个吧,我这里是localhost
%D   Time taken to process the request,in millis,请求消耗的时间,以毫秒记
%T   Time taken to process the request,in seconds,请求消耗的时间,以秒记 

2.3 多行匹配

在tomcat的错误日志中,可能会出现信息量较大,然后分多行显示的情况,当这些日志还以逐行采集的方式呈现到Kibana中时,日志的可读性就会变差,如下面的错误日志:

13-Sep-2022 10:15:15 下午 org.apache.tomcat.util.digester.Digester fatalError
严重: Parse Fatal Error at line 142 column 13: 元素类型 "Engine" 的结束标记必须以 '>' 分隔符结束。
org.xml.sax.SAXParseException; systemId: file:/usr/share/tomcat/conf/server.xml; lineNumber: 142; columnNumber: 13; 元素类型 "Engine" 的结束标记必须以 '>' 分隔符结束。
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1472)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1755)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2967)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
	at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1576)
	at org.apache.catalina.startup.Catalina.load(Catalina.java:616)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:681)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)

因此需要进行多行匹配,将原本分多行显示的日志整合到一起

yml 复制代码
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/tomcat/catalina.*.log
  tags: ["host3","tomcat","error"]
  multiline.type: pattern
  multiline.pattern: '^\d{2}'	# 连续两个数字开头
  multiline.negate: true		# 遇到数字就换行
  multiline.match: after

3 其他输入类型

3.1 filestream

使用filestream输入从活动日志文件中读取行。它是log的替代方案。它对现有输入进行了各种改进:

  • close_*选项的检查发生在带外。因此,如果输出被阻塞,Filebeat可以关闭阅读器并避免打开太多文件。
  • 无论harvester_limit如何,与路径配置匹配的所有文件都可以使用详细指标。通过这种方式,您可以跟踪所有文件,即使是未主动读取的文件。
  • parsers的顺序是可配置的。因此可以解析JSON行,然后将内容聚合到多行事件中。
  • 一些位置更新和元数据更改不再依赖于发布管道。如果管道被阻止,某些更改仍会应用于记录。
  • 只有最新的更新被序列化到记录中。相反,log输入必须从输出中序列化每个ACK上的完整记录。这使得使用此输入可以更快地更新记录。
  • 输入确保仅将偏移量更新写入记录。日志写入完整的文件状态。
  • 即使没有活动输入,也可以从记录中删除过时的条目。
yml 复制代码
filebeat.inputs:
- type: filestream
  enabled: true
  paths:
    - /var/log/nginx/access.log*
  parsers:
    - ndjson:				# 识别json格式日志
      keys_under_root: true
      message_key: msg
    - multiline:				# 多行匹配,写法和log类型类似
      type: pattern
      pattern: '^\d{2}'
      negate: true	
      match: after

3.2 TCP

这种模式可以将多个服务器上产生的日志发送到一台服务器上,该服务器上安装filebeat收集日志并发送给Elasticsearch

yml 复制代码
filebeat.inputs:
- type: tcp
  max_message_size: 10MiB		# 最大接收的尺寸,默认是20M
  host: "0.0.0.0:9000"			# 监听的端口

4 其他输出类型

4.1 file

除了在console显示和发送给Elasticsearch外,filebeat还支持文件类型的输出,可以将日志收集起来放在本地磁盘中。

filebeat.inputs:
- type: tcp
  max_message_size: 20MiB		
  host: "0.0.0.0:9000"			

output.file:
  path: "/tmp/filebeat"				# 目录会自动创建
  filename: filebeat
  rotate_every_kb: 20000			# 日志轮转的尺寸,默认是10M
  number_of_files: 10				# 默认是7
  permission:0644				# 日志的权限,默认就是0600

4.2 redis

output.redis
  hosts: ["192.168.19.101:6379"]
  password: "bruce123"		# redis的访问密码
  key: "filebeat-test"		# 键名
  db: 5				# 数据库名
  timeout: 5			# 超时时间

得到的数据是列表类型

相关推荐
TGB-Earnest1 小时前
【py脚本+logstash+es实现自动化检测工具】
大数据·elasticsearch·自动化
冬天vs不冷1 小时前
Linux用户与权限管理详解
linux·运维·chrome
凯子坚持 c2 小时前
深入Linux权限体系:守护系统安全的第一道防线
linux·运维·系统安全
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
watermelonoops5 小时前
Deepin和Windows传文件(Xftp,WinSCP)
linux·ssh·deepin·winscp·xftp
疯狂飙车的蜗牛6 小时前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
恩爸编程7 小时前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
远游客07138 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
马甲是掉不了一点的<.<8 小时前
本地电脑使用命令行上传文件至远程服务器
linux·scp·cmd·远程文件上传
jingyu飞鸟8 小时前
centos-stream9系统安装docker
linux·docker·centos