Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions src/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
const EventId = require('eventid');
import * as extend from 'extend';
import {google} from '../protos/protos';
import {objToStruct, structToObj, zuluToDateObj} from './utils/common';
import {
objToStruct,
structToObj,
zuluToDateObj,
toNanosAndSecondsObj,
} from './utils/common';
import {
makeHttpRequestData,
CloudLoggingHttpRequest,
Expand Down Expand Up @@ -75,7 +80,9 @@ export interface StructuredJson {
// Universally supported properties
message?: string | object;
httpRequest?: object;
timestamp?: string;
// Based on https://cloud.google.com/logging/docs/agent/logging/configuration#timestamp-processing, the
// timestamp should be in nanos and seconds format.
timestamp?: Timestamp;
[INSERT_ID_KEY]?: string;
[OPERATION_KEY]?: object;
[SOURCE_LOCATION_KEY]?: object;
Expand Down Expand Up @@ -214,12 +221,7 @@ class Entry {
}
// Format log timestamp
if (entry.timestamp instanceof Date) {
const seconds = entry.timestamp.getTime() / 1000;
const secondsRounded = Math.floor(seconds);
entry.timestamp = {
seconds: secondsRounded,
nanos: Math.floor((seconds - secondsRounded) * 1e9),
};
entry.timestamp = toNanosAndSecondsObj(entry.timestamp);
} else if (typeof entry.timestamp === 'string') {
entry.timestamp = zuluToDateObj(entry.timestamp);
}
Expand Down Expand Up @@ -300,7 +302,7 @@ class Entry {
}
// Format timestamp
if (meta.timestamp instanceof Date) {
entry.timestamp = meta.timestamp.toISOString();
entry.timestamp = toNanosAndSecondsObj(meta.timestamp);
}
// Format httprequest
const req = meta.httpRequest;
Expand Down
14 changes: 14 additions & 0 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,17 @@ export function zuluToDateObj(zuluTime: string) {
nanos: nanoSecs ? Number(nanoSecs.padEnd(9, '0')) : 0,
};
}

/**
* Converts Date to nanoseconds format suported by Logging.
* See https://cloud.google.com/logging/docs/agent/logging/configuration#timestamp-processing for more details
* @param date The date to be converted to Logging nanos and seconds format
*/
export function toNanosAndSecondsObj(date: Date) {
const seconds = date.getTime() / 1000;
const secondsRounded = Math.floor(seconds);
return {
seconds: secondsRounded,
nanos: Math.floor((seconds - secondsRounded) * 1e9),
};
}
32 changes: 13 additions & 19 deletions src/utils/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import arrify = require('arrify');
import path = require('path');
import {google} from '../../protos/protos';
import {Entry} from '../entry';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -95,25 +94,20 @@ export function createDiagnosticEntry(
if (!libraryName || !libraryName.startsWith(NODEJS_LIBRARY_NAME_PREFIX)) {
libraryName = NODEJS_LIBRARY_NAME_PREFIX;
}
const entry = new Entry(
{
severity: google.logging.type.LogSeverity.INFO,
const entry = new Entry(undefined, {
[DIAGNOSTIC_INFO_KEY]: {
[INSTRUMENTATION_SOURCE_KEY]: [
{
// Truncate libraryName and libraryVersion if more than 14 characters length
name: truncateValue(libraryName, maxDiagnosticValueLen),
version: truncateValue(
libraryVersion ?? getNodejsLibraryVersion(),
maxDiagnosticValueLen
),
},
],
},
{
[DIAGNOSTIC_INFO_KEY]: {
[INSTRUMENTATION_SOURCE_KEY]: [
{
// Truncate libraryName and libraryVersion if more than 14 characters length
name: truncateValue(libraryName, maxDiagnosticValueLen),
version: truncateValue(
libraryVersion ?? getNodejsLibraryVersion(),
maxDiagnosticValueLen
),
},
],
},
}
);
});
return entry;
}

Expand Down
16 changes: 14 additions & 2 deletions test/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ function withinExpectedTimeBoundaries(result?: Date): boolean {
return false;
}

function nanosAndSecondsToDate(timestamp: entryTypes.Timestamp) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const seconds = (timestamp as any).seconds;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const nanos = (timestamp as any).nanos;
return new Date(seconds * 1000 + nanos / 1e9);
}

describe('Entry', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let Entry: typeof entryTypes.Entry;
Expand Down Expand Up @@ -319,7 +327,9 @@ describe('Entry', () => {
entry.metadata.traceSampled = false;
entry.data = 'this is a log';
const json = entry.toStructuredJSON();
assert(withinExpectedTimeBoundaries(new Date(json.timestamp!)));
assert(
withinExpectedTimeBoundaries(nanosAndSecondsToDate(json.timestamp!))
);
delete json.timestamp;
const expectedJSON = {
[entryTypes.INSERT_ID_KEY]: '👀',
Expand All @@ -345,7 +355,9 @@ describe('Entry', () => {
it('should convert a string timestamp', () => {
entry.metadata.timestamp = new Date();
const json = entry.toStructuredJSON();
assert(withinExpectedTimeBoundaries(new Date(json.timestamp!)));
assert(
withinExpectedTimeBoundaries(nanosAndSecondsToDate(json.timestamp!))
);
});

it('should convert a raw http to httprequest', () => {
Expand Down