哈喽大家好,我是咸鱼YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
最近我们需要把 Nginx 的日志接入到自研的日志采集平台上,但是这个平台只支持 JSON 格式,所以需要把 Nginx 日志格式改成 JSON 格式YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
例如下面这样的效果YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
刚开始在主配置文件 nginx.conf 中定义了一个名叫 json 的日志格式字段YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
验证的时候其他内容没啥问题,但是时间是2023-09-12T13:54:22+08:00 这样子的,不太符合预期YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
咸鱼想着把 $time_iso8601 变量中的年月日时分秒分别提取出来然后用变量去接受它,如下所示:YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
我自定义了一个时间格式 $year-$month-$day $hour:$minutes:$seconds:000,然后接着用了一个 if 语句用于检查请求的时间是否匹配 ISO8601 时间格式(例如:2023-09-12T13:54:22+08:00)YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
如果匹配,它将执行其中的代码块。在代码块中,使用正则表达式提取时间的年、月、日、小时、分钟和秒,并将它们赋值给变量 $year、$month、$day、$hour、$minutes 和 $secondsYPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
但是 nginx -t 检测的时候我发现 if 语句不能够放在 http 块内,否则会报错YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
在 Nginx 中,if 语句主要用于在 server 或 location 块内设置条件,以便根据请求的属性来执行不同的配置。if 语句通常应该包含在 server 或 location 块内,而不是直接放在 http 块中YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
如果将 if 语句放在一个一个 server 块中,这不得累死我(有很多个 server 块),而且后期维护也不方便YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
所以如何将自定义变量在全局配置中生效则成为了一个问题YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
map
YPI28资讯网——每日最新资讯28at.com
map 指令是由 ngx_http_map_module 模块提供的,是 Nginx 配置文件中的一种用于创建变量映射的指令YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
模块链接:https://nginx.org/en/docs/http/ngx_http_map_module.htmlYPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
它允许我们将一个或多个输入值映射到一个输出值,类似于字典或哈希表的概念。map 指令通常用于根据特定条件为请求设置自定义变量,或者执行基于请求属性的条件控制YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
比较常见的 map 用法是通过 map 来实现允许多个域名跨域访问的问题YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
语法如下:YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
其中:YPI28资讯网——每日最新资讯28at.com
- $variable 输入变量,通常是 nginx 的内置变量。
- $new_variable 输出变量,它将根据输入值的映射设置为特定的结果。
- value1, value2, ... 输入值,可以列出多个值。
- result1, result2, ... 与相应输入值相关联的输出结果。
- default 一个可选项,表示如果没有匹配的输入值,将使用默认结果
YPI28资讯网——每日最新资讯28at.com
需要注意的是,map 只能放在 http 块中YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
有了 map,我们就可以轻易的把 $time_iso8601 变量中的 ISO 8601 格式的时间戳转换为指定的时间格式,然后存储到自定义变量 $log_time 中YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
我们可以看到:YPI28资讯网——每日最新资讯28at.com
- 输入变量为 $time_iso8601,输出变量为 $log_time;
- default "":如果没有匹配任何条件,将使用空字符串作为 $log_time 的值
- "~^(?<year>/d{4})-(?<month>/d{2})-(?<day>/d{2})T(?<hour>/d{2}):(?<minutes>/d{2}):(?<seconds>/d{2})":这是一个正则表达式条件,它用于匹配 ISO 8601 格式的时间戳。该正则表达式包含了多个捕获组(使用 ?<name> 语法),用于从时间戳中提取年、月、日、小时、分钟和秒的值
- "${year}-${month}-${day} ${hour}:${minutes}:${seconds}":这是与正则表达式条件匹配时设置的输出值。当正则表达式条件匹配时,它会将捕获组中提取的年、月、日、小时、分钟和秒的值组合成一个自定义的时间格式,然后将该值设置为 $log_time 变量的值
YPI28资讯网——每日最新资讯28at.com
例如,如果 $time_iso8601 的值是 "2023-09-09T14:30:00",则 $log_time 将被设置为 "2023-09-09 14:30:00"YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
然后我们再把 $log_time 放进我们自定义的日志格式里面,完整配置如下YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
最后我们验证一下YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
YPI28资讯网——每日最新资讯28at.com
本文链接:http://www.28at.com/showinfo-26-10492-0.htmlNginx map 实现时间格式转换
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 反驳来了!放弃TypeScript?说明你无知!
下一篇: 19个JavaScript数组常用方法总结! 赶快收藏吧!