diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 23bce4b247..86f868f6f5 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -35,6 +35,7 @@ All notable changes to experimental packages in this project will be documented * feat(exporter-logs-otlp-grpc): otlp-grpc exporter for logs. [#3712](https://github.com/open-telemetry/opentelemetry-js/pull/3712/) @llc1123 * feat(otlp-grpc-exporter-base): use statically generated protobuf code [#3705](https://github.com/open-telemetry/opentelemetry-js/pull/3705) @pichlermarc * refactor(otlp-transformer): refine metric transformers. [#3770](https://github.com/open-telemetry/opentelemetry-js/pull/3770/) @llc1123 +* feat(api-logs): add `ObservedTimestamp` to `LogRecord`. [#3787](https://github.com/open-telemetry/opentelemetry-js/pull/3787/) @llc1123 ### :bug: (Bug Fix) diff --git a/experimental/packages/api-logs/src/types/LogRecord.ts b/experimental/packages/api-logs/src/types/LogRecord.ts index a2c7d25ad3..e1c1100c5f 100644 --- a/experimental/packages/api-logs/src/types/LogRecord.ts +++ b/experimental/packages/api-logs/src/types/LogRecord.ts @@ -50,6 +50,11 @@ export interface LogRecord { */ timestamp?: number; + /** + * Time when the event was observed by the collection system. + */ + observedTimestamp?: number; + /** * Numerical value of the severity. */ diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts b/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts index b57b2682bd..1dfd82675a 100644 --- a/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts +++ b/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts @@ -45,6 +45,7 @@ export const mockedReadableLogRecord: ReadableLogRecord = { schemaUrl: 'http://url.to.schema', }, hrTime: [1680253513, 123241635] as HrTime, + hrTimeObserved: [1683526948, 965142784] as HrTime, attributes: { 'some-attribute': 'some attribute value', }, @@ -92,7 +93,7 @@ export function ensureExportedLogRecordIsCorrect(logRecord: ILogRecord) { ); assert.strictEqual( logRecord.observedTimeUnixNano, - '1680253513123241728', + '1683526948965142784', 'observedTimeUnixNano is wrong' ); assert.strictEqual( diff --git a/experimental/packages/otlp-transformer/src/logs/index.ts b/experimental/packages/otlp-transformer/src/logs/index.ts index 4fd114fa69..6fa4d11e86 100644 --- a/experimental/packages/otlp-transformer/src/logs/index.ts +++ b/experimental/packages/otlp-transformer/src/logs/index.ts @@ -93,7 +93,7 @@ function logRecordsToResourceLogs( function toLogRecord(log: ReadableLogRecord, useHex?: boolean): ILogRecord { return { timeUnixNano: hrTimeToNanoseconds(log.hrTime), - observedTimeUnixNano: hrTimeToNanoseconds(log.hrTime), + observedTimeUnixNano: hrTimeToNanoseconds(log.hrTimeObserved), severityNumber: toSeverityNumber(log.severityNumber), severityText: log.severityText, body: toAnyValue(log.body), diff --git a/experimental/packages/otlp-transformer/test/logs.test.ts b/experimental/packages/otlp-transformer/test/logs.test.ts index c184134ce4..ef0a4cf9d7 100644 --- a/experimental/packages/otlp-transformer/test/logs.test.ts +++ b/experimental/packages/otlp-transformer/test/logs.test.ts @@ -52,7 +52,7 @@ function createExpectedLogJson(useHex: boolean): IExportLogsServiceRequest { // eslint-disable-next-line @typescript-eslint/no-loss-of-precision timeUnixNano: 1680253513123241635, // eslint-disable-next-line @typescript-eslint/no-loss-of-precision - observedTimeUnixNano: 1680253513123241635, + observedTimeUnixNano: 1683526948965142784, severityNumber: ESeverityNumber.SEVERITY_NUMBER_ERROR, severityText: 'error', body: { stringValue: 'some_log_body' }, @@ -105,6 +105,7 @@ describe('Logs', () => { }; const log_fragment_1 = { hrTime: [1680253513, 123241635] as HrTime, + hrTimeObserved: [1683526948, 965142784] as HrTime, attributes: { 'some-attribute': 'some attribute value', }, @@ -119,6 +120,7 @@ describe('Logs', () => { }; const log_fragment_2 = { hrTime: [1680253797, 687038506] as HrTime, + hrTimeObserved: [1680253797, 687038506] as HrTime, attributes: { 'another-attribute': 'another attribute value', }, diff --git a/experimental/packages/sdk-logs/src/LogRecord.ts b/experimental/packages/sdk-logs/src/LogRecord.ts index a4601af6fc..9d3e909feb 100644 --- a/experimental/packages/sdk-logs/src/LogRecord.ts +++ b/experimental/packages/sdk-logs/src/LogRecord.ts @@ -30,6 +30,7 @@ import { Logger } from './Logger'; export class LogRecord implements ReadableLogRecord { readonly hrTime: api.HrTime; + readonly hrTimeObserved: api.HrTime; readonly spanContext?: api.SpanContext; readonly resource: IResource; readonly instrumentationScope: InstrumentationScope; @@ -73,7 +74,8 @@ export class LogRecord implements ReadableLogRecord { constructor(logger: Logger, logRecord: logsAPI.LogRecord) { const { - timestamp = Date.now(), + timestamp, + observedTimestamp, severityNumber, severityText, body, @@ -81,7 +83,10 @@ export class LogRecord implements ReadableLogRecord { context, } = logRecord; - this.hrTime = timeInputToHrTime(timestamp); + const now = Date.now(); + this.hrTime = timeInputToHrTime(timestamp ?? now); + this.hrTimeObserved = timeInputToHrTime(observedTimestamp ?? now); + if (context) { const spanContext = api.trace.getSpanContext(context); if (spanContext && api.isSpanContextValid(spanContext)) { diff --git a/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts b/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts index e02d53dae9..72fe7d1d35 100644 --- a/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts +++ b/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts @@ -21,6 +21,7 @@ import type { SeverityNumber } from '@opentelemetry/api-logs'; export interface ReadableLogRecord { readonly hrTime: HrTime; + readonly hrTimeObserved: HrTime; readonly spanContext?: SpanContext; readonly severityText?: string; readonly severityNumber?: SeverityNumber;