本文主要说明在使用Logtail进行日志采集时,如何有效地提取和处理具有纳秒精度的时间戳信息,确保对原始日志中的高精度时间数据进行准确捕获。
应用场景
某些业务场景下对时间精度要求较高(例如不同子模块日志保序要求),依赖毫秒甚至更高精度的时间戳,此时往往会在业务日志中打印毫秒精度的时间,这也就要求日志分析平台能够提供高精度时间戳的存储与查询分析能力。
使用Logtail进行日志采集时,可突破日志服务中存储模型中秒级精度时间戳的限制,根据业务需求提取纳秒精度的时间戳。
前提条件
已创建Project和Logstore。更多信息,请参见管理Project和管理Logstore。
已在服务器上安装Logtail,并已经创建了包含该服务器的机器组。
说明ECS安装具体操作,请参见安装Logtail(ECS实例)。
如果您的服务器是与日志服务属于不同账号的ECS、其他云厂商的服务器和自建IDC时,您需要手动安装Logtail。更多信息,请参见安装Logtail(Linux系统)。手动安装Logtail后,您必须在该服务器上手动配置用户标识。具体操作,请参见配置用户标识。
纳秒精度时间戳的提取功能需要Linux Logtail1.8.0及以上版本。
文件采集场景
原生插件解析
源日志样例:
2023.11.06-15.12.12.123456,10.10.*.*,"POST /PutData?Category=YunOsAccountOpLog&AccessKeyId=****************&Date=Fri%2C%2028%20Jun%202013%2006%3A53%3A30%20GMT&Topic=raw&Signature=******************************** HTTP/1.1",200,18204,aliyun-sdk-java
在Logtail配置中,单击其他全局配置,开启高级参数开关,输入
{ "EnableTimestampNanosecond": true}
。日志采集步骤请参见采集主机文本日志。
添加分隔符解析插件。具体配置说明,请参见分隔符模式解析。
添加时间解析插件。具体配置说明,请参见时间解析。
时间解析插件需要配置时间格式,例如分隔符插件解析后的字段
time
为2023.10.26-20.58.12.123456
,时间转换格式
应调整为%Y.%m.%d-%H.%M.%S.%f
,其中%f
为秒的小数部分,精度最高支持为纳秒。时间转换格式需要与原始日志中的时间格式保持一致,若不一致,就无法正常解析纳秒时间戳,详情参见常见问题。时间完整格式参考时间格式。配置索引结束后,在控制台查看解析结果,可以看到解析后的时间带有纳秒的时间戳。更多信息,请参见创建索引。
扩展插件提取日志时间(strptime时间格式)
源日志样例:
{
"asctime": "2023-10-25 23:51:10,199999999",
"filename": "generate_data.py",
"levelname": "INFO",
"lineno": 51,
"module": "generate_data",
"message": "{\"no\": 14, \"inner_loop\": 166, \"loop\": 27451, \"uuid\": \"9be98c29-22c7-40a1-b7ed-29ae6c8367af\"}",
"threadName": "MainThread"
}
在Logtail配置中,单击其他全局配置,开启高级参数开关,输入
{ "EnableTimestampNanosecond": true}
。日志采集步骤请参见采集主机文本日志。
添加展开JSON字段插件。具体配置说明,请参见展开JSON字段。
说明如果源日志为类似样例中的单层JSON,没有多层嵌套,配置JSON展开连接符用
""
。多层嵌套的JSON,配置JSON展开连接符用"_"
。添加提取日志时间(strptime时间格式)插件。具体配置说明,请参见strptime时间格式。
提取日志时间(strptime时间格式)插件需要配置时间格式,例如原始日志时间字段为
"asctime": "2022-04-29 21:37:40,251"
,时间转换格式
应调整为%Y-%m-%d %H:%M:%S,%f
,其中%f
为秒的小数部分,精度最高支持为纳秒。时间转换格式需要与原始日志中的时间格式保持一致,完整格式参考时间格式。配置索引结束后,在控制台查看解析结果,可以看到解析后的时间带有纳秒的时间戳。更多信息,请参见创建索引。
扩展插件提取日志时间(Go语言时间格式)
源日志样例:
{
"asctime": "2023-10-25 23:51:10,199999999",
"filename": "generate_data.py",
"levelname": "INFO",
"lineno": 51,
"module": "generate_data",
"message": "{\"no\": 14, \"inner_loop\": 166, \"loop\": 27451, \"uuid\": \"9be98c29-22c7-40a1-b7ed-29ae6c8367af\"}",
"threadName": "MainThread"
}
在Logtail配置中,单击其他全局配置,开启高级参数开关,输入
{ "EnableTimestampNanosecond": true}
。日志采集步骤请参见采集主机文本日志。
添加展开JSON字段插件。具体配置说明,请参见展开JSON字段。
说明如果源日志为类似样例中的单层JSON,没有多层嵌套,配置JSON展开连接符用
""
。多层嵌套的JSON,配置JSON展开连接符用"_"
。添加提取日志时间(Go语言时间格式)插件。具体配置说明,请参见Go语言时间格式。
提取日志时间(Go语言时间格式)的时间格式需要按照Golang的时间格式规范来编写。其中的格式化时间模板不是常见的
%Y-%m-%d %H:%M:%S
,而是使用Go语言的诞生时间2006-01-02 15:04:05 -0700 MST
。例如:2023-10-25 01:36:10,199999999
对应的时间格式应该为2006-01-02 15:04:05,999999999
。以下提供Golang官方的时间格式示例:
const ( Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order. ANSIC = "Mon Jan _2 15:04:05 2006" UnixDate = "Mon Jan _2 15:04:05 MST 2006" RubyDate = "Mon Jan 02 15:04:05 -0700 2006" RFC822 = "02 Jan 06 15:04 MST" RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone RFC850 = "Monday, 02-Jan-06 15:04:05 MST" RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone RFC3339 = "2006-01-02T15:04:05Z07:00" RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" Kitchen = "3:04PM" // Handy time stamps. Stamp = "Jan _2 15:04:05" StampMilli = "Jan _2 15:04:05.000" StampMicro = "Jan _2 15:04:05.000000" StampNano = "Jan _2 15:04:05.000000000" )
配置索引结束后,在控制台查看解析结果,可以看到解析后的时间带有纳秒的时间戳。更多信息,请参见创建索引。
常见问题
采集日志无法正常解析纳秒时间戳
配置采集后,发现高精度时间并未正常提取。
错误原因
插件模式支持%f,但是时间格式需要与源时间内容保持一致。
解决方法
登录Logtail机器,查看日志,发现大量STRPTIME_PARSE_ALARM异常日志。
tail -f /usr/local/ilogtail/logtail_plugin.LOG 2023-10-26 00:30:39 [WRN] [strptime.go:164] [processLog] [##1.0##xxxx,xxx] AlarmType:STRPTIME_PARSE_ALARM strptime(2023-10-26 00:30:10,199999999, %Y-%m-%d %H:%M:%S %f) failed: 0001-01-01 00:00:00 +0000 UTC, <nil>
修改插件日志解析格式。
原始日志时间为
2023-10-26 00:30:10,199999999
,秒与高精度时间(这里是毫秒)之间分隔符为半角逗号(,),解析格式为%Y-%m-%d %H:%M:%S %f
,秒与高精度时间之间分隔符为空格 。修改采集配置中时间转换格式为
%Y-%m-%d %H:%M:%S,%f
即可。