全部產品
Search
文件中心

Simple Log Service:日誌採集支援納秒精度時間戳記

更新時間:Nov 06, 2025

通過在 Logtail 採集配置中開啟納秒精度支援並配置時間解析外掛程式,可以採集和儲存毫秒、微秒、納秒級的高精度時間戳記。採集後的時間將拆分為秒級時間戳記 __time__ 和納秒位移量 __time_ns_part__ 兩個欄位進行儲存,以實現高精度的日誌排序與分析。

業務情境說明

在分布式追蹤、高頻交易、效能剖析或對日誌嚴格保序等情境中,秒級的時間精度無法滿足業務需求。這些情境的業務日誌中通常會記錄毫秒、微秒甚至納秒級的時間戳記。本方案旨在指導如何配置 Logtail,以完整地採集、儲存和分析這些高精度時間資訊,確保日誌分析的準確性和時序性。

方案架構

LoongCollector(Logtail)採集納秒精度時間戳記的核心機制是在標準秒級時間戳記之外,額外儲存一個納秒級的位移量。此設計旨在相容現有以秒為單位的時間系統,同時提供高精度排序能力。

核心工作流程如下:

  1. 開啟納秒支援:在 Logtail 採集配置的進階參數中,通過 { "EnableTimestampNanosecond": true } 啟用高精度時間處理能力。此功能僅適用於 Logtail 1.8.0 及以上版本的 Linux 環境。

  2. 日誌解析:使用分隔字元、JSON 或Regex等外掛程式從原始日誌中提取包含高精度時間戳記的字串。

  3. 時間轉換:時間解析外掛程式將時間字串轉換為標準時間格式。

  4. 時間儲存:Log Service將時間拆分為兩個欄位進行儲存:

    • __time__:標準的 Unix 時間戳記(長整型),單位為秒。

    • __time_ns_part__:納秒部分(長整型),取值範圍為 0 到 999,999,999。

  5. 查詢與分析:在查詢分析時,通過對 __time____time_ns_part__ 兩個欄位組合排序,可以實現嚴格的日誌時序分析。

實施步驟

本節將以一個包含納秒級時間戳記的JSON 日誌為例,提供一個從日誌採集、解析、索引配置到最終查詢分析的完整端到端操作流程。

步驟一:建立Project和Logstore

採集日誌前,需規劃並建立用於管理與儲存日誌的Project和Logstore。

  • Project:Log Service的資源嵌入式管理單元,用於隔離和管理不同專案或業務的日誌。

  • Logstore:日誌儲存單元,用於儲存日誌。

如果已提前建立,可跳過本步驟,直接進入配置機器組(安裝LoongCollector)

  1. 登入Log Service控制台

  2. 單擊建立Project,並配置:

    • 所屬地區:根據日誌來源選擇,建立後不可修改。

    • Project名稱:阿里雲內全域唯一,建立後不可修改。

    • 其他配置保持預設,單擊建立。如需瞭解其他參數,請參見管理Project

  3. 單擊Project名稱,進入目標Project。

  4. 在左側導覽列,選擇image日誌儲存,單擊+

  5. 在建立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)image頁面:

  1. 單擊目標Logstore名稱前的image展開,

  2. 單擊資料接入後的image

  3. 在彈框中選擇文本日誌接入模板,本文以單行-文本日誌模板為例,單擊立即接入

所有文本日誌接入模板僅在解析外掛程式上有所差異,其餘配置流程一致,後續均可修改。

image

配置步驟:

  1. 機器組配置頁面,配置如下參數:

    • 使用情境主機情境

    • 安裝環境ECS

  2. 配置機器組:根據目標伺服器的LoongCollector安裝情況與機器組配置狀態,選擇對應操作:

    • 已安裝LoongCollector且已加入某個機器組,可直接在源機器組列表中勾選,將其添加至應用機器組列表,無需重複建立。

    • 未安裝LoongCollector,單擊建立機器組

      以下步驟將引導您完成LoongCollector的自動安裝並建立新機器組。
      1. 系統會自動列出與 Project 同地區的 ECS 執行個體,勾選需要採集日誌的一台或多台執行個體。

      2. 單擊安裝並建立為機器組,系統將自動在所選ECS執行個體上安裝LoongCollector。

      3. 配置機器組名稱並單擊確定

      說明

      如果安裝失敗或一直處於等待中,請檢查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解析外掛程式,從原始日誌中分離出包含納秒時間戳記的字串,並將其存為一個獨立的欄位。

  1. 添加日誌範例

    假設記錄檔中的日誌格式如下,其中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"
    }
  2. 添加JSON解析外掛程式

    單擊添加處理外掛程式,選擇原生處理外掛程式 > JSON解析,單擊確認

  3. 添加時間解析外掛程式

    將上一步提取的時間字串(asctime欄位)轉換為標準的納秒時間戳記,並將其作為該條日誌的事件時間。

    外掛程式名稱

    核心功能

    適用情境

    時間解析

    基礎時間解析

    簡單情境,格式固定。

    提取日誌時間 (strptime時間格式)

    靈活,支援豐富的 strptime 格式

    推薦使用。功能全面,與業界標準相容。

    提取日誌時間 (Go語言時間格式)

    使用 Go 語言標準庫格式

    熟悉 Go 語言或日誌格式與 Go 標準庫匹配的情境。

    時間解析

    單擊添加處理外掛程式,選擇原生處理外掛程式 > 時間解析,進行如下配置:

    • 原始欄位:解析日誌前,用於存放時間的原始欄位,本樣本為asctime

    • 時間格式:根據日誌的時間欄位內容設定對應的時間格式,本樣本為%Y-%m-%d %H:%M:%S,%f。其中%f為秒的小數部分,精度最高支援為納秒。

      時間格式字串必須與原始日誌中的時間格式(包括秒和納秒之間的分隔字元,如 ,.)完全一致,否則無法正確解析。
    • 時區:選擇日誌時間欄位所在的時區,預設使用機器時區。

    提取日誌時間(strptime時間格式)

    單擊添加處理外掛程式,選擇拓展處理外掛程式 > 提取日誌時間(strptime時間格式),進行如下配置:

    • 原始欄位:解析日誌前,用於存放時間的原始欄位,本樣本為asctime

    • 原始時間格式:根據日誌的時間欄位內容設定對應的時間格式,本樣本為%Y-%m-%d %H:%M:%S,%f。其中%f為秒的小數部分,精度最高支援為納秒。

      時間格式字串必須與原始日誌中的時間格式(包括秒和納秒之間的分隔字元,如 ,.)完全一致,否則無法正確解析。

    提取日誌時間(Go語言時間格式)

    單擊添加處理外掛程式,選擇拓展處理外掛程式 > 提取日誌時間(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配置後,單擊下一步。進入查詢分析配置頁面:

  • 系統預設開啟全文索引,支援對日誌原始內容進行關鍵詞搜尋。

  • 如需按欄位進行精確查詢,請在頁面載入出預覽資料後,單擊自動產生索引,Log Service將根據預覽資料中的第一條內容產生欄位索引

配置完成後,單擊下一步,完成整個採集流程的設定。

通過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的查詢分析頁面,查看採集日誌,控制台會根據高精度的時間資訊,自動進行顯示最佳化,顯示成毫秒、微秒、納秒的形式。

image

常見問題

採集日誌無法正常解析納秒時間戳記

配置採集後,發現高精度時間並未正常提取。

image

  • 錯誤原因

    外掛程式模式支援%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"
)