通過在 Logtail 採集配置中開啟納秒精度支援並配置時間解析外掛程式,可以採集和儲存毫秒、微秒、納秒級的高精度時間戳記。採集後的時間將拆分為秒級時間戳記 __time__ 和納秒位移量 __time_ns_part__ 兩個欄位進行儲存,以實現高精度的日誌排序與分析。
業務情境說明
在分布式追蹤、高頻交易、效能剖析或對日誌嚴格保序等情境中,秒級的時間精度無法滿足業務需求。這些情境的業務日誌中通常會記錄毫秒、微秒甚至納秒級的時間戳記。本方案旨在指導如何配置 Logtail,以完整地採集、儲存和分析這些高精度時間資訊,確保日誌分析的準確性和時序性。
方案架構
LoongCollector(Logtail)採集納秒精度時間戳記的核心機制是在標準秒級時間戳記之外,額外儲存一個納秒級的位移量。此設計旨在相容現有以秒為單位的時間系統,同時提供高精度排序能力。
核心工作流程如下:
開啟納秒支援:在 Logtail 採集配置的進階參數中,通過
{ "EnableTimestampNanosecond": true }啟用高精度時間處理能力。此功能僅適用於 Logtail 1.8.0 及以上版本的 Linux 環境。日誌解析:使用分隔字元、JSON 或Regex等外掛程式從原始日誌中提取包含高精度時間戳記的字串。
時間轉換:時間解析外掛程式將時間字串轉換為標準時間格式。
時間儲存:Log Service將時間拆分為兩個欄位進行儲存:
__time__:標準的 Unix 時間戳記(長整型),單位為秒。__time_ns_part__:納秒部分(長整型),取值範圍為 0 到 999,999,999。
查詢與分析:在查詢分析時,通過對
__time__和__time_ns_part__兩個欄位組合排序,可以實現嚴格的日誌時序分析。
實施步驟
本節將以一個包含納秒級時間戳記的JSON 日誌為例,提供一個從日誌採集、解析、索引配置到最終查詢分析的完整端到端操作流程。
步驟一:建立Project和Logstore
採集日誌前,需規劃並建立用於管理與儲存日誌的Project和Logstore。
Project:Log Service的資源嵌入式管理單元,用於隔離和管理不同專案或業務的日誌。
Logstore:日誌儲存單元,用於儲存日誌。
如果已提前建立,可跳過本步驟,直接進入配置機器組(安裝LoongCollector)。
單擊建立Project,並配置:
所屬地區:根據日誌來源選擇,建立後不可修改。
Project名稱:阿里雲內全域唯一,建立後不可修改。
其他配置保持預設,單擊建立。如需瞭解其他參數,請參見管理Project。
單擊Project名稱,進入目標Project。
在左側導覽列,選擇
,單擊+。在建立Logstore頁面,完成以下核心配置:
Logstore名稱:設定一個在Project內唯一的名稱,建立後不可修改。
Logstore類型:根據規格對比選擇標準型或查詢型。
計費模式:
按使用功能計費:按儲存、索引、讀寫次數等各項資源獨立計,適合小規模或功能使用不確定的情境。
按寫入資料量計費:僅按原始寫入資料量計費,並提供30天的免費儲存周期及免費的資料加工、投遞等功能。成本模型簡單,適合儲存周期接近30天或資料處理鏈路複雜的情境。
資料儲存時間:設定日誌的保留天數,取值範圍為1~3650天(3650天表示永久儲存)。預設為30天。
其他配置保持預設,單擊確定。如需瞭解其他參數,請參考管理Logstore。
步驟二: 配置機器組(安裝LoongCollector)
在成功建立Project和Logstore後,為伺服器安裝LoongCollector並將其加入機器組。本文以ECS執行個體安裝LoongCollector(ECS與Log ServiceProject屬於同一阿里雲帳號和地區)為例,若ECS執行個體與Project不屬於同一帳號或地區,或為自建伺服器請參考LoongCollector安裝(Linux)手動安裝。
此功能僅支援 Linux 系統的LoongCollector( Logtail),在 Windows 系統上配置不生效,Logtail版本為1.8.0及以上。
單擊目標Project,在日誌庫(Logstore)
所有文本日誌接入模板僅在解析外掛程式上有所差異,其餘配置流程一致,後續均可修改。 |
|
配置步驟:
在機器組配置頁面,配置如下參數:
使用情境:主機情境
安裝環境:ECS
配置機器組:根據目標伺服器的LoongCollector安裝情況與機器組配置狀態,選擇對應操作:
已安裝LoongCollector且已加入某個機器組,可直接在源機器組列表中勾選,將其添加至應用機器組列表,無需重複建立。
未安裝LoongCollector,單擊建立機器組:
以下步驟將引導您完成LoongCollector的自動安裝並建立新機器組。
系統會自動列出與 Project 同地區的 ECS 執行個體,勾選需要採集日誌的一台或多台執行個體。
單擊安裝並建立為機器組,系統將自動在所選ECS執行個體上安裝LoongCollector。
配置機器組名稱並單擊確定。
說明如果安裝失敗或一直處於等待中,請檢查ECS地區是否與Project相同。
如需將已安裝LoongCollector的伺服器加入已有機器組,請參考常見問題如何將伺服器加入到已有機器組?
步驟三:建立採集配置
通過控制台配置
完成LoongCollector安裝和機器組配置後,進入Logtail配置頁面,開始定義日誌採集和處理規則。
1. 開啟納秒精度支援
定義日誌的採集源、採集規則,並開啟納秒精度支援。
全域配置:
配置名稱:設定一個在Project內唯一的名稱。建立成功後,無法修改。
:開啟進階參數開關,並輸入以下 JSON 內容以開啟納秒精度支援:
{ "EnableTimestampNanosecond": true }
輸入配置:
類型:文本日誌採集。
檔案路徑:日誌採集的路徑。
Linux:以“/”開頭,如
/data/mylogs/**/*.log,表示/data/mylogs目錄下所有尾碼名為.Log的檔案。Windows:以盤符開頭,如
C:\Program Files\Intel\**\*.Log。
最大目錄監控深度:檔案路徑中萬用字元
**匹配的最大目錄深度。預設為0(僅監控本層目錄)。
2. 配置處理外掛程式
由於源日誌為 JSON 格式,在處理配置地區,添加JSON解析外掛程式,從原始日誌中分離出包含納秒時間戳記的字串,並將其存為一個獨立的欄位。
添加日誌範例
假設記錄檔中的日誌格式如下,其中
asctime欄位包含了納秒精度的時間戳記。{ "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" }添加JSON解析外掛程式
單擊添加處理外掛程式,選擇,單擊確認。
添加時間解析外掛程式
將上一步提取的時間字串(
asctime欄位)轉換為標準的納秒時間戳記,並將其作為該條日誌的事件時間。外掛程式名稱
核心功能
適用情境
時間解析
基礎時間解析
簡單情境,格式固定。
提取日誌時間 (strptime時間格式)
靈活,支援豐富的
strptime格式推薦使用。功能全面,與業界標準相容。
提取日誌時間 (Go語言時間格式)
使用 Go 語言標準庫格式
熟悉 Go 語言或日誌格式與 Go 標準庫匹配的情境。
時間解析
單擊添加處理外掛程式,選擇,進行如下配置:
原始欄位:解析日誌前,用於存放時間的原始欄位,本樣本為
asctime。時間格式:根據日誌的時間欄位內容設定對應的時間格式,本樣本為
%Y-%m-%d %H:%M:%S,%f。其中%f為秒的小數部分,精度最高支援為納秒。時間格式字串必須與原始日誌中的時間格式(包括秒和納秒之間的分隔字元,如
,或.)完全一致,否則無法正確解析。時區:選擇日誌時間欄位所在的時區,預設使用機器時區。
提取日誌時間(strptime時間格式)
單擊添加處理外掛程式,選擇,進行如下配置:
原始欄位:解析日誌前,用於存放時間的原始欄位,本樣本為
asctime。原始時間格式:根據日誌的時間欄位內容設定對應的時間格式,本樣本為
%Y-%m-%d %H:%M:%S,%f。其中%f為秒的小數部分,精度最高支援為納秒。時間格式字串必須與原始日誌中的時間格式(包括秒和納秒之間的分隔字元,如
,或.)完全一致,否則無法正確解析。
提取日誌時間(Go語言時間格式)
單擊添加處理外掛程式,選擇,進行如下配置:
原始時間欄位:解析日誌前,用於存放時間的原始欄位,本樣本為
asctime。原始時間格式:根據原始日誌的時間欄位設定對應的時間格式,需要按照Golang的時間格式規範來編寫。格式化時間模板為Go語言的誕生時間
2006-01-02 15:04:05 -0700 MST。本樣本對應的時間格式為2006-01-02 15:04:05,999999999。時間格式字串必須與原始日誌中的時間格式(包括秒和納秒之間的分隔字元,如
,或.)完全一致,否則無法正確解析。結果時間欄位:解析日誌後,用於存放時間的目標欄位,本樣本為
result_asctime。結果時間格式:解析日誌後的時間格式,按照Golang的時間格式規範編寫。本樣本為
2006-01-02 15:04:05,999999999Z07:00。
3. 配置索引
完成Logtail配置後,單擊下一步。進入查詢分析配置頁面:
配置完成後,單擊下一步,完成整個採集流程的設定。
通過CRD配置(Kubernetes 情境)
在 ACK 或自建 Kubernetes 叢集中,可以通過 AliyunLog CRD 來配置納秒精度時間戳記的採集。以下是三種不同外掛程式的配置範例。
時間解析
apiVersion: telemetry.alibabacloud.com/v1alpha1
kind: ClusterAliyunPipelineConfig
metadata:
name: ${your-config-name}
spec:
config:
aggregators: []
global:
EnableTimestampNanosecond: true
inputs:
- Type: input_file
FilePaths:
- /test/sls/json_nano.log
MaxDirSearchDepth: 0
FileEncoding: utf8
EnableContainerDiscovery: true
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_parse_timestamp_native
SourceKey: asctime
SourceFormat: '%Y-%m-%d %H:%M:%S,%f'
flushers:
- Type: flusher_sls
Logstore: ${your-logstore-name}
sample: |-
{
"asctime": "2025-11-03 15:39:14,229939478",
"filename": "log_generator.sh",
"levelname": "INFO",
"lineno": 204,
"module": "log_generator",
"message": "{"no": 45, "inner_loop": 15, "loop": 1697, "uuid": "80366fca-a57d-b65a-be07-2ac1173505d9"}",
"threadName": "MainThread"
}
project:
name: ${your-project-name}
logstores:
- name: ${your-logstore-name}提取日誌時間(strptime時間格式)
apiVersion: telemetry.alibabacloud.com/v1alpha1
kind: ClusterAliyunPipelineConfig
metadata:
name: ${your-config-name}
spec:
config:
aggregators: []
global:
EnableTimestampNanosecond: true
inputs:
- Type: input_file
FilePaths:
- /test/sls/json_nano.log
MaxDirSearchDepth: 0
FileEncoding: utf8
EnableContainerDiscovery: true
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_strptime
SourceKey: asctime
Format: '%Y-%m-%d %H:%M:%S,%f'
KeepSource: true
AlarmIfFail: true
AdjustUTCOffset: false
flushers:
- Type: flusher_sls
Logstore: ${your-logstore-name}
sample: |-
{
"asctime": "2025-11-03 15:39:14,229939478",
"filename": "log_generator.sh",
"levelname": "INFO",
"lineno": 204,
"module": "log_generator",
"message": "{"no": 45, "inner_loop": 15, "loop": 1697, "uuid": "80366fca-a57d-b65a-be07-2ac1173505d9"}",
"threadName": "MainThread"
}
project:
name: ${your-project-name}
logstores:
- name: ${your-logstore-name}提取日誌時間(Go語言時間格式)
apiVersion: telemetry.alibabacloud.com/v1alpha1
kind: ClusterAliyunPipelineConfig
metadata:
name: ${your-config-name}
spec:
config:
aggregators: []
global:
EnableTimestampNanosecond: true
inputs:
- Type: input_file
FilePaths:
- /test/sls/json_nano.log
MaxDirSearchDepth: 0
FileEncoding: utf8
EnableContainerDiscovery: true
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_gotime
SourceKey: asctime
SourceFormat: '2006-01-02 15:04:05,999999999'
DestKey: result_asctime
DestFormat: '2006-01-02 15:04:05,999999999Z07:00'
SetTime: true
KeepSource: true
NoKeyError: true
AlarmIfFail: true
flushers:
- Type: flusher_sls
Logstore: ${your-logstore-name}
sample: |-
{
"asctime": "2025-11-03 15:39:14,229939478",
"filename": "log_generator.sh",
"levelname": "INFO",
"lineno": 204,
"module": "log_generator",
"message": "{"no": 45, "inner_loop": 15, "loop": 1697, "uuid": "80366fca-a57d-b65a-be07-2ac1173505d9"}",
"threadName": "MainThread"
}
project:
name: ${your-project-name}
logstores:
- name: ${your-logstore-name}步驟四:結果驗證
配置完成後,等待片刻,新的日誌資料將被採集到Logstore中。
在Log Service的查詢分析頁面,查看採集日誌,控制台會根據高精度的時間資訊,自動進行顯示最佳化,顯示成毫秒、微秒、納秒的形式。

常見問題
採集日誌無法正常解析納秒時間戳記
配置採集後,發現高精度時間並未正常提取。

錯誤原因
外掛程式模式支援%f,但是時間格式需要與源時間內容保持一致。
解決方案
登入LoongCollector(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即可。
成本與限制說明
成本影響:
__time_ns_part__欄位會作為日誌內容的一部分被儲存,略微增加原始日誌的儲存量。環境限制:此功能僅支援 Linux 系統的 Logtail 1.8.0 及以上版本,在 Windows 系統上配置不生效。
相關文檔
附錄一:常見日誌時間格式
Linux伺服器中,Logtail支援strftime函數提供的所有時間格式。即能被strftime函數格式化的日誌時間字串都能被Logtail解析並使用。
時間格式 | 說明 | 樣本 |
%a | 星期的縮寫。 | Fri |
%A | 星期的全稱。 | Friday |
%b | 月份的縮寫。 | Jan |
%B | 月份的全稱。 | January |
%d | 每月第幾天,十進位,範圍為01~31。 | 07, 31 |
%f | 秒的小數部分(毫秒、微秒或納秒) | 123 |
%h | 月份的縮寫,等同於%b。 | Jan |
%H | 小時,24小時制。 | 22 |
%I | 小時,12小時制。 | 11 |
%m | 月份,十進位,範圍為01~12。 | 08 |
%M | 分鐘,十進位,範圍為00~59。 | 59 |
%n | 分行符號。 | 分行符號 |
%p | AM或PM。 | AM、PM |
%r | 12小時制的時間組合,等同於%I:%M:%S %p。 | 11:59:59 AM |
%R | 小時和分鐘組合,等同於%H:%M。 | 23:59 |
%S | 秒數,十進位,範圍為00~59。 | 59 |
%t | Tab符號,定位字元。 | 無 |
%y | 年份,十進位,不帶世紀,範圍為00~99。 | 04、98 |
%Y | 年份,十進位。 | 2004、1998 |
%C | 世紀,十進位,範圍為00~99。 | 16 |
%e | 每月第幾天,十進位,範圍為1~31。 如果是個位元字,前面需要加空格。 | 7、31 |
%j | 一年中的天數,十進位,範圍為001~366。 | 365 |
%u | 星期幾,十進位,範圍為1~7,1表示周一。 | 2 |
%U | 每年的第幾周,星期天是一周的開始,範圍為00~53。 | 23 |
%V | 每年的第幾周,星期一是一周的開始,範圍為01~53。 如果一月份剛開始的一周>=4天,則認為是第1周,否則認為下一個星期是第1周。 | 24 |
%w | 星期幾,十進位,範圍為0~6,0代表周日。 | 5 |
%W | 每年的第幾周,星期一是一周的開始,範圍為00~53。 | 23 |
%c | 標準的日期和時間。 | Tue Nov 20 14:12:58 2020 |
%x | 標準的日期,不帶時間。 | Tue Nov 20 2020 |
%X | 標準的時間,不帶日期。 | 11:59:59 |
%s | Unix時間戳記。 | 1476187251 |
時間格式樣本
常見的時間標準、樣本及對應的時間運算式如下所示。
樣本 | 時間運算式 | 時間標準 |
2017-12-11 15:05:07 | %Y-%m-%d %H:%M:%S | 自訂 |
[2017-12-11 15:05:07.012] | [%Y-%m-%d %H:%M:%S | 自訂 |
2017-12-11 15:05:07.123 | %Y-%m-%d %H:%M:%S.%f | 自訂 |
02 Jan 06 15:04 MST | %d %b %y %H:%M | RFC822 |
02 Jan 06 15:04 -0700 | %d %b %y %H:%M | RFC822Z |
Monday, 02-Jan-06 15:04:05 MST | %A, %d-%b-%y %H:%M:%S | RFC850 |
Mon, 02 Jan 2006 15:04:05 MST | %A, %d %b %Y %H:%M:%S | RFC1123 |
2006-01-02T15:04:05Z07:00 | %Y-%m-%dT%H:%M:%S | RFC3339 |
2006-01-02T15:04:05.999999999Z07:00 | %Y-%m-%dT%H:%M:%S | RFC3339Nano |
1637843406 | %s | 自訂 |
1637843406123 | %s | 自訂(Log Service以秒級精度處理) |
附錄二:Golang時間格式
以下為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"
)