280 likes | 554 Views
PPTV LB 日志实时分析平台. XinyiZhou xinyizhou@pptv.com 11/5 2012. Agenda. PPTV LB 日志实时分析系统介绍 实际面临的问题 解决方案 系统部署 系统实现 Fluentd (td-agent) MongoDB Python Script( PyMongo module) Zabbix 应用实例 Nginx return code 4xx 5xx 监控 Nginx 响应时间监控 告警邮件自动分析程序 LB 日志实时分析与自动 Release 平台的集成. 实际面临的问题.
E N D
PPTV LB日志实时分析平台 XinyiZhou xinyizhou@pptv.com 11/5 2012
Agenda • PPTV LB日志实时分析系统介绍 • 实际面临的问题 • 解决方案 • 系统部署 • 系统实现 • Fluentd(td-agent) • MongoDB • Python Script(PyMongo module) • Zabbix • 应用实例 • Nginx return code 4xx 5xx 监控 • Nginx响应时间监控 • 告警邮件自动分析程序 • LB日志实时分析与自动Release平台的集成
实际面临的问题 • PPTV采用Nginx+Keepalived的方式构建Load Balancer,共有约40台LB server,每台承载10-50个域名的流量,我们需要精确的把握所有域名的健康状态(返回码是否正常,4xx/5xx率),及响应时间变化趋势;能够准实时的发现入侵行为; • 难点: • 日志量大 – 每台LB每天都有几百GB日志(压缩前) • 日志分散不易进行统一分析 • 难以添加有效监控
解决方案(一) • awk+grep+bash+gnuplot • 最方便的一招,比较灵活,计算准确;但实际使用不方便,看一个域名的日志需要登陆好几台LB • E.g. 统计非200的top return code • awk'{if ($9 ~ /^[0-9]*$/ && $9 != "200" && $9 !~ /^3/) code[$9]++}END {for ( i in code )print i " " code[i]}'|sort -k2 –nr • 使用gnuplot对统计结果绘图 • cut –d’’ –f1-4 log.txt | uniq –c | (echo “plot “-” using 2:1 with lines”;cat)|gnuplot
解决方案(二) • Python+zabbix • 每台LB均部署python日志分析脚本,通过zabbix调度,每隔五分钟对前五分钟生产的日志文件进行分析,保留分析结果; • Zabbix负责绘图和告警; • 主要两个缺点: 1)性能瓶颈,日志分析占用大量LB CPU资源 2)不够灵活,日志分析局限于单台LB
解决方案(三) • Fluentd+Mongodb+Python+zabbix • Fluentd实时收集LB日志,JSON化,存入中央Mongodb • Python程序查询Mongodb数据进行实时计算;计算结果存入zabbix;zabbix负责告警及图形展现 • P.S. That’s what we want!!
Fluentd介绍 • 开源日志收集工具 http://fluentd.org/ • LOG everything as JSON! • JSON:Schema-free, add/remove field from logs at anytime • 原始日志: “2012-10-01 host1 myapp: message size=1000 user=xyz” • JSON: 2012-10-01 myapp.message { “hostname”: ”host1”, “size”: 1000, “user”: “xyz” }
Fluentd plugin说明(1) • 在不使用plugin的情况下Fluentd仅仅是将日志输入转化为JSON格式输出的工具;各类plugin极大拓展了Fluentd的功能 • Fluentd plugin有如下三种: • Input plugin 定义日志来源标准化,输入的格式 • Buffer plugin 定义fluentd缓存的配置以实现可靠性 • Output Plugin 定义输出的格式及目的地,可以是文件,网络,数据库,etc
Fluentd plugin说明(2) • Fluentd Input Plugin • http • 让fluentd从http client获取数据 • tail • tail是最常用的input plugin; <source> type tail path /var/log/httpd-access.log #tail监听的文件地址 tag apache.access #每个输入需要一个特定标签以区别 format apache|syslog|自定义正则 #format可以灵活自定义 </source> • foward • 将其他fluentd/fluent-cat命令的输出作为该fluentd的输入; • exec • 通过执行外部命令,以命令执行的结果作为fluentd的输入;
Fluentd plugin说明(3) • Fluentd Output Plugin • Ouput Plugin用于存储Fluentd收集来的数据;目前有很多开源的plugin,如:fluentd-flume,fluentd-splunk,fluentd-cassandra,fluentd-scribe,fluentd-mongodb • fluent-plugin-mongo 0.6.10 • Output plugin中最完美的当属mongodb plugin,因为Fluentd/Mongodb都以JSON为基础;mongodb良好的插入查询性能可以顶住海量日志实时分析的压力;mongodb的capped collection很好的解决了日志定量轮转的问题
MONGODB部署 • 每个机房部署一台mongodb server,用于收集该机房全部LB的日志 • 每个mongodb部署多个instance,每个instance对应一台LB server • 建立多个collection,每个collection保存一个域名的日志信息 • 一定要使用capped collection!
MONGODB配置 • port = 270XX • dbpath = /home/mongodb/node270xx • logpath = /home/mongodb/node270xx.log • syncdelay = 10 #这个设置10秒左右,将IO压力平均化,避免sync时影响查询性能 • maxConns = 20000 • oplogSize = 1024 • directoryperdb = on • logappend = on • journal = off • fork = on • nohttpinterface = on
Fluentd部署 • 每台LB上均需安装一个Fluentd agent;使用TreasureData公司yum源上提供的td-agent rpm包安装即可; • 启动方法 /etc/init.d/td-agent start • 关键配置/etc/td-agent/td-agent.conf • 日志文件 /var/log/td-agent/td-agent.log
PPTV Fluentd Input配置 • <source> • type tail • path /home/logs/nginx/aplus-access.log • pos_file /var/log/td-agent/tmp/aplus.pptv.com.pos • format /^(?<ip>[^ ]*) (?<domain>[^ ]*) - ([^ ]*) ([^ ]*) "(?<url>[^"]*)" (?<code>[^ ]*) (?<bsize>[^ ]*) ("[^"]*") ("[^"]*") ("[^"]*") "(?<restime>[^"]*)" "(?<backend>[^,"]*)[^"]*" "(?<bcode>[^,"]*)[^"]*" "(?<nginxtime>[^"]*)"$/ • tag mongo.aplus.pptv.com.access • </source>
PPTV Fluentd Output配置 • <match mongo.aplus.pptv.com.access> • type mongo • database LB_hostname • collection aplus.pptv.com.access • host mongodb_host • port mongodb_port • capped • capped_size180m #确保能够保留最近1小时该域名的日志 • ignore_invalid_record true • buffer_typememory #使用内存作为buffer存储方式 • buffer_chunk_limit 1M • buffer_queue_limit 15 • retry_limit 10 • retry_wait 1s • flush_interval1s #刷新频率为1s,基本做到实时 • </match>
PPTV日志样例 • 原始日志: 218.26.242.14 999.fb.app.aplus.pptv.com - [05/Nov/2012:15:42:38 +0800] "GET /recommend_pop/?_=1352101423806 HTTP/1.0" 200 34 "http://v.pptv.com/show/MLibyMJjibbqyJB28.html" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)" "60.211.95.201, 127.0.0.1" "0.012" "10.201.10.94:80" "200" "0.012“ MONGODB中的日志: { "_id" : ObjectId("5097755c31d87b09f8046f1f"), "ip" : "218.26.242.14", "domain" : "999.fb.app.aplus.pptv.com", "url" : " GET /recommend_pop/?_=1352101423806 HTTP/1.0", “code” : “200”, #返回码 "bsize" : “34", #bodysize “restime” : “0.012”, #后端服务响应时间 “backend” : “10.201.10.94:80”, #后端服务地址 “bcode” : “200”, #后端服务返回码 “nginxtime” : “0.012”, #nginx响应时间 "time" : ISODate("2012-11-05T15:42:38Z") }
PPTV LB日志分析逻辑(1) • 为LB日志自动生成fluentd配置文件: • 对某台/log/nginx/*.access.log和*.error.log: • 根据LB所在机房分配后端mongodb地址/端口,根据历史日志大小分配capped collection size,根据LB机器名分配mongodbdatabase_name,根据域名确定mongodb collection name.
PPTV LB日志分析逻辑(2) • 保存域名-LB-后端主机的对应关系,并定期更新(parse nginx配置文件) • > db.domain_host_info.find({domain:"aplus.pptv.com"}) • { "_id" : ObjectId("5096bc7b19859831d6000002"), "domain" : "aplus.pptv.com", "host" : “lb1", "backend" : “host1" } • { "_id" : ObjectId("5096bc7b19859831d6000003"), "domain" : "aplus.pptv.com", "host" : "lb1", "backend" : “host2" } • { "_id" : ObjectId("5096bc7b19859831d6000004"), "domain" : "aplus.pptv.com", "host" : “lb2", "backend" : “host3" } • { "_id" : ObjectId("5096bc7b19859831d6000005"), "domain" : "aplus.pptv.com", "host" : “lb2", "backend" : “host4" }
PPTV LB日志分析逻辑(3) • 每五分钟对前五分钟mongodb收集到的日志基于域名进行汇总计算(python/pymongo),得出结果存入mongodb中的lb_detail表: • > db.lb_detail.findOne() • { • "_id" : ObjectId("509434522573b0625d000002"), • “domain” : “xxxxx.pptv.com”, #分析的域名 • “ng1_count” : 0, #nginx请求时间超过1秒个数 • “be1_count” : 0, #backend后端响应时间超过1秒个数 • “total_count” : 2703, # 过去5分钟该域名的请求总数 • “backtime_total” : 6.71, # backend后端响应时间总和 • “bodysize_total” : 124100, #bodysize总和 • “xx4_count” : 2, #4xx请求个数 • "time" : ISODate("2012-11-03T05:00:02.634Z"), • “ng3_count” : 0, #nginx请求总时间大于3秒的请求个数 • “c200_count” : 2700, #200请求个数 • “xx5_count” : 1, #5xx请求个数 • “ngxtime_total” : 7.191, #nginx请求总时间 • “be3_count” : 0 #backend响应时间超过3秒的个数 • }
PPTV LB日志分析逻辑(4) • 每五分钟对前五分钟mongodb收集到的日志基于后端机器进行汇总计算(python/pymongo),得出结果存入mongodb中的backend_detail表: • > #某域名xxxx.pptv.com中某后端机器(backend_ip:80)过去5分钟的4xx/5xx/响应时间/超时次数情况 • > db.backend_detail.findOne() • { • "_id" : ObjectId("509677552573b02445000004"), • "bk_xx5_count" : 183, • "bk_be3_count" : 62, • "bk_ng3_count" : 65, • "bk_body_size_total" : 214842812, • "bk_ngx_time_total" : 1443.1720000000564, • "bk_be1_count" : 83, • "domain" : “xxxx.pptv.com", • "bk_total" : 25378, • "server" : “LB_NAME", • "bk_back_time_total" : 1233.362000000008, • "bk_c200_count" : 25140, • "time" : ISODate("2012-11-04T22:10:29.004Z"), • "bk_xx4_count" : 42, • "bk_ng1_count" : 109, • "backend" : “backend_ip:80" • }
PPTV LB日志分析逻辑(5) • 对前面(3),(4)实时分析得出的结果,配置zabbix监控项进行采集、绘图 • Zabbix监控脚本使用python/pymongo查询mongodb中lb_detail/backend_detail表获取过去5分钟 某域名的总请求数/2xx率/4xx率/5xx率/平均响应时间/后端响应超过1秒的比率等
Zabbix监控(1) • 建立zabbix LB_log_mining监控模板,对每个域名建立总请求数,4xx/5xx数,后端平均响应时间,nginx响应时间,bodysize平均大小,响应时间>1秒比例,响应时间>3秒比例 (每五分钟采集一次)
Zabbix监控(3) • 如上页所示,某域名的总请求数、4xx、5xx比率,平均响应时间,均可以在zabbix中查看变化趋势;针对4xx、5xx率特别高或者响应时间>3秒的比率特别高的,可以进行实时告警; • 告警邮件见下图;
Zabbix监控(4) Zabbix告警邮件实例;