ES 数据预处理 Ingest Node/Pipeline

需求

收集所有服务的请求日志,存储以供后续使用。

初步想法是用Nginx将所有服务的请求输出到日志,再由收集器将日志 收集起来->解析->存储。

使用ES家族的 filebeat 收集NG日志,可是收集到的日志不太好解析,而且还增加个时间字段,转换某些字段等操作,后来想法是再写个服务(或Logstash)吧 Filebeat调这个服务,由这个服务做处理解析。但是又感觉太重了,偶然发现 ES 原生 已经支持数据处理(filter)了。
于是花了半天研究了下,下面把坑、和使用方法都记一下。

具体参考了优秀的这篇文章:

关于 Ingest Node/Pipeline 的详解。赞!
https://www.felayman.com/articles/2017/11/24/1511527532643.html
还有官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/current/handling-failure-in-pipelines.html

先看下效果吧:
【源】NG log
61.50.98.62 - [08/Jan/2019:13:11:09 +0800] "GET /images/index/img05_11.jpg HTTP/1.1" 200 312473 "http://vipcode.cn/" - 0.210 0.052 100.118.58.9:80 200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3494.0 Safari/537.36

【结果】处理后存入后的效果:

要做的事情:

  1. 增加 gmt_create 记录数据时间。
  2. 将以空格分隔的NG日志 解析为 图中的K->V

解决过程:

  1. create index ... 略过。
  2. 创建pipeline(processor)增加gmt_create
  3. 创建pipeline(processor)解析 ng log
    2、3步最终是要合一起的,一个processor即增加了时间也解析了格式;可我初次试验的时候是分开调试的。

创建processor:

其中用到了 set 和 grok (在上面的连接中有介绍)
_ingest/pipeline/nglogproc

这里坑有两个,

  1. {{_ingest.timestamp}} 存到ES里的时间是UTC0的时间,晚于国内8小时。
  2. grok 的调试比较烦人,虽说写比较容易,比对数据是最耗时的。

解决方案:

  1. 因为 _ingest.timestamp 是ES生成的,没有找到通过哪个配置能修改,想了一晚上最后想编译源码解决去了。还好,不用管,Kibana会正常显示、检索。
  2. Grok语法和内置的表达式网上有很多,熟悉一下然后 根据这个调试器http://grokdebug.herokuapp.com,一点点来吧。

最后,post ES 处理保存数据:

没有出错就是文章开始的效果图了,_ingest.timestamp 不会出错,会出问题的多半出在grok和源数据不匹配的问题里,错误里会有部分提示。

One more thing, 贴出我的 grok
Log1:
112.17.88.223 - [08/Jan/2019:10:49:08 +0800] "GET /open_008/08_img6.png HTTP/1.1" 200 1445 "https://www.vipcd.com/_zh/open_008.min.css" - 0.005 0.004 59.110.185.113:80 200 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Log2:
39.104.152.143 - [08/Jan/2019:17:34:18 +0800] "GET / HTTP/1.1" 200 9262 "-" - 0.032 0.031 172.17.231.247:8080 200 Go-http-client/1.1
Log3:
39.82.11.241 - [22/Jan/2019:16:53:04 +0800] "GET /v1?uuid=vipcode2165376223244&uid=154814718762578s5dfaco&project=act&logType=pv&logVersion=1.0&refer=&ua=Mozilla%2F5.0%20(iPad%3B%20U%3B%20CPU%20OS%205_0%20like%20Mac%20OS%20X%3B%20en-us)%20AppleWebKit%2F534.46%20(KHTML%2C%20like%20Gecko)%20Version%2F5.1%20Mobile%2F9A334%20Safari%2F7534.48.3&subType=guangdiantong%7C%7ChasCode&screensize=w800||h1280&url=http%3A%2F%2Fact.vipcode.com%2Fmps%2Fproduce%2F1545381467902%2Fpc%2Findex.html%3FstClId%3D7%26sLClId%3D0%26plId%3D0%26unId%3D0%26kwd%3D%26lGPId%3D150%26acId%3D0%26pSId%3D28%26acPFlag%3D0%26sFFlag%3D0%26remark%3D113Lllq122105%26qz_gdt%3Df7mumxf7aaaoaehyrkya HTTP/1.1" 200 1 "http://act.vipcode.com/mps/produce/1545381467902/pc/index.html?stClId=7&sLClId=0&plId=0&unId=0&kwd=&lGPId=150&acId=0&pSId=28&acPFlag=0&sFFlag=0&remark=113Lllq122105&qz_gdt=f7mumxf7aaaoaehyrkya" - 0.000 - - - Mozilla/5.0 (iPad; U; CPU OS 5_0 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
Grok:
%{IP:client} %{USER:user} \[%{HTTPDATE:http_date}\] \"%{WORD:method} %{NOTSPACE:http_uri} HTTP/%{NUMBER:http_ver}\" %{NUMBER:http_st_ng} %{NUMBER:bytes} \"(?<referer>https?://[^ ]+|-)\" (?<x_forwarded_for>[0-9]+(\.[0-9]+){3}(?:, [0-9]+(\.[0-9]+){3})*|-) %{NUMBER:rsp_time1} (?:%{NUMBER:rsp_time2}|-) (?<target_server>[0-9]+(\.[0-9]+){3}(:[0-9]+)?|-) (?:%{NUMBER:http_st_server}|-) (?<u_agent>.*$)

nglogproc Pipleline:

{
    "description": "nginx log processor",
    "processors": [
      {
        "grok": {
          "field": "message",
          "patterns": [
            "%{IP:client} %{USER:user} \\[%{HTTPDATE:http_date}\\] \"%{WORD:method} %{NOTSPACE:http_uri} HTTP/%{NUMBER:http_ver}\" %{NUMBER:http_st_ng} %{NUMBER:bytes} \"(?<referer>[^\"]+|-)\" (?<x_forwarded_for>[0-9]+(\\.[0-9]+){3}(?:, [0-9]+(\\.[0-9]+){3})*|-) %{NUMBER:rsp_tn} (?<rsp_ts>[0-9.]+(, [0-9.]+)*|-) (?<tar_server>[0-9]+(\\.[0-9]+){3}(:[0-9]+)?(, ([0-9]+(\\.[0-9]+){3}(:[0-9]+)?))*|-) (?<http_st_server>[0-9]+(, [0-9]+)*|-) (?<u_agent>.*$)"
          ],
          "on_failure": [
            {
              "set": {
                "field": "g_err0",
                "value": "{{_ingest.on_failure_message }}"
              }
            }
          ]
        }
      },
      {
        "set": {
          "field": "gmt_create",
          "value": "{{_ingest.timestamp}}"
        }
      },
      {
        "grok": {
          "field": "http_uri",
          "patterns": [
            "/v\\d+\\?uuid=(?<uuid>[^&]*+)&uid=(?<uid>[^&]*+)&project=(?<project>[^&]*+)&logType=(?<logType>[^&]*+)&logVersion=(?<logVersion>[^&]*+)&refer=(?<refer>[^&]*+)&ua=(?<ua>[^&]*+)&subType=(?<subType>[^&]*+)&screensize=(?<screensize>[^&]*+)&url=(?<url>.*+$)"
          ],
          "on_failure": [
            {
              "set": {
                "field": "g_err1",
                "value": "{{_ingest.on_failure_message }}"
              }
            }
          ]
        }
      },
      {
        "urldecode": {
          "field": "ua",
          "on_failure": [
            {
              "set": {
                "field": "g_err2",
                "value": "{{_ingest.on_failure_message }}"
              }
            }
          ]
        }
      },
      {
        "urldecode": {
          "field": "url",
          "on_failure": [
            {
              "set": {
                "field": "g_err2",
                "value": "{{_ingest.on_failure_message }}"
              }
            }
          ]
        }
      },
      {
        "urldecode": {
          "field": "screensize",
          "on_failure": [
            {
              "set": {
                "field": "g_err2",
                "value": "{{_ingest.on_failure_message }}"
              }
            }
          ]
        }
      },
      {
        "urldecode": {
          "field": "subType",
          "on_failure": [
            {
              "set": {
                "field": "g_err2",
                "value": "{{_ingest.on_failure_message }}"
              }
            }
          ]
        }
      }
    ]
  }

这种方式的好处是非常简便,缺点是容错率非常低对格式有着严格的要求。

不过庆幸的是其提供了“当错误发生时你要做的事情 —— on_failure ”

Filebeat 使用 Pipeline
http://www.axiaoxin.com/article/236/
在FB配置文件中增加配置即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容