ELK日志系统之使用Rsyslog快速方便的收集Nginx日志

常规的日志收集方案中Client端都须要额外安装一个Agent来收集日志,例如logstash、filebeat等,额外的程序也就意味着环境的复杂,资源的占用,有没有一种方式是不须要额外安装程序就能实现日志收集呢?Rsyslog就是你要找的答案!mysql

Rsyslog

Rsyslog是高速的日志收集处理服务,它具备高性能、安全可靠和模块化设计的特色,可以接收来自各类来源的日志输入(例如:file,tcp,udp,uxsock等),并经过处理后将结果输出的不一样的目的地(例如:mysql,mongodb,elasticsearch,kafka等),每秒处理日志量可以超过百万条。linux

Rsyslog做为syslog的加强升级版本已经在各linux发行版默认安装了,无需额外安装。nginx

收集Nginx日志

ELK经过Rsyslog收集日志流程图以下: git

  1. 处理流程为:Nginx --syslog--> Rsyslog --omkafka--> Kafka --> Logstash --> Elasticsearch --> Kibana
  2. Nginx产生日志经过syslog系统服务传给Rsyslog服务端,Rsyslog接收到日志后经过omkafka模块将日志写入Kafka,Logstash读取Kafka队列而后写入Elasticsearch,用户经过Kibana检索Elasticsearch里存储的日志
  3. Rsyslog服务系统自带无需安装,因此整个流程中客户端不须要额外安装应用
  4. 服务端虽然Rsyslog也已安装,但默认没有omkafka模块,若是须要Rsyslog写入Kafka须要先安装这个模块
  5. omkafka模块在rsyslog v8.7.0以后的版本才支持,因此须要先经过rsyslogd -v命令查看rsyslog版本,若是版本较低则须要升级

Rsyslog升级

1.添加rsyslog源的keygithub

# apt-key adv --recv-keys --keyserver keys.gnupg.net AEF0CF8E
复制代码

2.添加rsyslog源地址redis

echo "deb http://debian.adiscon.com/v8-stable wheezy/" >> /etc/apt/sources.list
echo "deb-src http://debian.adiscon.com/v8-stable wheezy/" >> /etc/apt/sources.list
复制代码

3.升级rsyslog服务sql

# apt-get update && apt-get -y install rsyslog
复制代码

添加omkafka模块

1.安装编译工具,下边autoreconf须要用到,否则没法生成configure文件mongodb

# apt-get -y install pkg-config autoconf automake libtool unzip
复制代码

2.omkafka须要安装一堆的依赖包json

# apt-get -y install libdbi-dev libmysqlclient-dev postgresql-client libpq-dev libnet-dev librdkafka-dev libgrok-dev libgrok1 libgrok-dev libpcre3-dev libtokyocabinet-dev libglib2.0-dev libmongo-client-dev libhiredis-dev
# apt-get -y install libestr-dev libfastjson-dev uuid-dev liblogging-stdlog-dev libgcrypt-dev
# apt-get -y install flex bison librdkafka1 librdkafka-dev librdkafka1-dbg
复制代码

3.编译安装omkafka模块bootstrap

# mkdir tmp && cd tmp

# git init
# git pull git@github.com:VertiPub/omkafka.git

# autoreconf -fvi
# ./configure --sbindir=/usr/sbin --libdir=/usr/lib --enable-omkafka && make && make install && cd ..
复制代码

Rsyslog收集nginx日志

Client端Nginx配置
log_format  jsonlog '{'
    '"host": "$host",'
    '"server_addr": "$server_addr",'
    '"http_x_forwarded_for":"$http_x_forwarded_for",'
    '"remote_addr":"$remote_addr",'
    '"time_local":"$time_local",'
    '"request_method":"$request_method",'
    '"request_uri":"$request_uri",'
    '"status":$status,'
    '"body_bytes_sent":$body_bytes_sent,'
    '"http_referer":"$http_referer",'
    '"http_user_agent":"$http_user_agent",'
    '"upstream_addr":"$upstream_addr",'
    '"upstream_status":"$upstream_status",'
    '"upstream_response_time":"$upstream_response_time",'
    '"request_time":$request_time'
'}';


access_log syslog:server=rsyslog.domain.com,facility=local7,tag=nginx_access_log,severity=info jsonlog;
复制代码

1.Nginx在v1.10以后的版本才支持syslog的方式处理日志,请确保你的Nginx版本高于1.10

2.为了下降logstash的处理压力,同时也为了下降整个配置的复杂度,咱们nginx的日志直接采用json格式

3.抛弃文本文件记录nginx日志,改用syslog直接将日志传输到远端的rsyslog服务器,以便咱们后续的处理;这样作的另外一个很是重要的好处是咱们再也无需考虑nginx日志的分割和按期删除问题(通常咱们为了方便管理一般会采用logrotate服务来对日志进行按天拆分和按期删除,以避免磁盘被占满)

4.access_log直接输出到syslog服务,各参数解释以下:

  • syslog:指明日志用syslog服务接收
  • server:接收syslog发送日志的Rsyslog服务端地址,默认使用udp协议,端口是514
  • facility:指定记录日志消息的类型,例如认证类型auth、计划任务cron、程序自定义的local0-7等,没有什么特别的含义,没必要深究,默认的值是local7
  • tag:给日志添加一个tag,主要是为了方便咱们在服务端区分是哪一个服务或者client传来的日志,例如咱们这里给了tag:nginx_access_log,若是有多个服务同时都写日志给rsyslog,且配置了不通的tag,在rsyslog服务端就能够根据这个tag找出哪些是nginx的日志
  • severity:定义日志的级别,例如debug,info,notice等,默认是error
Server端Rsyslog配置
# cat /etc/rsyslog.d/rsyslog_nginx_kafka_cluster.conf 
module(load="imudp")
input(type="imudp" port="514")

# nginx access log ==> rsyslog server(local) ==> kafka
module(load="omkafka")

template(name="nginxLog" type="string" string="%msg%")

if $inputname == "imudp" then {
    if ($programname == "nginx_access_log") then
        action(type="omkafka"
            template="nginxLog"
            broker=["10.82.9.202:9092","10.82.9.203:9092","10.82.9.204:9092"]
            topic="rsyslog_nginx"
            partitions.auto="on"
            confParam=[
                "socket.keepalive.enable=true"
            ]
        )
}

:rawmsg, contains, "nginx_access_log" ~
复制代码

1.在rsyslog.d目录下添加一个专门处理nginx日志的配置文件

2.rsyslog配置文件重要配置解释以下:

  • module:加载模块,这里咱们须要加载imudp模块来接收nginx服务器syslog发过来的日志数据,也须要加载omkafka模块来将日志写入到kafka
  • input:开启udp协议,端口514,也能够同时开启tcp协议,二者能够共存
  • template:定义一个模板,名字叫nginxLog,模板里能够定义日志的格式,由于咱们传的已是json了,不须要再匹配格式,因此这里不额外定义,注意模板名字要惟一
  • action:在匹配到inputname为imudp且programname为nginx_access_log(就是咱们上边nginx配置里边的tag)以后的处理方式,这里的配置为匹配到的日志经过omkafka模块写入kafka集群,还有一些关于omkafka更详细的配置参考上边给出的omkafka模块官方文档
  • :rawmsg, contains:最后这一行的意思是忽略包含nginx_access_log的日志,没有这一行的话rsyslog服务默认会把全部日志都记录到message里边一份,咱们已经把日志输出到kafka了,本地就不必再记录了

3.omkafka模块检查kafka里边topic是否存在,若是不存在则建立,无需手动建立kafka的topic

Server端logstash配置
input {
    kafka {
        bootstrap_servers => "10.82.9.202:9092,10.82.9.203:9092,10.82.9.204:9092"
        topics => ["rsyslog_nginx"]
    }
}

filter {
    mutate {
        gsub => ["message", "\\x", "\\\x"]
    }

    json {
        source => "message"
    }

    date {
        match => ["time_local","dd/MMM/yyyy:HH:mm:ss Z"]
        target => "@timestamp"
    }

}

output {
    elasticsearch {
        hosts => ["10.82.9.205", "10.82.9.206", "10.82.9.207"]
        index => "rsyslog-nginx-%{+YYYY.MM.dd}"
    }
}

复制代码

重要配置参数解释以下:

  • input:配置kafka的集群地址和topic名字
  • filter:一些过滤策略,由于传入kafka的时候是json格式,因此不须要额外处理,惟一须要注意的是若是日志中有中文,例如url中有中文内容时须要替换\\x,否则json格式会报错
  • output:配置ES服务器集群的地址和index,index自动按天分割
联调测试

配置完成后分别重启rsyslog服务和nginx服务,访问nginx产生日志

1.查看kafka是否有正常生成topic

# bin/kafka-topics.sh --list --zookeeper 127.0.0.1:2181
__consumer_offsets
rsyslog_nginx
复制代码

2.查看topic是否能正常接收日志

# bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic rsyslog_nginx
{"host": "domain.com","server_addr": "172.17.0.2","http_x_forwarded_for":"58.52.198.68","remote_addr":"10.120.89.84","time_local":"28/Aug/2018:14:26:00 +0800","request_method":"GET","request_uri":"/","status":200,"body_bytes_sent":1461,"http_referer":"-","http_user_agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36","upstream_addr":"-","upstream_status":"-","upstream_response_time":"-","request_time":0.000}
复制代码

3.kibana添加index,查看Elasticsearch中是否有数据,若是前两步都正常,kibana搜不到index或index没有数据,多半是index名字写错了之类的基础问题,仔细检查

kibana查询展现

  • 打开Kibana添加rsyslog-nginx-*的Index,并选择timestamp,建立Index Pattern

  • 进入Discover页面,能够很直观的看到各个时间点请求量的变化,根据左侧Field实现简单过滤,例如咱们想查看全部访问状态为404的uri,能够点击request_uri和status后边的add,这两项的内容将出如今右侧,而后点击status下边404状态码后边的加号,则只查看状态为404的请求,点击上方auto-refresh能够设置页面自动刷新时间

  • 经过各类条件的组合查询能够实现各类各样的需求,例如每秒请求、带宽占用、异常比例、慢响应、TOP IP、TOP URL等等各类状况,而且能够经过Visualize很方便的将这些信息绘制图标,生成Dashboard保存

写在最后

  1. Nginx的access log绝对是网站的一个宝藏,经过日志量的变化能够知道网站的流量状况,经过对status状态的分析能够知道咱们提供服务的可靠性,经过对特定活动url的追踪能够实时了解活动的火爆程度,经过对某些条件的组合查询也能为网站运营提供建议和帮助,从而使咱们的网站更友好更易用
  2. Rsyslog服务的单点问题能够经过部署多个Rsyslog服务过三层负载来保证高可用,不过以咱们的经验来讲rsyslog服务仍是很稳定的,跑了一年多,每分钟日志处理量在20w左右,没有出现过宕机状况,不想这么复杂的话能够写个check rsyslog服务状态的脚本跑后台,挂了自动拉起来
  3. 整个过程当中咱们使用了UDP协议,第一是由于Nginx日志的syslog模式默认支持的就是UDP协议,翻了官网没找到支持TCP的方式,我想这也是考虑到UDP协议的性能要比TCP好的多,第二也考虑到若是使用TCP遇到网络不稳定的状况下可能会不停的重试或等待,影响到Nginx的稳定。对于由于内容过长超过以太网数据帧长度的问题暂时没有遇到

长按关注公众号查看更多原创文章

若是你以为文章对你有帮助,请转发分享给更多的人。若是你以为读的不尽兴,推荐阅读如下文章:

相关文章
相关标签/搜索