[toc]
Logstash收集java日志并输出到ES中 因为我们现在需要用Logstash收集tomcat日志,所以我们暂时将tomcat安装到Logstash所在机器,也就是db03:10.0.0.83这台机器,收集tomcat访问日志以及tomcat错误日志进行实时统计,在企业中,tomcat机器肯定不是单台,而是一个集群的形式,那么我们每台tomcat上都需要安装一个Logstash,然后将收集到的日志输出给Elasticsearch进行分析。
将tomcat日志改成json格式 在企业中,我们看到tomcat日志遇到异常(exception)一条日志可能是几行或者十几行甚至几十行,组成的,那么,我们需要将多行日志变成一行日志,来收集。
这里我们有几种方式可以实现:
将日志改成Json格式
通过Logstash其他模块来收集例:multiline多行匹配
安装tomcat 安装JDK环境
安装tomcat
二进制安装tomcat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 tar xf apache-tomcat-8.0.38.tar.gz mv apache-tomcat-8.0.38 /usr/local/tomcat-8.0.38ln -s /usr/local/tomcat-8.0.38 /usr/local/tomcatcd /usr/local/tomcat/webapps/mkdir webdirecho 'test tomcat' > webdir/index.htmlcd /usr/local/tomcat/bin/./catalina.sh start netstat -lntup|grep 8080 tcp 0 0 :::8080 :::* LISTEN 12569/java
yum安装tomcat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 yum install -y tomcat mkdir /usr/share/tomcat/webapps/ROOTvim /usr/share/tomcat/webapps/ROOT/index.jsp test tomcatsystemctl start tomcat netstat -lntup tcp6 0 0 :::8080 :::* LISTEN 23350/java ll /var/log/tomcat/ total 12 -rw-r--r-- 1 tomcat tomcat 4366 Feb 15 09:29 catalina.2023-02-15.log -rw-rw---- 1 tomcat tomcat 28 Nov 17 2020 catalina.out -rw-r--r-- 1 tomcat tomcat 0 Feb 15 09:29 host-manager.2023-02-15.log -rw-r--r-- 1 tomcat tomcat 0 Feb 15 09:29 localhost.2023-02-15.log -rw-r--r-- 1 tomcat tomcat 0 Feb 15 09:29 localhost_access_log.2023-02-15.txt -rw-r--r-- 1 tomcat tomcat 0 Feb 15 09:29 manager.2023-02-15.log 10.0.0.83:8080
访问页面
修改tomcat日志格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 vim /usr/local/tomcat/conf/server.xml <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="tomcat_access_log" suffix=".log" pattern="{"clientip":"%h","ClientUser":"%l","authenticated":"%u","AccessTime":"%t","method":"%r","status":"%s","SendBytes":"%b","Query?string":"%q","partner":"%{Referer}i","AgentVersion":"%{User-Agent}i"}" /> cd /usr/local/tomcat/bin/./catalina.sh stop ./catalina.sh start cd /usr/local/tomcat/logs/ll 总用量 40 -rw-r--r-- 1 root root 14601 3月 31 10:10 tomcat_access_log.2019-03-31.log tail -f tomcat_access_log.2019-03-31.log
验证Json格式 复制一条日志,打开浏览器,访问:http://www.kjson.com/
配置Logstash收集tomcat日志输出到ES中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 vim /etc/logstash/conf.d/tomcat_es.conf input { file { path => "/usr/local/tomcat/logs/tomcat_access_log.2023-02-15.log" start_position => "end" type => "tomct_access_log" } } output { elasticsearch { hosts => ["10.0.0.81:9200" ] index => "tomcat_access-%{+YYYY.MM.dd}" codec => "json" } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tomcat_es.conf &
启动成功,如下图所示:
打开浏览器,访问:http://10.0.0.81:9100/ 查看是否生成日志,如果没有,则访问tomcat页面。
解析json格式 将tomcat日志索引添加到Kibana中
查看日志内容,不难发现,即便是用了Json格式的,所有日志在message中还是 一坨 看起来很麻烦,并不是以KEY:VALUE
的形式展示出来的。
所以,我们需要获取到message中的KEY:VALUE
将他解析成键值对的形式,展现出来
1 2 3 4 5 6 7 8 9 filter { json { source => "message" } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tomcat_es.conf &
再次查看日志内容
删除多余的message 两条日志对比,可以看出修改后的Logstash日志,前面多出很多KEY,虽然还message里还是有一坨,但是message中的所有Json已经被解析出来变成了KEY:VALUE
的形式,当然我们也可以取消message的显示,操作如下:
1 2 3 4 5 6 7 8 9 10 filter { json { source => "message" remove_field => ["message" ] } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tomcat_es.conf &
再次查看日志,可以看到message已经没有了,但是所有的KEY:VALUE都还在。
为什么要这么做呢,一定要展示成Json格式呢?
因为,如果我们想要Kibana画图,那么必须用KEY:VALUE的形式,获取值,来画图。
最终配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 vim tomcat_file_es_json.conf input{ file{ type => 'tomcat_access_log' path => '/var/log/tomcat/localhost_access_log.*.txt' start_position => 'end' } } filter{ json{ source => 'message' remove_field => ["message" ] } } output{ elasticsearch{ hosts => ["10.0.0.81:9200" ] index => "%{type}-%{+yyyy.MM.dd}" codec => 'json' } }
Logstash收集nginx日志并输出到ES中 源码安装nginx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 yum install -y gcc gcc-c++ automake pcre-devel zlib-devel openssl-devel wget http://nginx.org/download/nginx-1.10.3.tar.gz tar xf nginx-1.10.3.tar.gz cd nginx-1.10.3/./configure --prefix=/usr/local/nginx-1.10.3 make make install ln -s /usr/local/nginx-1.10.3 /usr/local/nginx/usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx-1.10.3/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx-1.10.3/conf/nginx.conf test is successful /usr/local/nginx/sbin/nginx
配置nginx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 grep -Ev '#|^$' /usr/local/nginx/conf/nginx.conf.default > /usr/local/nginx/conf/nginx.conf vim /usr/local/nginx/conf/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' ; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 4096; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; } vim /etc/nginx/conf.d/www.conf server{ listen 80; server_name www.xxx.com; root /code; index index.html; access_log /var/log/nginx/www.xxx.com_access_json.log json; } vim /etc/nginx/conf.d/xxx.conf server{ listen 80; server_name xxx.xxx.com; root /code1; index index.html; access_log /var/log/nginx/xxx.xxx.com_access_json.log json; } mkdir /codemkdir /code1echo test nginx > /code/index.htmlecho test nginx1 > /code1/index.html/usr/local/nginx/sbin/nginx -s reload
修改nginx日志格式为Json 之前我们讲了tomcat日志,在企业中,修改格式需要与开发商量,但是nginx我们不需要,如果需要原来的格式日志,我们可以将日志输出两份,一份 main格式,一份Json格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 vim /usr/local/nginx/conf/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } 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 json '{"@timestamp":"$time_iso8601",' '"host":"$server_addr",' '"clientip":"$remote_addr",' '"size":$body_bytes_sent,' '"responsetime":$request_time,' '"upstreamtime":"$upstream_response_time",' '"upstreamhost":"$upstream_addr",' '"http_host":"$host",' '"url":"$uri",' '"domain":"$host",' '"xff":"$http_x_forwarded_for",' '"referer":"$http_referer",' '"status":"$status"}' ; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 4096; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; } /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx-1.10.3/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx-1.10.3/conf/nginx.conf test is successful /usr/local/nginx/sbin/nginx -s reload
打开浏览器,访问:http://10.0.0.83/ 查看日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ll /usr/local/nginx/logs/ 总用量 24 -rw-r--r-- 1 root root 1280 4月 8 10:47 access_json.log -rw-r--r-- 1 root root 5286 4月 8 10:47 access.log -rw-r--r-- 1 root root 4218 4月 8 10:46 error.log -rw-r--r-- 1 root root 5 4月 8 10:20 nginx.pid cat access_json.log{"@timestamp" :"2019-04-08T10:47:41+08:00" ,"host" :"10.0.0.53" ,"clientip" :"10.0.0.1" ,"size" :0,"responsetime" :0.000,"upstreamtime" :"-" ,"upstreamhost" :"-" ,"http_host" :"10.0.0.53" ,"url" :"/index.html" ,"domain" :"10.0.0.53" ,"xff" :"-" ,"referer" :"-" ,"status" :"304" } cat access.log10.0.0.1 - - [08/Apr/2019:10:29:11 +0800] "GET / HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
通过Logstash收集nginx日志输出到ES中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 vim /etc/logstash/conf.d/nginx_es.conf input { file { type => "www_nginx_access" path => "/var/log/nginx/www.xxx.com_access_json.log" start_position => "beginning" } file { type => "xxx_nginx_access" path => "/var/log/nginx/xxx.xxx.com_access_json.log" start_position => "beginning" } } filter{ json{ source => 'message' remove_field => ["message" ] } } output { elasticsearch { hosts => ["10.0.0.81:9200" ] index => "nginx_access-%{+YYYY.MM.dd}" codec => json } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx_es.conf -t /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx_es.conf &
Logstash通过TCP/UDP收集日志并输出到ES中 通过logstash的tcp/udp插件收集日志,通常用于在向elasticsearch日志补录丢失的部分日志,可以将丢失的日志通过一个TCP端口直接写入到elasticsearch服务器。
配置Logstash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 cd /etc/logstash/conf.d/vim tcp.conf input { tcp { port => 1234 type => "tcplog" mode => "server" } } output { stdout { codec => rubydebug } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tcp.conf netstat -lntup tcp 0 0 :::1234 :::* LISTEN 8656/java
使用nc传输日志 NetCat简称nc,在网络工具中有瑞士军刀美誉,其功能实用,是一个简单、可靠的网络工具,可通过TCP或UDP协议传输读写数据,另外还具有很多其他功能。
在其它服务器安装nc命令
1 2 3 4 5 yum install -y nc echo "test nc" | nc 10.0.0.83 1234
通过nc发送一个文件
1 2 nc 10.0.0.83 1234 < /etc/passwd
结果如下,我们不难发现,Logstash会将传送来的日志文件 一行一行 读取,收集成日志
通过伪设备的方式发送日志 在类Unix操作系统中,设备节点并不一定要对应物理设备。没有这种对应关系的设备是伪设备。操作系统运用了它们提供的多种功能,tcp只是dev下面众多伪设备当中的一种设备。
1 2 echo "测试设备" > /dev/tcp/10.0.0.83/1234
将输出改成ES 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 vim tcp.conf input { tcp { port => 1234 type => "tcplog" mode => "server" } } output { elasticsearch { hosts => ["10.0.0.51:9200" ] index => "tcp_log-%{+YYYY.MM.dd}" } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tcp.conf & echo "测试设备1" > /dev/tcp/10.0.0.53/1234echo "测试设备2" > /dev/tcp/10.0.0.53/1234
打开浏览器,访问:http://10.0.0.51:9100/
将ES索引添加到Kibana中
Logstash配合rsyslog收集haproxy日志并输出到ES中 rsyslog详解
在centos 6及之前的版本叫做syslog,centos 7开始叫做rsyslog,根据官方的介绍,rsyslog(2013年版本)可以达到每秒转发百万条日志的级别,官方网址:http://www.rsyslog.com/
rsyslog是linux系统中用来实现日志功能的服务,默认已经安装,并且自动启用。
作用:
特性:
支持输出日志到各种数据库,如 MySQL,PostgreSQL,MongoDB ElasticSearch,等等;
通过 RELP + TCP 实现数据的可靠传输(基于此结合丰富的过滤条件可以建立一种 可靠的数据传输通道供其他应用来使用);
精细的输出格式控制以及对消息的强大 过滤能力;
高精度时间戳;队列操作(内存,磁盘以及混合模式等); 支持数据的加密和压缩传输等。
haproxy详解
原理
haproxy提供高可用性、负载均衡 以及基于TCP(第四层)和HTTP(第七层)应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
优点
免费开源,稳定性也是非常好。单haproxy也跑得不错,稳定性可以与硬件级的F5相媲美。
根据官方文档,haproxy可以跑满10Gbps,这个数值作为软件级负载均衡器是相当惊人的。
haproxy支持连接拒绝:因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。
haproxy支持全透明代理(已具备硬件防火墙的典型特点):可以用客户端IP地址或者任何其他地址来连接后端服务器。这个特性仅在Linux 2.4/2.6内核打了tcp proxy补丁后才可以使用。这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。
haproxy现多于线上的Mysql集群环境,我们常用于它作为MySQL(读)负载均衡。
自带强大的监控服务器状态的页面,实际环境中我们结合Nagios进行邮件或短信报警。
HAProxy支持虚拟主机,许多朋友说它不支持虚拟主机是错误的,通过测试我们知道,HAProxy是支持虚拟主机的。
架构流程图示
修改nginx配置文件(同时配置多台nginx服务器) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 vim /usr/local/nginx/conf/nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; 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 access_json '{"@timestamp":"$time_iso8601",' '"host":"$server_addr",' '"clientip":"$remote_addr",' '"size":$body_bytes_sent,' '"responsetime":$request_time,' '"upstreamtime":"$upstream_response_time",' '"upstreamhost":"$upstream_addr",' '"http_host":"$host",' '"url":"$uri",' '"domain":"$host",' '"xff":"$http_x_forwarded_for",' '"referer":"$http_referer",' '"status":"$status"}' ; server { listen 8081; server_name 10.0.0.83; location / { root /code/html; index index.html index.htm; } } } vim /etc/nginx/conf.d/www.conf server{ listen 8090; server_name www.xxx.com; root /code; index index.html; access_log /var/log/nginx/www.xxx.com_access_json.log json; } vim /etc/nginx/conf.d/xxx.conf server{ listen 8091; server_name xxx.xxx.com; root /code1; index index.html; access_log /var/log/nginx/xxx.xxx.com_access_json.log json; } /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx-1.10.3/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx-1.10.3/conf/nginx.conf test is successful /usr/local/nginx/sbin/nginx -s reload
安装配置rsyslog 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 yum install -y rsyslog vim /etc/rsyslog.conf 15 $ModLoad imudp 16 $UDPServerRun 514 19 $ModLoad imtcp 20 $InputTCPServerRun 514 92 local7.* @@10.0.0.83:2222 systemctl start rsyslog
安装配置haproxy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 yum install -y haproxy vim /etc/haproxy/haproxy.cfg global maxconn 100000 chroot /var/lib/haproxyuid 99 gid 99 daemon nbproc 1 pidfile /var/run/haproxy.pid log 127.0.0.1 local7 info defaults option http-keep-alive option forwardfor maxconn 100000 mode http timeout connect 300000mstimeout client 300000mstimeout server 300000mslisten stats mode http bind 0.0.0.0:9999 stats enable log global stats uri /haproxy-status stats auth haadmin:123456 frontend web_port bind 0.0.0.0:80 mode http option httplog log global option forwardfor acl pc hdr_dom(host) -i www.xxx.com acl mobile hdr_dom(host) -i xxx.xxx.com use_backend pc_host if pc use_backend mobile_host if mobile backend pc_host mode http option httplog balance static-rr server web1 10.0.0.83:8090 check inter 2000 rise 3 fall 2 weight 1 server web1 10.0.0.52:8090 check inter 2000 rise 3 fall 2 weight 1 backend mobile_host mode http option httplog balance static-rr server web1 10.0.0.83:8091 check inter 2000 rise 3 fall 2 weight 1 server web1 10.0.0.52:8091 check inter 2000 rise 3 fall 2 weight 1 systemctl start haproxy netstat -lntup tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 9082/haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 9631/haproxy ps -ef|grep haproxy nobody 9082 1 0 14:04 ? 00:00:00 /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid 10.0.0.83 www.xxx.com xxx.xxx.com
logstash通过rsyslog收集haproxy日志 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 vim haproxy.cof input{ syslog1{ type => "rsyslog_haproxy" port => "2222" } } output{ stdout{ codec => rubydebug } elasticsearch{ hosts => ["10.0.0.81:9200" ] index => "%{type}-%{+yyyy.MM.dd}" } } /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/haproxy.conf netstat -lntup|grep 2222 tcp 0 0 :::2222 :::* LISTEN 9867/java udp 0 0 :::2222 :::* LISTEN 9867/java
logstash监听2222端口
rsyslog是接收到了haproxy的日志然后转发给10.0.0.83:2222
logstash启动2222端口实时接收rsyslog传来的日志
如果logstash停掉 2222端口就会消失 2222是logstash起来的
打开浏览器,访问:http://10.0.0.81:9100/
将ES索引添加到Kibana中 打开浏览器,访问:http://10.0.0.83:5601/