1、安装nginx
[root@elasticsearch-01 ~]# yum install nginx
2、修改nginx是日志文件以json的格式输出
##添加
13log_format json'{"@timestamp":"$time_iso8601",'
14'"@version":"1",'
15'"client":"$remote_addr",'
16'"url":"$uri",'
17'"status":"$status",'
18'"domain":"$host",'
19'"host":"$server_addr",'
20'"size":$body_bytes_sent,'
21'"responsetime":$request_time,'
22'"referer": "$http_referer",'
23'"ua": "$http_user_agent"'
24'}';
43access_log /var/log/nginx/access_json.log json;
3、安装redis(搭建过程可以参考之前的文章redis主从结构)
为了节省资源,博主这里只搭建了一台,只有一台主的服务器。端口:6301密码:rds6301_paswd
4、编写logstash.conf配置文件(将Nginx日志存入redis)
input {
file {
path=>"/var/log/nginx/access.log"
type=>"nginx_102_20"
start_position=>"beginning"
stat_interval=>"2"
}
}
output {
if[type]=="nginx_102_20"{
redis {
data_type=>"list"##使用发布/订阅模式
host=>"172.17.120.12"##redis主机地址
db=>"6"##Redis会生成0-15号默认有16个库,默认连接的是 index=0 的那一个。这16个库互相之间是独立的。
port=>"6301"##redis端口号
password=>"rds6301_paswd"##redis密码
key=>"nginx_102_20"##发布通道名称
}
}
}
5、将数据从redis写入es
input {
redis {
type=>"systemlog"
host=>"172.17.120.12"
password=>'rds6301_paswd'
port=>"6301"
db=>"6"
data_type=>"list"
key=>"systemlog"
}
}
filter {
json {
source=>"message"
}
}
output {
stdout {}
if[status]=="304"{
exec {
command=>"python /root/elk_alarm/count.py err_304 %{proxy_host}"
}
}
elasticsearch {
index=>"test"#索引信息
hosts=> ["172.17.120.11:9200"]
}
}
------------------------------------------------------------------
这里agent往redis里写数据 server从redis里读数据,并且判断状态码304(方便测试而已具体规则自己定义,也支持and or等)发现后执行python脚本。
6、自定义报警脚本
[root@elasticsearch-01 ~]# vim /root/elk_alarm/count.py
##大致意思为发现报警自动往redis增加一条计数器
#!/usr/bin/python
import redis
import sys
f=open("/root/elk_alarm/status.log","a")
f.write(sys.argv[1]+"\n")
f.write(sys.argv[2]+"\n")
f.close()
r=StrictRedis(host='172.17.0.9',port=6306,db=6,password='rds6306_paswd')
count=r.hget(sys.argv[1],sys.argv[2])
ifcount:
r.hset(sys.argv[1],sys.argv[2],int(count)+1)
else:
r.hset(sys.argv[1],sys.argv[2],1)
7、还要写一个报警脚本
[root@elasticsearch-01 ~]# vim /root/elk_alarm/check.py
##大致是发现304超过3时报警,需要配合crontab定时执行,如果在定义的时间内达不到3就清0,如果大于3就报警
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import redis
import smtplib
from email.mime.text import MIMEText
from email.header import Header
r=StrictRedis(host='172.17.0.9',port=6306,db=6,password='rds6306_paswd')
tengine=[
'err_304',
]
sender='upstream_error@xxx.com'
receivers=['xxxxxxx@qq.com']
foriintengine:
print i
print"============================="
fork,vinr.hgetall(i).items():
ifint(v) >3:
print k,v
print"error"
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
mail_msg="错误Upstream:"+" "+k+"次数:"+" "+v
message=MIMEText(mail_msg,'plain','utf-8')
message['From']=Header(sender)
message['To']=Header("测试",'utf-8')
subject='Log_error_mail'
message['Subject']=Header(subject,'utf-8')
try:
smtpObj=smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message.as_string())
print"邮件发送成功"
except smtplib.SMTPException:
print"Error: 无法发送邮件"
r.hset(i,k,0)
print"-----------------------------------------"
else:
print k,v
print"ok"
print"-----------------------------------------"
8、效果展示
关于运维学习、分享、交流,笔者开通了微信公众号【运维猫】,感兴趣的朋友可以关注下,欢迎加入,建立属于我们自己的小圈子,一起学运维知识。