Nginx map 实现时间格式转换

这篇具有很好参考价值的文章主要介绍了Nginx map 实现时间格式转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

哈喽大家好,我是咸鱼

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

例如下面这样的效果
Nginx map 实现时间格式转换
刚开始在主配置文件 nginx.conf 中定义了一个名叫 json 的日志格式字段
Nginx map 实现时间格式转换
验证的时候其他内容没啥问题,但是时间是2023-09-12T13:54:22+08:00 这样子的,不太符合预期

Nginx map 实现时间格式转换
咸鱼想着把 $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 语句主要用于在 serverlocation 块内设置条件,以便根据请求的属性来执行不同的配置。if 语句通常应该包含在 serverlocation 块内,而不是直接放在 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 实现时间格式转换文章来源地址https://www.toymoban.com/news/detail-709757.html

到了这里,关于Nginx map 实现时间格式转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uni-app优雅的实现时间戳转换日期格式

    现在显示的格式如下图: 我期望统一格式,所以不妨前端处理一下,核心代码如下 使用方法如下: 代码结构如下:

    2024年02月16日
    浏览(29)
  • java实现时间格式转换(int整数类型的秒/毫秒---时分秒毫秒)

    秒或毫秒类型的数值转为指定格式的时间格式: 运行结果如下: 当然,还可以指定自定义的格式转化显示。

    2024年02月11日
    浏览(38)
  • Java——时间戳和时间格式转换

    时间戳(TimeStamp):通常是一个字符序列,唯一地标志某一刻的时间。Java 中时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数。 一、获取时间戳的方式 二、Date类 1、无参构造方法——返回结果Thu Dec 15 09:55:39 CST 2022 2、有参构造方法——已废弃 三、时间格式

    2024年02月11日
    浏览(28)
  • 时间格式转换

    2023年04月09日
    浏览(24)
  • 【js】时间和时间戳转换、日期格式化

    1、时间戳转换日期方法 (格式:2023-08-17) 2、日期字符串转时间戳 3、时间戳转换日期+时间方法 date:时间戳数字(格式:2023-08-17 14:11:01) 4、 获取日期中文格式

    2024年02月12日
    浏览(40)
  • 九、python-时间数据格式转换

    关于数据格式转换,最常用的就是时间格式的转换 如果时间数据是以字符串格式存入,那就无法进行时间运算,需要把字符串格式的时间数据转换成真正的时间格式数据。下面是常见的时间格式处理方法 首先,导入 datetime 模块,使用 datetime() 函数; 然后, 按照年、月、日

    2024年02月08日
    浏览(34)
  • sql字段类型和时间格式转换

    在SQL中,字段类型格式转换是指将数据从一种数据类型转换为另一种数据类型的过程。这通常涉及将字符串转换为日期、将数字转换为字符串、将整数转换为浮点数等。 SQL字段类型格式转换的原理如下: 显式转换:显式转换是指用户明确指定要执行的数据类型转换。这可以

    2024年02月08日
    浏览(36)
  • 在线时间戳格式化转换工具

    在线时间戳格式化转换工具 本工具支持在时间和时间戳之间相互转换,默认时间参考的是服务器时间 Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIXtime),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起

    2024年02月15日
    浏览(33)
  • 【Vue】使用moent转换GMT时间格式为北京时间

    名词解释 GMT(Greenwich Mean Time)和UTC(Coordinated Universal Time)是两个时间标准,它们在许多方面非常相似,但也有一些微小的差异。 GMT最初是在1884年确定的,它是以英国伦敦的格林威治天文台的时间为基准。GMT使用了一个固定的时区偏移,没有考虑夏令时的变化。因此,在夏

    2024年02月05日
    浏览(43)
  • 玩转Java时间格式转换(亲测可用)

    相信很多小伙伴在时间格式转换的时候非常头疼,我也是如此,所以总结以下的方法供大家使用,都是我自己用过没问题的大家开箱即用! 一、获取当前时间 二、获取当前时间戳 三、日期转时间戳 四、时间戳转换为时间 五、时间转换为时间戳 六、日期转字符串 七、字符串

    2024年02月13日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包