专栏首页莫韵的专栏基于ELK的nginx-qps监控解决方案
原创

基于ELK的nginx-qps监控解决方案

先说说原理:

nginx-log中所有我们需要的信息,都是有的 。

比如user-agent .  http-refer ,  url   remote_addr 等等  . 

我们只需要把nginx-log中的信息进行计算和汇总即可。

效果展示

有人说,有日志了用awk/grep 什么的快速计算就行了 。 ansible+awk/grep 那都不是事

但面临两大困难点 

1.  我们的服务通常是多机 , 基于日志,使用脚本awk计算的话,只能得到单机性能,多机汇总是个问题;

2. 脚本计算的实时性,脚本计算基本无法实现 ;

当然这种nginx-qps监控什么的,肯定也有各路大神,通过其它方式完成过

今天在这里介绍的,是一种纯开源解决方案,对于开发能力不强的运维童鞋,那会是非常适宜的。

过程大约是这样

  1. nginx-log 以固定的json串的方式打印
  2. filebeat将日志以json方式发送到es
  3. 利用ES的计算能力,将日志按字段汇总起来
  4. 最后grafana/kibana 通过ES-API接口,获取数据后,展示到前台

假定你已经搭好 nginx服务和elk服务 , 下面我们来描述关键步骤

nginx - 日志的配置操作 . 定义一个nginx-log-format 为 json串形式的

log_format json '{"@timestamp":"$time_iso8601",'
                '"@version":"1",'
                '"server_addr":"$server_addr",'
                '"remote_addr":"$remote_addr",'
                '"host":"$host",'
                '"uri":"$uri",'
                '"body_bytes_sent":$body_bytes_sent,'
                '"bytes_sent":$body_bytes_sent,'
                '"upstream_response_time":$upstream_response_time,'
                '"request":"$request",'
                '"request_length":$request_length,'
                '"request_time":$request_time,'
                '"status":"$status",'
                '"http_referer":"$http_referer",'
                '"http_x_forwarded_for":"$http_x_forwarded_for",'
                '"http_user_agent":"$http_user_agent"'
                '}';

access_log  log/access.log   json ; 

输出的日志大约是这样
{"@timestamp":"2018-01-21T17:13:20+08:00","@version":"1","server_addr":"2.2.2.2","remote_addr":"1.1.1.1","host":"xxx.tencentyun.com","uri":"/interfaces/interface.php","upstream_response_time":0.131,"body_bytes_sent":312,"bytes_sent":489,"request":"POST /interfaces/interface.php HTTP/1.0","request_length":372,"request_time":0.238,"status":"200","http_referer":"-","http_x_forwarded_for":"-","http_user_agent":"-"}

配置filebeat 日志上报 filebeat.yml 

output.elasticsearch:
  hosts: ["your.elk.address:9200"]
  index: "%{[name]}-%{+yyyyMMdd}"

filebeat.prospectors:

## nginx相关日志的探测器
- input_type: log

  paths:
    - /data/log/tnginx_1_0_0-1.0/access.log 

  fields:
    name: "nginx_log_json"
    ## this is 自定义字段,方便后续按集群名字汇总。 当然也可以起其它名字
    cluster_name: web-access

 ## 一些filebeat的配置,包括从最后一行读取,文件自动释放FD等
 tail_files: true
 close_removed: true
 close_remane: true
 close_inactive: 1h
 ignore_older: 1h
  
  ##非常关键, 自定义的字段在root层。 这个后面稍后讲
  fields_under_root: true
  ##日志以json的方式进行本地解析, 拆词后的发送到filebeat 
  json.keys_under_root: true
  json.add_error_key: true

按上面的步骤配置后,nginx-access-log-json会被filebeat解析到一个一个分好的词,把数据上报到ES , 最后的日志结果类似这样:

{
  "_index": "nginx_log_json-20180121",
  "_type": "doc",
  "_id": "AWEX-dUURCyizcQtzIkX",
  "_score": null,
  "_source": {
    "@timestamp": "2018-01-21T09:12:23.525Z",
    "@version": "1",
    "beat": {
      "hostname": "100_125_96_55",
      "name": "100_125_96_55",
      "version": "5.5.0"
    },
##这一层就是root层, 所有的自定义变量会在这个层级上
    "body_bytes_sent": 1098,
    "bytes_sent": 1303,
    "cluster_name": "web-access",      ##这个是上面自定义的字段
    "host": "xxx.tencentyun.com",
    "http_referer": "-",
    "http_user_agent": "-",
    "http_x_forwarded_for": "-",
    "input_type": "log",
    "name": "nginx_log_json",
    "offset": 192139484,
    "remote_addr": "2.2.2.2",
    "request": "POST /interfaces/interface.php HTTP/1.1",
    "request_length": 432,
    "request_time": 0.045,
    "server_addr": "1.1.1.1",
    "source": "/data/log/tnginx_1_0_0-1.0/access.log",
    "status": "200",
    "type": "log",
    "upstream_response_time": 0.026,
    "uri": "/interfaces/interface.php"
  },
  "fields": {
    "@timestamp": [
      1516525943525
    ]
  },
  "highlight": {
    "cluster_name": [
      "@kibana-highlighted-field@trade@/kibana-highlighted-field@"
    ]
  },
  "sort": [
    1516525943525
  ]
}

kibana上搜索的结果会类似如下

kibana的绘图, 搜索和展示你认为有用的信息

比如,最近一段时间来源IP统计,比如最近一段平均请求时间

总之你能查询到数据,就能自定义你的视图展现

然后通过kibana的dashboarad给老板展示一个酷炫的报表

总结一下:

1.  nginx-log以json串的方式打印日志

2.  filebeat解析日志后,发送到es进行数据实时处理和分析

3. 利用kibana的功能,自定义数据报表

## FAQ 

F. 为什么日志要以json形式打印?  ELK本身也能解析日志拆词的? 

A: 如果日志是普通方式打印, 比如下面这样 ,就需要logstat  or es本身再对日志进行拆词,方式是形得通的。但我们用json打印后, filebeat就能直接解析上报,减少集中过滤带来的性能问题。 相信elk使用者,对于lostat的高CPU占用很头痛。

F: granafa的图表更酷炫,它能代替kibana进行数据展现吗? 

A: 是的,granfa的图表很好看, 它可以做为整个系统平台的有益补充,进行数据展现。 

大约方式是, 在granafa中定义一个数据源,然后用luence的语法查到数据后,然后展示在图表上。适合做数据报表,改动不大的情况, 比如下图的这种。 Kiaban的优势在于 非常高的自定义化,搜索条件可以自行输入。 比如  `status:>200 AND remote_addr:127.0.0.1` 这种组合, 会带你无尽的想像空间。 

F: elk汇总的数据延时是多少? 数据质量如何? 

A: 目前我们实测,100台8c8g500G的机器,支撑30k QPS数据写入,毫无压力 。如果换性能更好的机器,能得到更优的结果。  至于查询 , 应该是目前最好用的开源 全文日志搜索工具 ,  1000w行日志,实测30s内搜索得到结果,非常高效 . 

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在腾讯云上使用自建DNS

    在腾讯云上使用自建DNS , 这是一个非常非常非常硬的需求。非常多的程序模块要求,通过DNS解析去访问调用,但是,当你把dns改为自己的,接着腾讯云提供的套件服...

    莫韵
  • 简易 linux 网卡带宽检查工具纯 shell 和 awk

    最近要检查网卡流量,其实是有各种现存工具,非常容易实现 。但需要把这个东西与icinga2 集成起来搞报警什么的。这些cati collectd tsar 网管...

    莫韵
  • linux 根分区的空间去哪里了 ?记一次根分区满的服务故障排查记录

    linux 根分区的空间去哪里了 ?记一次根分区满的服务故障排查记录。我的排查思路是先找占用没有占用,找占用的文件句柄。

    莫韵
  • 我用 Python 爬取了全国 4500 个热门景点,告诉你国庆哪里去不得?

    金秋九月,丹桂飘香,在这秋高气爽,阳光灿烂的收获季节里,我们送走了一个个暑假余额耗尽哭着走向校园的孩子们,又即将迎来一年一度伟大祖国母亲的生日趴体(无心上班,迫...

    CDA数据分析师
  • Python爬取4500个景点:用echarts热力图分析国庆哪里最堵?

    于是我萌生了通过旅游网站的景点销量来判断近期各景点流量情况的想法(这个想法很危险啊)。

    机器学习AI算法工程
  • 工具 | w3af系列高级篇(三)

    本期带来w3af的高级使用,包括认证扫描,页面爬取和漏洞利用等几个部分。 一、认证扫描 w3af支持如下4种认证类型: HTTP Basic authen...

    漏斗社区
  • 4500个热门景点数据,告诉你国庆长假的正确打开姿势

    国庆出游,确实是个让人头痛的问题。今天这位数据侠,不仅用数据告诉你国庆如何成功避开“people mountain people sea”,还手把手带你用Pyt...

    DT数据侠
  • Audition快捷键

    今天朋友让测试一段代码,功能是音频分割.代码需要输入wav得文件.我手头没有,只好用Au转码一下,好长时间不用Au了.有点忘记操作.记录一下

    云深无际
  • 快速API自动化测试

    我们平时写API,时效性太慢了。而且花费的成本代价太高。特别是有严重的滞后性。当平台多,业务多,迭代多的时候,接口自动化实现出来的时候,黄花菜都凉了。

    赵云龙龙
  • 【Rust项目推荐】用actix-web 2.0-α 写了一个小工具

    偶然看到一个Json server 的 Rust 库 weld. 感觉挺好玩的, 但是代码比较老了, 试着用 actix-web 2.0 和 serde_jso...

    MikeLoveRust

扫码关注云+社区

领取腾讯云代金券