diff --git a/core/file_server/reader/LogFileReader.cpp b/core/file_server/reader/LogFileReader.cpp index e3ea1d5e3e..dc492622eb 100644 --- a/core/file_server/reader/LogFileReader.cpp +++ b/core/file_server/reader/LogFileReader.cpp @@ -2526,7 +2526,23 @@ PipelineEventGroup LogFileReader::GenerateEventGroup(LogFileReaderPtr reader, Lo if (AppConfig::GetInstance()->EnableLogTimeAutoAdjust()) { logtime += GetTimeDelta(); } - event->SetTimestamp(logtime); + // Check if nanosecond timestamp is enabled in global config + const GlobalConfig& globalConfig = reader->mReaderConfig.second->GetGlobalConfig(); + if (globalConfig.mEnableTimestampNanosecond) { + // Use nanosecond precision timestamp + uint64_t currentTimeNs = GetCurrentTimeInNanoSeconds(); + if (AppConfig::GetInstance()->EnableLogTimeAutoAdjust()) { + // When auto-adjusting, use the adjusted second timestamp with current nanosecond part + event->SetTimestamp(logtime, static_cast(currentTimeNs % kNanoPerSeconds)); + } else { + // When not auto-adjusting, use the full nanosecond timestamp + event->SetTimestamp(static_cast(currentTimeNs / kNanoPerSeconds), + static_cast(currentTimeNs % kNanoPerSeconds)); + } + } else { + // Use regular second timestamp + event->SetTimestamp(logtime); + } event->SetContentNoCopy(DEFAULT_CONTENT_KEY, logBuffer->rawBuffer); event->SetPosition(logBuffer->readOffset, logBuffer->readLength); diff --git a/pkg/protocol/converter/converter_single_log_flatten.go b/pkg/protocol/converter/converter_single_log_flatten.go index 9daf6000c5..3e6d0440d3 100644 --- a/pkg/protocol/converter/converter_single_log_flatten.go +++ b/pkg/protocol/converter/converter_single_log_flatten.go @@ -48,10 +48,22 @@ func (c *Converter) ConvertToSingleProtocolLogsFlatten(logGroup *protocol.LogGro } } - if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyTime]; ok { - customSingleLog[newKey] = log.Time + // Set timestamp with nanosecond precision if enabled + timestamp := log.Time + if c.GlobalConfig != nil && c.GlobalConfig.EnableTimestampNanosecond { + // Combine seconds and nanoseconds + timestampNs := uint64(timestamp) * 1000000000 + uint64(log.GetTimeNs()) + if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyTime]; ok { + customSingleLog[newKey] = timestampNs + } else { + customSingleLog[protocolKeyTime] = timestampNs + } } else { - customSingleLog[protocolKeyTime] = log.Time + if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyTime]; ok { + customSingleLog[newKey] = timestamp + } else { + customSingleLog[protocolKeyTime] = timestamp + } } convertedLogs[i] = customSingleLog diff --git a/pkg/protocol/converter/custom_single_log.go b/pkg/protocol/converter/custom_single_log.go index b20df66e0e..3f377f4b16 100644 --- a/pkg/protocol/converter/custom_single_log.go +++ b/pkg/protocol/converter/custom_single_log.go @@ -41,10 +41,22 @@ func (c *Converter) ConvertToSingleProtocolLogs(logGroup *protocol.LogGroup, tar desiredValues[i] = desiredValue customSingleLog := make(map[string]interface{}, numProtocolKeys) - if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyTime]; ok { - customSingleLog[newKey] = log.Time + // Set timestamp with nanosecond precision if enabled + timestamp := log.Time + if c.GlobalConfig != nil && c.GlobalConfig.EnableTimestampNanosecond { + // Combine seconds and nanoseconds + timestampNs := uint64(timestamp) * 1000000000 + uint64(log.GetTimeNs()) + if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyTime]; ok { + customSingleLog[newKey] = timestampNs + } else { + customSingleLog[protocolKeyTime] = timestampNs + } } else { - customSingleLog[protocolKeyTime] = log.Time + if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyTime]; ok { + customSingleLog[newKey] = timestamp + } else { + customSingleLog[protocolKeyTime] = timestamp + } } if newKey, ok := c.ProtocolKeyRenameMap[protocolKeyContent]; ok { customSingleLog[newKey] = contents