Nginx/Openresty日志时间显示到毫秒级的三种方法(不改源码)

在这里,我们生成三个自定义变量

#以下为内置变量
$time_iso8601  日期格式示例: 2022-09-08T18:16:01+08:00
$time_local    日期格式示例: 02/Aug/2022:11:11:32 +0800
$msec          日期格式示例: 1663839717.105 当前的Unix时间戳,单位为秒,小数为毫秒

#生成自定义变量
$time_zh    示例值: 2022-10-08 22:00:18
$timestamp  示例值: 1663839717105
$time_zh_ms 示例值: 2022-10-08 22:00:18,888

方法一 :set (只能在server节点内)

建议创建独立 conf 文件,使用include方式,如:time-zh.conf 内容如下:

# 该 文件使用方法  在 nginx 配置 server 节点内:   include time-zh.conf;
#
# nginx 内置变量,解析为定义格式,仅支持到秒 (实现支持到毫秒)
#
# $time_iso8601  日期格式示例: 2022-09-08T18:16:01+08:00
# $time_local    日期格式示例: 02/Aug/2022:11:11:32 +0800
# $msec          日期格式示例: 1663839717.105 当前的Unix时间戳,单位为秒,小数为毫秒
# 自定义变量 - 默认值
#set $time_zh $time_iso8601;
#set $timestamp $msec;
#set $time_zh_ms $time_zh,000;

# 格式化日期
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\+\d{2})") {
  set $year   $1;
  set $month  $2;
  set $day    $3;
  set $hour   $4;
  set $minute $5;
  set $second $6;
  # 时区,只到小时
  set $time_zone $7;
  # 自定义 yyyy-MM-dd hh:mi:ss 格式
  set $time_zh "$1-$2-$3 $4:$5:$6";
}
# 时间戳,单位毫秒  使用 $msec 去除中间的小数点实现
if ($msec ~ "^(\d+)\.(\d+)") {
  set $timestamp $1$2;
  # 自定义 yyyy-MM-dd hh:mi:ss,SSS 带毫秒格式
  set $time_zh_ms $time_zh,$2;
}

方法二: set_by_lua (只能在server节点内)

建议创建独立 conf 文件,使用include方式,如:time-zh-lua.conf 内容如下:

# 该 文件使用方法  在 nginx 配置 server 节点内:   include time-zh-lua.conf;
#
# nginx 内置变量,解析为定义格式,仅支持到秒 (实现支持到毫秒)
#
# 取 ngx_lua 模块提供的带缓存的时间接口
# ngx.now()          日期格式示例: 1663839717.105  当前的Unix时间戳,单位为秒,小数为毫秒; 与 nginx 内置变量 $msec 相同
#                          -- 因 nginx 有缓存时间,所以与实际服务器时间会有些许偏差,可能偏差几毫秒 - 正常业务可忽略不计
#                          -- 若 一定要强一致,可先调用 ngx.update_time() 强制更新,但成本较高,不推荐使用
# ngx.time()         日期格式示例: 1663839717  当前的Unix时间戳,单位为秒(1970年至今)
# ngx.var.time_local 日期格式示例: 02/Aug/2022:11:11:32 +0800
# ngx.utctime()      日期格式示例: 2022-09-08 10:16:01
# ngx.localtime()    日期格式示例: 2022-09-08 18:16:01
# ngx.today()        日期格式示例: 2022-09-08
#

# 本地时间(yyyy-MM-dd hh:mi:ss)
set_by_lua $time_zh 'return ngx.localtime()';

# Unix时间戳,单位为毫秒
set_by_lua $timestamp 'return ngx.now() * 1000';

# 本地时间(yyyy-MM-dd hh:mi:ss,SSS)
# 毫秒数: 先用 ngx.now()%1, 取余数去除秒的部分,再*1000获取毫秒部分,再用 math.floor + 0.5 四舍五入,再用 string.format 固定3位长度
set_by_lua $time_zh_ms 'return ngx.localtime()..","..string.format("%03d", math.floor(ngx.now()%1*1000+0.5))';

方法三: map (在http节点内)

建议创建独立 conf 文件,使用include方式,如:time-zh-map.conf 内容如下:

# 该 文件使用方法  在 nginx 配置 http 节点内:   include time-zh-map.conf;
#
# nginx 内置变量,解析为定义格式,仅支持到秒
#
# $time_iso8601  日期格式示例: 2022-09-08T18:16:01+08:00
# $time_local    日期格式示例: 02/Aug/2022:11:11:32 +0800
# $msec          日期格式示例: 1663839717.105 当前的Unix时间戳,单位为秒,小数为毫秒

# 使用以下 map 必须增加 map_hash_bucket_size 大小,否则会报异常
# 默认值为 cpu 的缓存行大小,一般为64
map_hash_bucket_size 128;

# 自定义 yyyy-MM-dd hh:mi:ss 格式
map $time_iso8601 $time_zh {
  default $time_iso8601;
  "~(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(\+\d{2})" "$1 $2";
}

# 时间戳,单位毫秒  使用 $msec 去除中间的小数点实现
map $msec $timestamp {
  default $msec;
  ~(\d+)\.(\d+) $1$2;
}

# 自定义 yyyy-MM-dd hh:mi:ss,SSS 带毫秒格式
map "$time_iso8601 # $msec" $time_zh_ms {
  default $time_zh,000;
  "~(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(\+\d{2}:\d{2}) # (\d+)\.(\d+)$" "$1 $2,$5";
}

PS: 若存在多个Server, 推荐使用方法三, 则不需要每个 server 配置一次

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值