Nginx map 实现时间格式转换的方法

 更新时间:2023年09月15日 08:58:33   作者:咸鱼Linux运维  
最近我们需要把 Nginx 的日志接入到自研的日志采集平台上,但是这个平台只支持 JSON 格式,所以需要把 Nginx 日志格式改成 JSON 格式,这篇文章主要介绍了Nginx map 实现时间格式转换,需要的朋友可以参考下

最近我们需要把 Nginx 的日志接入到自研的日志采集平台上,但是这个平台只支持 JSON 格式,所以需要把 Nginx 日志格式改成 JSON 格式

例如下面这样的效果

刚开始在主配置文件 nginx.conf 中定义了一个名叫 json 的日志格式字段

验证的时候其他内容没啥问题,但是时间是 2023-09-12T13:54:22+08:00 这样子的,不太符合预期

咸鱼想着把 $time_iso8601 变量中的年月日时分秒分别提取出来然后用变量去接受它,如下所示:

我自定义了一个时间格式 $year-$month-$day $hour:$minutes:$seconds:000 ,然后接着用了一个 if 语句用于检查请求的时间是否匹配 ISO8601 时间格式(例如: 2023-09-12T13:54:22+08:00

如果匹配,它将执行其中的代码块。在代码块中,使用正则表达式提取时间的年、月、日、小时、分钟和秒,并将它们赋值给变量 $year $month $day $hour $minutes $seconds

    log_format json '{  "SYS_NO":"my_nginx",
                        "OS_TIME":"$year-$month-$day $hour:$minutes:$seconds",
                        "LOG_TYPE":"",
                        "RESULT":"$status",
                        "SPENT_TIME":"$request_time",
                        "CLIENT_IP":"$remote_addr",
                        "SERVER_IP":"$server_addr",
                        "O_CHANNEL":"$http_user_agent",
                        "UID":"$http_host",
                        "VALUE1":$body_bytes_sent,
                        "INFO1":"$http_referer",
					}';
	  if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
                        set $year $1;
                        set $month $2;
                        set $day $3;
                        set $hour $4;
                        set $minutes $5;
                        set $seconds $6;
                        }

但是 nginx -t 检测的时候我发现 if 语句不能够放在 http 块内,否则会报错

在 Nginx 中,if 语句主要用于在 server location 块内设置条件,以便根据请求的属性来执行不同的配置。if 语句通常应该包含在 server location 块内,而不是直接放在 http 块中

如果将 if 语句放在一个一个 server 块中,这不得累死我(有很多个 server 块),而且后期维护也不方便

所以如何将自定义变量在全局配置中生效则成为了一个问题

map

map 指令是由 ngx_http_map_module 模块提供的,是 Nginx 配置文件中的一种用于创建变量映射的指令

模块链接:Module ngx_http_map_module (nginx.org)

它允许我们将一个或多个输入值映射到一个输出值,类似于字典或哈希表的概念。 map 指令通常用于根据特定条件为请求设置自定义变量,或者执行基于请求属性的条件控制

比较常见的 map 用法是通过 map 来实现允许多个域名跨域访问的问题

语法如下:

map $variable $new_variable {
    value1   result1;
    value2   result2;
    ...
    default  default_result;
}

其中:

  • $variable 输入变量,通常是 nginx 的内置变量。
  • $new_variable 输出变量,它将根据输入值的映射设置为特定的结果。
  • value1 , value2 , ... 输入值,可以列出多个值。
  • result1 , result2 , ... 与相应输入值相关联的输出结果。
  • default 一个可选项,表示如果没有匹配的输入值,将使用默认结果

需要注意的是,map 只能放在 http 块中

有了 map,我们就可以轻易的把 $time_iso8601 变量中的 ISO 8601 格式的时间戳转换为指定的时间格式,然后存储到自定义变量 $log_time

# nginx.conf
	map $time_iso8601 $log_time {
        default "";
        "~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})" "${year}-${month}-${day} ${hour}:${minutes}:${seconds}";
    }

我们可以看到:

  • 输入变量为 $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 变量的值

例如,如果 $time_iso8601 的值是 "2023-09-09T14:30:00",则 $log_time 将被设置为 "2023-09-09 14:30:00"

然后我们再把 $log_time 放进我们自定义的日志格式里面,完整配置如下

    log_format json '{  "SYS_NO":"my_nginx",
                        "OS_TIME":"$log_time",
                        "LOG_TYPE":"",
                        "RESULT":"$status",
                        "SPENT_TIME":"$request_time",
                        "CLIENT_IP":"$remote_addr",
                        "SERVER_IP":"$server_addr",
                        "O_CHANNEL":"$http_user_agent",
                        "UID":"$http_host",
                        "VALUE1":$body_bytes_sent,
                        "INFO1":"$http_referer",
		}';
	map $time_iso8601 $log_time {
    	default "";
        "~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})" "${year}-${month}-${day} ${hour}:${minutes}:${seconds}";
    }

最后我们验证一下

到此这篇关于Nginx map 实现时间格式转换的文章就介绍到这了,更多相关Nginx map 实现时间格式转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Nginx进行URL转发的配置案例

    使用Nginx进行URL转发的配置案例

    Nginx是一个高性能的Web服务器和反向代理服务器,它还可以用于URL转发,在本教学文章中,我们将从安装Nginx开始,逐步介绍配置步骤,并展示一个URL转发的案例,感兴趣的朋友可以参考下
    2023-09-09
  • Ubuntu使用nginx搭建webdav文件服务器的详细过程

    Ubuntu使用nginx搭建webdav文件服务器的详细过程

    今天通过本文给大家分享Ubuntu使用nginx搭建webdav文件服务器的详细过程,在这小编提示大家在安装nginx时需要先安装nginx-full,具体安装方法跟随小编一起通过本文学习下吧
    2021-05-05
  • Nginx的一些基本功能极速入门

    Nginx的一些基本功能极速入门

    本文主要介绍一些Nginx的最基本功能以及简单配置,但不包括Nginx的安装部署以及实现原理。有兴趣的可以了解一下。
    2016-12-12
  • nginx部署前端项目后刷新浏览器报错404问题解决

    nginx部署前端项目后刷新浏览器报错404问题解决

    现在前端页面部署正常访问,但是刷新的时候出现了404,所以下面给整理下,这篇文章主要给大家介绍了关于nginx部署前端项目后刷新浏览器报错404问题的解决办法,需要的朋友可以参考下
    2023-11-11
  • 在Nginx服务器上安装SSL证书完成HTTPS请求的步骤详解(springboot项目)

    在Nginx服务器上安装SSL证书完成HTTPS请求的步骤详解(springboot项目)

    这篇文章主要介绍了在Nginx服务器上安装SSL证书完成HTTPS请求(springboot项目),首先需要下载证书到本地接着在Nginx独立服务器上安装证书,本文给大家介绍的非常详细,需要的朋友参考下吧
    2022-04-04
  • 利用Nginx反向代理功能解决WEB网站80端口被封的解决方法

    利用Nginx反向代理功能解决WEB网站80端口被封的解决方法

    大陆的网络环境,都在天朝神兽的制度下让我等小P民悲剧一片;动不动就拔网线、封机房;现在更厉害的一招,从网关封杀你的80端口,一旦被封,网站域名就无法访问
    2012-08-08
  • nginx反向代理之将80端口请求转发到8080

    nginx反向代理之将80端口请求转发到8080

    这篇文章主要介绍了nginx反向代理之将80端口请求转发到8080,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Nginx自定义日志中时间格式的操作方法

    Nginx自定义日志中时间格式的操作方法

    工作需要对接内部的日志中台,对日志打印有固定的格式要求,为了使Nginx的access日志也能被采集,需要对日志格式进行自定义,这篇文章主要介绍了Nginx自定义日志中时间格式,需要的朋友可以参考下
    2023-11-11
  • 利用Nginx实现URL重定向的简单方法

    利用Nginx实现URL重定向的简单方法

    使用Nginx的重定向功能时,除了可以重定向到新域名,还可以将请求重定向到特定的协议上,下面这篇文章主要给大家介绍了关于如何利用Nginx实现URL重定向的简单方法,需要的朋友可以参考下
    2022-04-04
  • 在Nginx用htpasswd对网站进行密码保护的设置方法

    在Nginx用htpasswd对网站进行密码保护的设置方法

    很多时候我们需要对一些网站进行密码保护,比如团队内部的站点、demo站点等等。这里所说的密码保护是服务器级的,并非网站应用层的注册登录那一套,而是利用服务器配置和htpasswd文件来实现访问的密码验证
    2013-06-06

最新评论