开发者学堂课程【DevOps 日志分析实战 :Nginx 日志分析(一)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/736/detail/13102
Nginx 日志分析(一)
内容介绍:
一、数据加工
二、code 码
三、通过 UserAgent 判断客户端操作系统
一、数据加工
通过前面的课程介绍知道阿里云日志服务(SLS)是面向日志场景提供了包括数据实时采集、数据加工、数据智能查询分析、数据分发。
本节主要内容为围绕数据加工
1.数据加工简介:
数据加工是阿里云日志服务提供的一项面向日志实时处理的一项功能,提供了200多个函数用来解决日志行处理过程中遇到的过滤、复制、分裂、补漏、孵化转化等场景。后面在实战的过程中会对这几类产品进行真实的内容演示和介绍。
2.本次主题:
本次实战以 Nginx 日志为例,介绍日志服务( SLS )以下功能
数据加工☆(功能)
查询、分析、可视化、报警
3.数据加工的交互界面:
该处有一个已经采集完成的 nginx 日志,点击查询界面时看到上面有一个数据加工的开关,打开该开关就可以进行数据加工的代码编写:
在上图右边有一个预览数据,会对数据加工的函数进行执行,然后查看效果。有两种预览的形式,一种是快速预览,另一种是高级预览,一般情况下可以使用快速预览。
如果在数据加工的函数中用到了数据孵化、资源函数,有可能要去连 MySQL 或者 OSS ,那么快速预览模式不会真正的连接数据库或者 OSS 。需要用维表数据直接模拟数据的方式来做模拟,如果需要真实的连接 MySQL 或者 OSS,则需要用高级预览的方式来真实的运行。(后面在真实的 case 中会做演示)
在数据加工中想知道支持哪些函数,可以点击 DSL 简介。
进入后在左侧帮助文档中找到函数总览,点击后可以看到应一个完整的数据加工支持的函数列表,部分界面如下:
这里根据函数的场景进行分类,可以根据场景选择相应的函数进行数据加工。
4.举例:
给数据设置一个新的字段
代码:
e_set(“a”,”hello”)
快速预览:
看到新增一个字段,可以在原始数据中看到没有该字段,说明该字段为新增字段。
在写完该数据加工的作业后,可以看到一个保数据加工的按钮,点击保存数据加工,然后进行相应的配置就可以数据加工任务的上限(在后面实战的过程中会演示上限的流程)
使用正则提取对象
现在使用的是极简的方式采集 nginx 数据内容,所有数据内容会被放在一个 content 的字段中:
这样的日志内容非常不利于分析,可以提供正则的方式把该内容抽取成相应的字段,这里可以用到函数:
e_regex ("content", '(?<remote _addr>[0-9:\.]*)-(?<remote_user>[a-zA-Z0-9\-_]*)\[(?<local_time[a-zA-z0-9\/:\-\+]*)\]"(?<request>[^"]*)”(?<status>[0-9]*)(?<body_bytes_sent>[0-9\-]*)“(?<refer>[^"]*)""(?<http_user_agent>[^"]*)"‘)
其第一个参数是需要被正则抽取的字段,这里是 content 字段,第二个是正则表达式,这里指定了有名不过组,其字段的名字为 remote _addr。
预览效果为:
通过快速预览看到其效果,并且发现多了很多字段,包括 refer、remote_addr、request、status 等等。
5.处理时间字段
预览中看到 local_time 这个字段的时间并不是容易阅读,可以将其改为常见的日志格式。
可以使用 e_set 算子(用来设置字段的值),dt_strptime(将字符串转换为日期时间对象),dt_strftime(转换为自己想要的格式)
语句如下:
e_set("local_time" , dt_strftime(dt_strptime(v("local_time"),"%d/%b/%Y%H:%M:%S%z"),"%Y-%m-%d%H:%M:%S”)]
首先调用 dt_strptime 把 local_time 的内容用格式 %d/%b/%Y%H:%M:%S%z 去解析,解析完成后得到一个日期格式的对象,该对象可以被 dt_strftime 格式化,然后转换为较常见的日期格式:%Y-%m-%d%H:%M:%S 。
%后面是对应时间的格式,例如 %d 表示 date。
最终会设置为 local_time 这个字段。
快速预览查看器效果:
发现通过处理将 local_time 的字段处理为想要的日期格式。
6.解析 request uri
看到 request uri 的请求:
此处包含了三部分内容,分别是 request messaged、request url、http 请求的版本。
首先将该字段通过正则的方式解析成三个字段,然后对 url 处理把真实请求的字段转换,还可以把其中 get 请求中的键值对再抽取为键值字段方便后面分析。
7.如何实现:
e_regex(""request", "(?<request_method>[^\s]*)(?<request_uri>[*\s]*)(?<http_version>[^\s]*)")
e _set("request_url" , url_decoding(v("request_url")))
e_kv( "request_url", prefix="url_")
(注意:编辑的快捷键,如果想要注释掉一块代码,可以选中代码然后点击 ctrl+/)
先将下面两行内容添加注释,然后快速预览:
通过 e_regex 抽取,可以看到 http_version 已经被抽取,还有request_url 也被抽取出来。
将第一行注解解除
对 request_url 将其中对 url 编码进行一次解码操作,使用的是
url_decoding 函数,该函数输入需要 url_decoding 的字符串,该字
符串来自 request_url,通过 v("request_url") 可以对该字段进行
取值,
取值完成后传给 url_decoding,然后再设置回 request_url。效果
如下:
通过 url_decoding ,可以看到 url 已经还原为原始请求
还想对 get 请求的 key value进行抽取
解除第三行注释
用 e_kv 可以对 request_url 里面的 get 请求中的参数进行提取。
效果如下:
可以看到该处的 url_action 、url_item_id、url_item_name 已经
被提
取,但是他们前面都加了前缀 url_,因为是由 prefix 指定的,如果
不指定 prefix 则会直接使用 get 请求中 key 名字作为抽取字段
的名字。
将 e_kv( ""request_url", prefix="url_") 改为 e_kv( "request_url"),快速预览的效果为:
发现 item_name 已经抽取出来并且名字保持一样,可能会与已有的字段冲突,所以为了统一可以加 prefix="url_",方便识别来自 url 的参数解析出的字段。