From 809b940fc5f51361ec02eda166040cc19b8a887d Mon Sep 17 00:00:00 2001 From: cindy-peng Date: Mon, 15 Apr 2024 11:54:14 -0700 Subject: [PATCH] Fix lint errors --- src/entry.ts | 6 +- src/utils/context.ts | 30 ++- system-test/logging.ts | 282 +++++++++++---------- test/entry.ts | 228 ++++++++++------- test/utils/context.ts | 538 ++++++++++++++++++++++------------------- 5 files changed, 594 insertions(+), 490 deletions(-) diff --git a/src/entry.ts b/src/entry.ts index 089c93db..6916bd6d 100644 --- a/src/entry.ts +++ b/src/entry.ts @@ -30,7 +30,11 @@ import { RawHttpRequest, isRawHttpRequest, } from './utils/http-request'; -import {CloudTraceContext, getContextFromOtelContext, getOrInjectContext} from './utils/context'; +import { + CloudTraceContext, + getContextFromOtelContext, + getOrInjectContext, +} from './utils/context'; const eventId = new EventId(); diff --git a/src/utils/context.ts b/src/utils/context.ts index 08cce712..24c13995 100644 --- a/src/utils/context.ts +++ b/src/utils/context.ts @@ -30,8 +30,7 @@ import * as http from 'http'; import * as uuid from 'uuid'; import * as crypto from 'crypto'; -import { trace, context, isSpanContextValid} from '@opentelemetry/api'; - +import { trace, isSpanContextValid } from '@opentelemetry/api'; /** Header that carries span context across Google infrastructure. */ export const X_CLOUD_TRACE_HEADER = 'x-cloud-trace-context'; @@ -99,7 +98,6 @@ export function getOrInjectContext( projectId: string, inject?: boolean ): CloudTraceContext { - const defaultContext = toCloudTraceContext({}, projectId); // Get trace context from OpenTelemetry span context. @@ -107,7 +105,7 @@ export function getOrInjectContext( if (otelContext) return otelContext; const wrapper = makeHeaderWrapper(req); - + if (wrapper) { // Detect 'traceparent' header. const traceContext = getContextFromTraceParent(wrapper, projectId); @@ -161,24 +159,24 @@ function makeCloudTraceHeader(): string { /** * getContextFromOtelContext looks for the active open telemetry span context * per Open Telemetry specifications for tracing contexts. - * + * * @param projectId */ export function getContextFromOtelContext( projectId: string ): CloudTraceContext | null { - const spanContext = trace.getActiveSpan()?.spanContext(); - if (spanContext != undefined && isSpanContextValid(spanContext)) { - const otelSpanContext = { - // trace: "projects/cindy-cloud-sdk-test/traces/"+spanContext?.traceId, - trace: spanContext?.traceId, - spanId: spanContext?.spanId, - traceSampled: spanContext?.traceFlags === 1, - }; + const spanContext = trace.getActiveSpan()?.spanContext(); + if (spanContext !== undefined && isSpanContextValid(spanContext)) { + const otelSpanContext = { + // trace: "projects/cindy-cloud-sdk-test/traces/"+spanContext?.traceId, + trace: spanContext?.traceId, + spanId: spanContext?.spanId, + traceSampled: spanContext?.traceFlags === 1, + }; - const return_context = toCloudTraceContext(otelSpanContext, projectId); - return return_context; - } + const return_context = toCloudTraceContext(otelSpanContext, projectId); + return return_context; + } return null; } diff --git a/system-test/logging.ts b/system-test/logging.ts index 9369ce9a..6f00cb4e 100644 --- a/system-test/logging.ts +++ b/system-test/logging.ts @@ -14,33 +14,38 @@ * limitations under the License. */ -import { BigQuery } from '@google-cloud/bigquery'; -import { PubSub } from '@google-cloud/pubsub'; -import { Storage } from '@google-cloud/storage'; +import {BigQuery} from '@google-cloud/bigquery'; +import {PubSub} from '@google-cloud/pubsub'; +import {Storage} from '@google-cloud/storage'; import * as assert from 'assert'; -import { describe, it } from 'mocha'; -import { HOST_ADDRESS } from 'gcp-metadata'; +import {describe, it} from 'mocha'; +import {HOST_ADDRESS} from 'gcp-metadata'; import * as nock from 'nock'; -import { Duplex } from 'stream'; -import { v4 } from 'uuid'; -import { after, before } from 'mocha'; +import {Duplex} from 'stream'; +import {v4} from 'uuid'; +import {after, before} from 'mocha'; // eslint-disable-next-line @typescript-eslint/no-var-requires const http2spy = require('http2spy'); -import { Logging, Sink, Log, Entry, TailEntriesResponse } from '../src'; +import {Logging, Sink, Log, Entry, TailEntriesResponse} from '../src'; import * as http from 'http'; import * as instrumentation from '../src/utils/instrumentation'; -import { trace } from '@opentelemetry/api'; -const { Resource } = require('@opentelemetry/resources'); -const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); -const { - TraceExporter, -} = require("@google-cloud/opentelemetry-cloud-trace-exporter"); -import { NodeSDK } from '@opentelemetry/sdk-node'; +import {trace} from '@opentelemetry/api'; +import {Resource} from '@opentelemetry/resources'; +//const {Resource} = require('@opentelemetry/resources'); +import {SEMRESATTRS_SERVICE_NAME} from '@opentelemetry/semantic-conventions'; +import {TraceExporter} from '@google-cloud/opentelemetry-cloud-trace-exporter'; +import {NodeSDK} from '@opentelemetry/sdk-node'; +// const { +// SemanticResourceAttributes, +// } = require('@opentelemetry/semantic-conventions'); +// const { +// TraceExporter, +// } = require('@google-cloud/opentelemetry-cloud-trace-exporter'); // block all attempts to chat with the metadata server (kokoro runs on GCE) nock(HOST_ADDRESS) .get(() => true) - .replyWithError({ code: 'ENOTFOUND' }) + .replyWithError({code: 'ENOTFOUND'}) .persist(); describe('Logging', () => { @@ -91,7 +96,7 @@ describe('Logging', () => { // Only delete log buckets that are at least 2 days old // Fixes: https://github.com/googleapis/nodejs-logging/issues/953 async function deleteBuckets() { - const [buckets] = await storage.getBuckets({ prefix: TESTS_PREFIX }); + const [buckets] = await storage.getBuckets({prefix: TESTS_PREFIX}); const bucketsToDelete = buckets.filter((bucket: any) => { if (bucket.metadata.timeCreated) { return new Date(bucket.metadata.timeCreated) < twoDaysAgo; @@ -155,7 +160,7 @@ describe('Logging', () => { it('should create a sink with a Dataset destination', async () => { const sink = logging.sink(generateName()); // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [_, apiResponse] = await sink.create({ destination: dataset }); + const [_, apiResponse] = await sink.create({destination: dataset}); const destination = `bigquery.googleapis.com/datasets/${dataset.id}`; @@ -171,7 +176,7 @@ describe('Logging', () => { it('should create a sink with a Topic destination', async () => { const sink = logging.sink(generateName()); // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [_, apiResponse] = await sink.create({ destination: topic }); + const [_, apiResponse] = await sink.create({destination: topic}); const destination = 'pubsub.googleapis.com/' + topic.name; // The projectId may have been replaced depending on how the system @@ -187,11 +192,11 @@ describe('Logging', () => { const FILTER = 'severity = ALERT'; before(async () => { - await sink.create({ destination: topic }); + await sink.create({destination: topic}); }); it('should set metadata', async () => { - const metadata = { filter: FILTER }; + const metadata = {filter: FILTER}; const [apiResponse] = await sink.setMetadata(metadata); assert.strictEqual(apiResponse.filter, FILTER); }); @@ -243,7 +248,7 @@ describe('Logging', () => { const sink = logging.sink(generateName()); before(async () => { - await sink.create({ destination: topic }); + await sink.create({destination: topic}); }); it('should list sinks', async () => { @@ -253,7 +258,7 @@ describe('Logging', () => { it('should list sinks as a stream', done => { const logstream: Duplex = logging - .getSinksStream({ pageSize: 1 }) + .getSinksStream({pageSize: 1}) .on('error', done) .once('data', () => { logstream.end(); @@ -263,7 +268,7 @@ describe('Logging', () => { it('should get metadata', done => { logging - .getSinksStream({ pageSize: 1 }) + .getSinksStream({pageSize: 1}) .on('error', done) .once('data', (sink: Sink) => { sink.getMetadata((err, metadata) => { @@ -285,7 +290,7 @@ describe('Logging', () => { log.entry('log entry 1'), // object data - log.entry({ delegate: 'my_username' }), + log.entry({delegate: 'my_username'}), // various data types log.entry({ @@ -302,12 +307,12 @@ describe('Logging', () => { }), ]; - return { log, logEntries }; + return {log, logEntries}; } function getEntriesFromLog( log: Log, - config: { numExpectedMessages: number }, + config: {numExpectedMessages: number}, callback: (err: Error | null, entries?: Entry[]) => void ) { let numAttempts = 0; @@ -323,7 +328,7 @@ describe('Logging', () => { time.setHours(time.getHours() - 1); log.getEntries( - { autoPaginate: false, filter: `timestamp > "${time.toISOString()}"` }, + {autoPaginate: false, filter: `timestamp > "${time.toISOString()}"`}, (err, entries) => { if (err) { callback(err); @@ -353,7 +358,7 @@ describe('Logging', () => { describe('listing logs', () => { before(async () => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); await log.write(logEntries, options); }); @@ -364,7 +369,7 @@ describe('Logging', () => { it('should list logs as a stream', done => { const stream: Duplex = logging - .getLogsStream({ pageSize: 1 }) + .getLogsStream({pageSize: 1}) .on('error', done) .once('data', () => { stream.end(); @@ -374,14 +379,14 @@ describe('Logging', () => { }); it('should list log entries', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.write(logEntries, options, err => { assert.ifError(err); getEntriesFromLog( log, - { numExpectedMessages: logEntries.length }, + {numExpectedMessages: logEntries.length}, (err, entries) => { assert.ifError(err); // Instrumentation log entry is added automatically, so we should discount it @@ -391,7 +396,7 @@ describe('Logging', () => { if ( ent && ent.data?.[instrumentation.DIAGNOSTIC_INFO_KEY]?.[ - instrumentation.INSTRUMENTATION_SOURCE_KEY + instrumentation.INSTRUMENTATION_SOURCE_KEY ] ) { entry = ent; @@ -400,7 +405,7 @@ describe('Logging', () => { assert.ok(entry); assert.equal( entry.data?.[instrumentation.DIAGNOSTIC_INFO_KEY]?.[ - instrumentation.INSTRUMENTATION_SOURCE_KEY + instrumentation.INSTRUMENTATION_SOURCE_KEY ]?.[0]?.['name'], instrumentation.NODEJS_LIBRARY_NAME_PREFIX ); @@ -411,7 +416,7 @@ describe('Logging', () => { }); it('should list log entries as a stream', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.write(logEntries, options, err => { assert.ifError(err); @@ -428,7 +433,7 @@ describe('Logging', () => { }); it('should tail log entries as a stream', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); const logInterval = setInterval(() => { log.write(logEntries, options, err => { @@ -458,7 +463,7 @@ describe('Logging', () => { let logEntriesExpected: Entry[]; before(done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); logExpected = log; logEntriesExpected = logEntries; log.write(logEntries, options, done); @@ -467,7 +472,7 @@ describe('Logging', () => { it('should list log entries', done => { getEntriesFromLog( logExpected, - { numExpectedMessages: logEntriesExpected.length }, + {numExpectedMessages: logEntriesExpected.length}, (err, entries) => { assert.ifError(err); assert.strictEqual(entries!.length, logEntriesExpected.length); @@ -508,30 +513,30 @@ describe('Logging', () => { }); it('should write a single entry to a log', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.write(logEntries[0], options, done); }); it('should write a single entry to a log as a Promise', async () => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); await log.write(logEntries[1], options); }); it('should write multiple entries to a log', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.write(logEntries, options, err => { assert.ifError(err); getEntriesFromLog( log, - { numExpectedMessages: logEntries.length }, + {numExpectedMessages: logEntries.length}, (err, entries) => { assert.ifError(err); assert.deepStrictEqual(entries!.map(x => x.data).reverse(), [ 'log entry 1', - { delegate: 'my_username' }, + {delegate: 'my_username'}, { nonValue: null, boolValue: true, @@ -551,19 +556,19 @@ describe('Logging', () => { }); it('should preserve order of entries', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const entry1 = log.entry('1'); setTimeout(() => { const entry2 = log.entry('2'); - const entry3 = log.entry({ timestamp: entry2.metadata.timestamp }, '3'); + const entry3 = log.entry({timestamp: entry2.metadata.timestamp}, '3'); // Re-arrange to confirm the timestamp is sent and honored. log.write([entry2, entry3, entry1], options, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 3 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 3}, (err, entries) => { assert.ifError(err); assert.deepStrictEqual( entries!.map(x => x.data), @@ -576,7 +581,7 @@ describe('Logging', () => { }); it('should preserve order for sequential write calls', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const messages = ['1', '2', '3', '4', '5']; (async () => { @@ -586,7 +591,7 @@ describe('Logging', () => { getEntriesFromLog( log, - { numExpectedMessages: messages.length }, + {numExpectedMessages: messages.length}, (err, entries) => { assert.ifError(err); assert.deepStrictEqual( @@ -600,7 +605,7 @@ describe('Logging', () => { }); it('should write an entry with primitive values', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const logEntry = log.entry({ when: new Date(), @@ -612,7 +617,7 @@ describe('Logging', () => { log.write(logEntry, options, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; @@ -629,7 +634,7 @@ describe('Logging', () => { }); it('should write a log with metadata', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const metadata = Object.assign({}, options, { severity: 'DEBUG', @@ -644,7 +649,7 @@ describe('Logging', () => { log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; @@ -656,15 +661,15 @@ describe('Logging', () => { }); it('should write a structured httpRequest log with no message', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const metadata = { - httpRequest: { status: 200 }, + httpRequest: {status: 200}, }; const logEntry = log.entry(metadata); log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; assert.strictEqual( @@ -678,7 +683,7 @@ describe('Logging', () => { }); it('should write a request log with x-cloud-trace-context header', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const URL = 'http://www.google.com'; // Use the response of a http request as the incomingmessage request obj. http.get(URL, res => { @@ -686,11 +691,11 @@ describe('Logging', () => { res.headers = { 'x-cloud-trace-context': '1/2;o=1', }; - const metadata = { httpRequest: res }; + const metadata = {httpRequest: res}; const logEntry = log.entry(metadata, 'some log message'); log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; assert.strictEqual(entry.data, 'some log message'); @@ -709,7 +714,7 @@ describe('Logging', () => { }); it('should write a http request log with traceparent header', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const URL = 'http://www.google.com'; // Use the response of a http request as the incomingmessage request obj. http.get(URL, res => { @@ -718,11 +723,11 @@ describe('Logging', () => { traceparent: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01', }; - const metadata = { httpRequest: res }; + const metadata = {httpRequest: res}; const logEntry = log.entry(metadata, 'some log message'); log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; assert.strictEqual(entry.data, 'some log message'); @@ -747,40 +752,40 @@ describe('Logging', () => { // this enables the API to record telemetry sdk = new NodeSDK({ resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: TESTS_PREFIX, + [SEMRESATTRS_SERVICE_NAME]: TESTS_PREFIX, }), // Add cloud trace exporter as SDK trace exporter traceExporter: new TraceExporter(), }); sdk.start(); - }) + }); after(() => { sdk.shutdown(); - }) + }); it('should not overwrite user defined trace and spans with OpenTelemetry context', done => { - trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', (span) => { - const { log } = getTestLog(); - const spanTestMessage = "span test log message"; + trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', span => { + const {log} = getTestLog(); + const spanTestMessage = 'span test log message'; const metadata = { - trace: "1", - spanId: "1", - traceSampled: false + trace: '1', + spanId: '1', + traceSampled: false, }; const logEntry = log.entry(metadata, spanTestMessage); log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; assert.strictEqual(entry.data, spanTestMessage); + assert.strictEqual(entry.metadata.trace, metadata.trace); + assert.strictEqual(entry.metadata.spanId, metadata.spanId); assert.strictEqual( - entry.metadata.trace, - metadata.trace + entry.metadata.traceSampled, + metadata.traceSampled ); - assert.strictEqual(entry.metadata.spanId, metadata.spanId); - assert.strictEqual(entry.metadata.traceSampled, metadata.traceSampled); }); }); span.end(); @@ -789,16 +794,16 @@ describe('Logging', () => { }); it('should write a log with trace and spans from OpenTelemetry context', done => { - trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', (span) => { + trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', span => { const traceId = span.spanContext().traceId; const spanId = span.spanContext().spanId; const traceSampled = (span.spanContext().traceFlags & 1) !== 0; - const { log } = getTestLog(); - const spanTestMessage = "span test log message"; + const {log} = getTestLog(); + const spanTestMessage = 'span test log message'; const logEntry = log.entry(spanTestMessage); log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; assert.strictEqual(entry.data, spanTestMessage); @@ -816,9 +821,9 @@ describe('Logging', () => { }); it('should write a log with OpenTelemetry trace and spans and ignore http requests traceparent header', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const URL = 'http://www.google.com'; - trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', (span) => { + trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', span => { // Use the response of a http request as the incomingmessage request obj. http.get(URL, res => { res.url = URL; @@ -826,7 +831,7 @@ describe('Logging', () => { traceparent: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01', }; - const metadata = { httpRequest: res }; + const metadata = {httpRequest: res}; const logEntry = log.entry(metadata, 'some log message'); const traceId = span.spanContext().traceId; @@ -835,70 +840,89 @@ describe('Logging', () => { log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { - assert.ifError(err); - const entry = entries![0]; - assert.strictEqual(entry.data, 'some log message'); - assert.strictEqual(entry.metadata.httpRequest?.requestUrl, URL); - assert.strictEqual(entry.metadata.httpRequest?.protocol, 'http:'); - assert.strictEqual( - entry.metadata.trace, - `projects/${PROJECT_ID}/traces/${traceId}` - ); - assert.strictEqual(entry.metadata.spanId, spanId); - assert.strictEqual(entry.metadata.traceSampled, traceSampled); - done(); - }); + getEntriesFromLog( + log, + {numExpectedMessages: 1}, + (err, entries) => { + assert.ifError(err); + const entry = entries![0]; + assert.strictEqual(entry.data, 'some log message'); + assert.strictEqual( + entry.metadata.httpRequest?.requestUrl, + URL + ); + assert.strictEqual( + entry.metadata.httpRequest?.protocol, + 'http:' + ); + assert.strictEqual( + entry.metadata.trace, + `projects/${PROJECT_ID}/traces/${traceId}` + ); + assert.strictEqual(entry.metadata.spanId, spanId); + assert.strictEqual(entry.metadata.traceSampled, traceSampled); + done(); + } + ); }); }); }); }); it('should write a log with OpenTelemetry trace and spans and ignore http requests x-cloud-trace-context header', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const URL = 'http://www.google.com'; - trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', (span) => { + trace.getTracer(TESTS_PREFIX).startActiveSpan('foo', span => { // Use the response of a http request as the incomingmessage request obj. http.get(URL, res => { res.url = URL; res.headers = { 'x-cloud-trace-context': '1/2;o=1', }; - const metadata = { httpRequest: res }; + const metadata = {httpRequest: res}; const logEntry = log.entry(metadata, 'some log message'); const traceId = span.spanContext().traceId; const spanId = span.spanContext().spanId; const traceSampled = (span.spanContext().traceFlags & 1) !== 0; log.write(logEntry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { - assert.ifError(err); - const entry = entries![0]; - assert.strictEqual(entry.data, 'some log message'); - assert.strictEqual(entry.metadata.httpRequest?.requestUrl, URL); - assert.strictEqual(entry.metadata.httpRequest?.protocol, 'http:'); - assert.strictEqual( - entry.metadata.trace, - `projects/${PROJECT_ID}/traces/${traceId}` - ); - assert.strictEqual(entry.metadata.spanId, spanId); - assert.strictEqual(entry.metadata.traceSampled, traceSampled); - done(); - }); + getEntriesFromLog( + log, + {numExpectedMessages: 1}, + (err, entries) => { + assert.ifError(err); + const entry = entries![0]; + assert.strictEqual(entry.data, 'some log message'); + assert.strictEqual( + entry.metadata.httpRequest?.requestUrl, + URL + ); + assert.strictEqual( + entry.metadata.httpRequest?.protocol, + 'http:' + ); + assert.strictEqual( + entry.metadata.trace, + `projects/${PROJECT_ID}/traces/${traceId}` + ); + assert.strictEqual(entry.metadata.spanId, spanId); + assert.strictEqual(entry.metadata.traceSampled, traceSampled); + done(); + } + ); }); }); }); }); - - }) + }); it('should set the default resource', done => { - const { log } = getTestLog(); + const {log} = getTestLog(); const text = 'entry-text'; const entry = log.entry(text); log.write(entry, err => { assert.ifError(err); - getEntriesFromLog(log, { numExpectedMessages: 1 }, (err, entries) => { + getEntriesFromLog(log, {numExpectedMessages: 1}, (err, entries) => { assert.ifError(err); const entry = entries![0]; @@ -916,7 +940,7 @@ describe('Logging', () => { }); it('should write a log with camelcase resource label keys', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.write( logEntries, { @@ -933,49 +957,49 @@ describe('Logging', () => { }); it('should write to a log with alert helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.alert(logEntries, options, done); }); it('should write to a log with critical helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.critical(logEntries, options, done); }); it('should write to a log with debug helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.debug(logEntries, options, done); }); it('should write to a log with emergency helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.emergency(logEntries, options, done); }); it('should write to a log with error helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.error(logEntries, options, done); }); it('should write to a log with info helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.info(logEntries, options, done); }); it('should write to a log with notice helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.notice(logEntries, options, done); }); it('should write to a log with warning helper', done => { - const { log, logEntries } = getTestLog(); + const {log, logEntries} = getTestLog(); log.warning(logEntries, options, done); }); it('should populate x-goog-api-client header', async () => { const gax = http2spy.require(require.resolve('google-gax')); - const { Logging } = require('../src'); - const { log, logEntries } = getTestLog(new Logging({}, gax)); + const {Logging} = require('../src'); + const {log, logEntries} = getTestLog(new Logging({}, gax)); await log.write(logEntries[0], options); assert.ok( /gax\/[0-9]+\.[\w.-]+ gapic\/[0-9]+\.[\w.-]+ gl-node\/[0-9]+\.[\w.-]+ grpc\/[0-9]+\.[\w.-]+ gccl\/[0-9]+\.[\w.-]+/.test( diff --git a/test/entry.ts b/test/entry.ts index a03294c5..71a4c751 100644 --- a/test/entry.ts +++ b/test/entry.ts @@ -13,25 +13,24 @@ // limitations under the License. import * as assert from 'assert'; -import { describe, it, before, beforeEach, afterEach } from 'mocha'; +import {describe, it, before, beforeEach, afterEach} from 'mocha'; import * as extend from 'extend'; import * as proxyquire from 'proxyquire'; import * as entryTypes from '../src/entry'; import * as common from '../src/utils/common'; import * as http from 'http'; -import { - InMemorySpanExporter, -} from '@opentelemetry/sdk-trace-base'; -import { NodeSDK } from '@opentelemetry/sdk-node'; -import { trace } from '@opentelemetry/api'; -const { Resource } = require('@opentelemetry/resources'); -const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); +import {InMemorySpanExporter} from '@opentelemetry/sdk-trace-base'; +import {trace} from '@opentelemetry/api'; +import {Resource} from '@opentelemetry/resources'; +//const {Resource} = require('@opentelemetry/resources'); +import {SEMRESATTRS_SERVICE_NAME} from '@opentelemetry/semantic-conventions'; +import {NodeSDK} from '@opentelemetry/sdk-node'; let fakeEventIdNewOverride: Function | null; class FakeEventId { new() { - const func = fakeEventIdNewOverride || (() => { }); + const func = fakeEventIdNewOverride || (() => {}); // eslint-disable-next-line prefer-rest-params return func(null, arguments); } @@ -106,7 +105,7 @@ describe('Entry', () => { it('should not assign timestamp if one is already set', () => { const timestamp = new Date('2012') as entryTypes.Timestamp; - const entry = new Entry({ timestamp }); + const entry = new Entry({timestamp}); assert.strictEqual(entry.metadata.timestamp, timestamp); }); @@ -193,7 +192,7 @@ describe('Entry', () => { describe('toJSON', () => { beforeEach(() => { - fakeObjToStruct = () => { }; + fakeObjToStruct = () => {}; }); it('should not modify the original instance', () => { @@ -230,7 +229,7 @@ describe('Entry', () => { done(); }; entry.data = {}; - entry.toJSON({ removeCircular: true }); + entry.toJSON({removeCircular: true}); }); it('should assign string data as textPayload', () => { @@ -313,65 +312,83 @@ describe('Entry', () => { assert.strictEqual(json.traceSampled, expected.traceSampled); }); - describe.only('toJSONWithOtel', () => { + describe('toJSONWithOtel', () => { let sdk: NodeSDK; before(() => { sdk = new NodeSDK({ resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: 'nodejs-logging-entry-test', + [SEMRESATTRS_SERVICE_NAME]: 'nodejs-logging-entry-test', }), traceExporter: new InMemorySpanExporter(), }); sdk.start(); - }) + }); after(() => { sdk.shutdown(); - }) + }); it('should detect open telemetry trace and span if open telemetry context present', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (span) => { - const json = entry.toJSON(); - assert.strictEqual(json.trace, `projects//traces/${span.spanContext().traceId}`); - assert.strictEqual(json.spanId, span.spanContext().spanId); - assert.strictEqual(json.traceSampled, (span.spanContext().traceFlags & 1) !== 0); - }); + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', span => { + const json = entry.toJSON(); + assert.strictEqual( + json.trace, + `projects//traces/${span.spanContext().traceId}` + ); + assert.strictEqual(json.spanId, span.spanContext().spanId); + assert.strictEqual( + json.traceSampled, + (span.spanContext().traceFlags & 1) !== 0 + ); + }); }); it('should detect open telemetry trace and span if open telemetry context and headers present', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (span) => { - const req = { - method: 'GET', - } as unknown as http.IncomingMessage; - // To mock http message.headers, we must use lowercased keys. - req.headers = { - 'x-cloud-trace-context': '0000/1111;o=1', - }; - entry.metadata.httpRequest = req; - const json = entry.toJSON(); - assert.strictEqual(json.trace, `projects//traces/${span.spanContext().traceId}`); - assert.strictEqual(json.spanId, span.spanContext().spanId); - assert.strictEqual(json.traceSampled, (span.spanContext().traceFlags & 1) !== 0); - }); + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', span => { + const req = { + method: 'GET', + } as unknown as http.IncomingMessage; + // To mock http message.headers, we must use lowercased keys. + req.headers = { + 'x-cloud-trace-context': '0000/1111;o=1', + }; + entry.metadata.httpRequest = req; + const json = entry.toJSON(); + assert.strictEqual( + json.trace, + `projects//traces/${span.spanContext().traceId}` + ); + assert.strictEqual(json.spanId, span.spanContext().spanId); + assert.strictEqual( + json.traceSampled, + (span.spanContext().traceFlags & 1) !== 0 + ); + }); }); it('should not overwrite user defined trace and span when open telemetry context detected', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (span) => { - entry.metadata.spanId = '1'; - entry.metadata.trace = '1'; - entry.metadata.traceSampled = false; - const expected = { - trace: '1', - spanId: '1', - traceSampled: false, - }; - - const json = entry.toJSON(); - assert.strictEqual(json.trace, expected.trace); - assert.strictEqual(json.spanId, expected.spanId); - assert.strictEqual(json.traceSampled, expected.traceSampled); - }); + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', span => { + entry.metadata.spanId = '1'; + entry.metadata.trace = '1'; + entry.metadata.traceSampled = false; + const expected = { + trace: '1', + spanId: '1', + traceSampled: false, + }; + + const json = entry.toJSON(); + assert.strictEqual(json.trace, expected.trace); + assert.strictEqual(json.spanId, expected.spanId); + assert.strictEqual(json.traceSampled, expected.traceSampled); + }); }); }); }); @@ -390,7 +407,7 @@ describe('Entry', () => { it('should re-map new keys and delete old keys', () => { entry.metadata.insertId = '👀'; - entry.metadata.labels = { foo: '⌛️' }; + entry.metadata.labels = {foo: '⌛️'}; entry.metadata.spanId = '🍓'; entry.metadata.trace = '🍝'; entry.metadata.traceSampled = false; @@ -405,7 +422,7 @@ describe('Entry', () => { [entryTypes.TRACE_KEY]: '🍝', [entryTypes.SPAN_ID_KEY]: '🍓', [entryTypes.TRACE_SAMPLED_KEY]: false, - [entryTypes.LABELS_KEY]: { foo: '⌛️' }, + [entryTypes.LABELS_KEY]: {foo: '⌛️'}, message: 'this is a log', }; assert.deepStrictEqual(json, expectedJSON); @@ -451,7 +468,7 @@ describe('Entry', () => { }); it('should add message field for structured data', () => { - entry.data = { message: 'message', test: 'test' }; + entry.data = {message: 'message', test: 'test'}; let json = entry.toStructuredJSON(); // eslint-disable-next-line @typescript-eslint/no-explicit-any assert(((json.message as any).message = 'message')); @@ -473,64 +490,91 @@ describe('Entry', () => { assert((json.message = 'test')); }); - describe.only('toStructuredJSONWithOtel', () => { + describe('toStructuredJSONWithOtel', () => { let sdk: NodeSDK; before(() => { sdk = new NodeSDK({ resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: 'nodejs-logging-entry-test', + [SEMRESATTRS_SERVICE_NAME]: 'nodejs-logging-entry-test', }), traceExporter: new InMemorySpanExporter(), }); sdk.start(); - }) + }); after(() => { sdk.shutdown(); - }) + }); it('should detect open telemetry trace and span if open telemetry context present', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (span) => { - const json = entry.toStructuredJSON(); - assert.strictEqual(json[entryTypes.TRACE_KEY], `projects//traces/${span.spanContext().traceId}`); - assert.strictEqual(json[entryTypes.SPAN_ID_KEY], span.spanContext().spanId); - assert.strictEqual(json[entryTypes.TRACE_SAMPLED_KEY], (span.spanContext().traceFlags & 1) !== 0); - }); + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', span => { + const json = entry.toStructuredJSON(); + assert.strictEqual( + json[entryTypes.TRACE_KEY], + `projects//traces/${span.spanContext().traceId}` + ); + assert.strictEqual( + json[entryTypes.SPAN_ID_KEY], + span.spanContext().spanId + ); + assert.strictEqual( + json[entryTypes.TRACE_SAMPLED_KEY], + (span.spanContext().traceFlags & 1) !== 0 + ); + }); }); it('should detect open telemetry trace and span if open telemetry context and headers present', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (span) => { - const req = { - method: 'GET', - } as unknown as http.IncomingMessage; - // To mock http message.headers, we must use lowercased keys. - req.headers = { - 'x-cloud-trace-context': '0000/1111;o=1', - }; - entry.metadata.httpRequest = req; - const json = entry.toStructuredJSON(); - assert.strictEqual(json[entryTypes.TRACE_KEY], `projects//traces/${span.spanContext().traceId}`); - assert.strictEqual(json[entryTypes.SPAN_ID_KEY], span.spanContext().spanId); - assert.strictEqual(json[entryTypes.TRACE_SAMPLED_KEY], (span.spanContext().traceFlags & 1) !== 0); - }); + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', span => { + const req = { + method: 'GET', + } as unknown as http.IncomingMessage; + // To mock http message.headers, we must use lowercased keys. + req.headers = { + 'x-cloud-trace-context': '0000/1111;o=1', + }; + entry.metadata.httpRequest = req; + const json = entry.toStructuredJSON(); + assert.strictEqual( + json[entryTypes.TRACE_KEY], + `projects//traces/${span.spanContext().traceId}` + ); + assert.strictEqual( + json[entryTypes.SPAN_ID_KEY], + span.spanContext().spanId + ); + assert.strictEqual( + json[entryTypes.TRACE_SAMPLED_KEY], + (span.spanContext().traceFlags & 1) !== 0 + ); + }); }); it('should not overwrite user defined trace and span when open telemetry context detected', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (span) => { - entry.metadata.spanId = '1'; - entry.metadata.trace = '1'; - entry.metadata.traceSampled = false; - const expected = { - trace: '1', - spanId: '1', - traceSampled: false, - }; - const json = entry.toStructuredJSON(); - assert.strictEqual(json[entryTypes.TRACE_KEY], expected.trace); - assert.strictEqual(json[entryTypes.SPAN_ID_KEY], expected.spanId); - assert.strictEqual(json[entryTypes.TRACE_SAMPLED_KEY], expected.traceSampled); - }); + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', span => { + entry.metadata.spanId = '1'; + entry.metadata.trace = '1'; + entry.metadata.traceSampled = false; + const expected = { + trace: '1', + spanId: '1', + traceSampled: false, + }; + const json = entry.toStructuredJSON(); + assert.strictEqual(json[entryTypes.TRACE_KEY], expected.trace); + assert.strictEqual(json[entryTypes.SPAN_ID_KEY], expected.spanId); + assert.strictEqual( + json[entryTypes.TRACE_SAMPLED_KEY], + expected.traceSampled + ); + }); }); }); }); diff --git a/test/utils/context.ts b/test/utils/context.ts index 86e10f9e..caf9ed71 100644 --- a/test/utils/context.ts +++ b/test/utils/context.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { describe, it} from 'mocha'; +import {describe, it} from 'mocha'; import * as http from 'http'; import { getOrInjectContext, @@ -23,13 +23,12 @@ import { parseXCloudTraceHeader, parseTraceParentHeader, } from '../../src/utils/context'; -import { - InMemorySpanExporter, -} from '@opentelemetry/sdk-trace-base'; -import { NodeSDK } from '@opentelemetry/sdk-node'; -import { trace } from '@opentelemetry/api'; -const { Resource } = require('@opentelemetry/resources'); -const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); +import {InMemorySpanExporter} from '@opentelemetry/sdk-trace-base'; +import {trace} from '@opentelemetry/api'; +import {Resource} from '@opentelemetry/resources'; +//const {Resource} = require('@opentelemetry/resources'); +import {SEMRESATTRS_SERVICE_NAME} from '@opentelemetry/semantic-conventions'; +import {NodeSDK} from '@opentelemetry/sdk-node'; describe('context', () => { describe('makeHeaderWrapper', () => { @@ -103,288 +102,323 @@ describe('context', () => { assert.strictEqual(context.traceSampled, false); }); - describe.only('getOrInjectContextWithOtel', () => { + describe('getOrInjectContextWithOtel', () => { let sdk: NodeSDK; before(() => { sdk = new NodeSDK({ resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: 'nodejs-logging-context-test', + [SEMRESATTRS_SERVICE_NAME]: 'nodejs-logging-context-test', }), traceExporter: new InMemorySpanExporter(), }); - + sdk.start(); - }) - + }); + after(() => { sdk.shutdown(); - }) - - it('should ignore a default trace context when open telemetry context detected', () => { - trace.getTracer('nodejs-logging-context-test').startActiveSpan('foo', (parentSpan) => { - const req = { - method: 'GET', - } as http.IncomingMessage; - const projectId = 'myProj'; - const context = getOrInjectContext(req, projectId); - const traceId = parentSpan.spanContext().traceId; - const spanId = parentSpan.spanContext().spanId; - const traceSampled = (parentSpan.spanContext().traceFlags & 1) !== 0; - assert.strictEqual(context.trace, `projects/${projectId}/traces/${traceId}`); - assert.strictEqual(context.spanId, spanId); - assert.strictEqual(context.traceSampled, traceSampled); }); + + it('should ignore a default trace context when open telemetry context detected', () => { + trace + .getTracer('nodejs-logging-context-test') + .startActiveSpan('foo', parentSpan => { + const req = { + method: 'GET', + } as http.IncomingMessage; + const projectId = 'myProj'; + const context = getOrInjectContext(req, projectId); + const traceId = parentSpan.spanContext().traceId; + const spanId = parentSpan.spanContext().spanId; + const traceSampled = + (parentSpan.spanContext().traceFlags & 1) !== 0; + assert.strictEqual( + context.trace, + `projects/${projectId}/traces/${traceId}` + ); + assert.strictEqual(context.spanId, spanId); + assert.strictEqual(context.traceSampled, traceSampled); + }); }); it('should return a formatted open telemetry trace context', () => { - trace.getTracer('nodejs-context-test').startActiveSpan('foo', (parentSpan) => { - const req = {headers: {}} as http.IncomingMessage; - const projectId = 'myProj'; - const context = getOrInjectContext(req, projectId); - const traceId = parentSpan.spanContext().traceId; - const spanId = parentSpan.spanContext().spanId; - const traceSampled = (parentSpan.spanContext().traceFlags & 1) !== 0; - assert.strictEqual(context.trace, `projects/${projectId}/traces/${traceId}`); - assert.strictEqual(context.spanId, spanId); - assert.strictEqual(context.traceSampled, traceSampled); + trace + .getTracer('nodejs-context-test') + .startActiveSpan('foo', parentSpan => { + const req = {headers: {}} as http.IncomingMessage; + const projectId = 'myProj'; + const context = getOrInjectContext(req, projectId); + const traceId = parentSpan.spanContext().traceId; + const spanId = parentSpan.spanContext().spanId; + const traceSampled = + (parentSpan.spanContext().traceFlags & 1) !== 0; + assert.strictEqual( + context.trace, + `projects/${projectId}/traces/${traceId}` + ); + assert.strictEqual(context.spanId, spanId); + assert.strictEqual(context.traceSampled, traceSampled); + }); }); - }) - - it('should ignore W3C trace context and return open telemetry context', () => { - trace.getTracer('nodejs-context-test').startActiveSpan('foo', (parentSpan) => { - const projectId = 'myProj'; - const req = { - headers: { - ['traceparent']: - '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01', - }, - } as unknown as http.IncomingMessage; - const context = getOrInjectContext(req, projectId); - const traceId = parentSpan.spanContext().traceId; - const spanId = parentSpan.spanContext().spanId; - const traceSampled = (parentSpan.spanContext().traceFlags & 1) !== 0; - assert.strictEqual(context.trace, `projects/${projectId}/traces/${traceId}`); - assert.strictEqual(context.spanId, spanId); - assert.strictEqual(context.traceSampled, traceSampled); - }) - }); - it('should ignore google trace context and return open telemetry context', () => { - trace.getTracer('nodejs-context-test').startActiveSpan('foo', (parentSpan) => { - const projectId = 'myProj'; - const req = { - headers: {['x-cloud-trace-context']: '1/2;o=1'}, - } as unknown as http.IncomingMessage; - const context = getOrInjectContext(req, projectId); - const traceId = parentSpan.spanContext().traceId; - const spanId = parentSpan.spanContext().spanId; - const traceSampled = (parentSpan.spanContext().traceFlags & 1) !== 0; - assert.strictEqual(context.trace, `projects/${projectId}/traces/${traceId}`); - assert.strictEqual(context.spanId, spanId); - assert.strictEqual(context.traceSampled, traceSampled); - }) - }); + it('should ignore W3C trace context and return open telemetry context', () => { + trace + .getTracer('nodejs-context-test') + .startActiveSpan('foo', parentSpan => { + const projectId = 'myProj'; + const req = { + headers: { + ['traceparent']: + '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01', + }, + } as unknown as http.IncomingMessage; + const context = getOrInjectContext(req, projectId); + const traceId = parentSpan.spanContext().traceId; + const spanId = parentSpan.spanContext().spanId; + const traceSampled = + (parentSpan.spanContext().traceFlags & 1) !== 0; + assert.strictEqual( + context.trace, + `projects/${projectId}/traces/${traceId}` + ); + assert.strictEqual(context.spanId, spanId); + assert.strictEqual(context.traceSampled, traceSampled); + }); + }); + it('should ignore google trace context and return open telemetry context', () => { + trace + .getTracer('nodejs-context-test') + .startActiveSpan('foo', parentSpan => { + const projectId = 'myProj'; + const req = { + headers: {['x-cloud-trace-context']: '1/2;o=1'}, + } as unknown as http.IncomingMessage; + const context = getOrInjectContext(req, projectId); + const traceId = parentSpan.spanContext().traceId; + const spanId = parentSpan.spanContext().spanId; + const traceSampled = + (parentSpan.spanContext().traceFlags & 1) !== 0; + assert.strictEqual( + context.trace, + `projects/${projectId}/traces/${traceId}` + ); + assert.strictEqual(context.spanId, spanId); + assert.strictEqual(context.traceSampled, traceSampled); + }); + }); - it('should ignore injecting Google trace context option', () => { - trace.getTracer('nodejs-context-test').startActiveSpan('foo', (parentSpan) => { - const projectId = 'myProj'; - const req = {headers: {}} as http.IncomingMessage; - const context = getOrInjectContext(req, projectId, true); - const traceId = parentSpan.spanContext().traceId; - const spanId = parentSpan.spanContext().spanId; - const traceSampled = (parentSpan.spanContext().traceFlags & 1) !== 0; - assert.strictEqual(context.trace, `projects/${projectId}/traces/${traceId}`); - assert.strictEqual(context.spanId, spanId); - assert.strictEqual(context.traceSampled, traceSampled); - }) + it('should ignore injecting Google trace context option', () => { + trace + .getTracer('nodejs-context-test') + .startActiveSpan('foo', parentSpan => { + const projectId = 'myProj'; + const req = {headers: {}} as http.IncomingMessage; + const context = getOrInjectContext(req, projectId, true); + const traceId = parentSpan.spanContext().traceId; + const spanId = parentSpan.spanContext().spanId; + const traceSampled = + (parentSpan.spanContext().traceFlags & 1) !== 0; + assert.strictEqual( + context.trace, + `projects/${projectId}/traces/${traceId}` + ); + assert.strictEqual(context.spanId, spanId); + assert.strictEqual(context.traceSampled, traceSampled); + }); + }); }); - }); - describe('parseXCloudTraceHeader', () => { - it('should extract trace properties from X-Cloud-Trace-Context', () => { - const tests = [ - { - header: '105445aa7843bc8bf206b120001000/000000001;o=1', - expected: { - trace: '105445aa7843bc8bf206b120001000', - spanId: '000000001', - traceSampled: true, + describe('parseXCloudTraceHeader', () => { + it('should extract trace properties from X-Cloud-Trace-Context', () => { + const tests = [ + { + header: '105445aa7843bc8bf206b120001000/000000001;o=1', + expected: { + trace: '105445aa7843bc8bf206b120001000', + spanId: '000000001', + traceSampled: true, + }, }, - }, - // TraceSampled is false - { - header: '105445aa7843bc8bf206b120001000/000000001;o=0', - expected: { - trace: '105445aa7843bc8bf206b120001000', - spanId: '000000001', - traceSampled: false, + // TraceSampled is false + { + header: '105445aa7843bc8bf206b120001000/000000001;o=0', + expected: { + trace: '105445aa7843bc8bf206b120001000', + spanId: '000000001', + traceSampled: false, + }, }, - }, - { - // No span - header: '105445aa7843bc8bf206b120001000;o=1', - expected: { - trace: '105445aa7843bc8bf206b120001000', - spanId: undefined, - traceSampled: true, + { + // No span + header: '105445aa7843bc8bf206b120001000;o=1', + expected: { + trace: '105445aa7843bc8bf206b120001000', + spanId: undefined, + traceSampled: true, + }, }, - }, - { - // No trace - header: '/105445aa7843bc8bf206b120001000;o=0', - expected: { - trace: undefined, - spanId: '105445aa7843bc8bf206b120001000', - traceSampled: false, + { + // No trace + header: '/105445aa7843bc8bf206b120001000;o=0', + expected: { + trace: undefined, + spanId: '105445aa7843bc8bf206b120001000', + traceSampled: false, + }, }, - }, - { - // No traceSampled - header: '105445aa7843bc8bf206b120001000/0', - expected: { - trace: '105445aa7843bc8bf206b120001000', - spanId: '0', - traceSampled: false, + { + // No traceSampled + header: '105445aa7843bc8bf206b120001000/0', + expected: { + trace: '105445aa7843bc8bf206b120001000', + spanId: '0', + traceSampled: false, + }, }, - }, - { - // No input - header: '', - expected: { - trace: undefined, - spanId: undefined, - traceSampled: false, + { + // No input + header: '', + expected: { + trace: undefined, + spanId: undefined, + traceSampled: false, + }, }, - }, - ]; - for (const test of tests) { - const req = { - method: 'GET', - } as unknown as http.IncomingMessage; - req.headers = { - 'x-cloud-trace-context': test.header, - }; + ]; + for (const test of tests) { + const req = { + method: 'GET', + } as unknown as http.IncomingMessage; + req.headers = { + 'x-cloud-trace-context': test.header, + }; - const wrapper = makeHeaderWrapper(req); - const context = parseXCloudTraceHeader(wrapper!); - if (context) { - assert.strictEqual( - context.trace, - test.expected.trace, - `From ${test.header}; Expected trace: ${test.expected.trace}; Got: ${context.trace}` - ); - assert.strictEqual( - context.spanId, - test.expected.spanId, - `From ${test.header}; Expected spanId: ${test.expected.spanId}; Got: ${context.spanId}` - ); - assert.strictEqual( - context.traceSampled, - test.expected.traceSampled, - `From ${test.header}; Expected traceSampled: ${test.expected.traceSampled}; Got: ${context.traceSampled}` - ); - } else { - assert.fail(); + const wrapper = makeHeaderWrapper(req); + const context = parseXCloudTraceHeader(wrapper!); + if (context) { + assert.strictEqual( + context.trace, + test.expected.trace, + `From ${test.header}; Expected trace: ${test.expected.trace}; Got: ${context.trace}` + ); + assert.strictEqual( + context.spanId, + test.expected.spanId, + `From ${test.header}; Expected spanId: ${test.expected.spanId}; Got: ${context.spanId}` + ); + assert.strictEqual( + context.traceSampled, + test.expected.traceSampled, + `From ${test.header}; Expected traceSampled: ${test.expected.traceSampled}; Got: ${context.traceSampled}` + ); + } else { + assert.fail(); + } } - } + }); }); - }); - describe('parseOtelContext', ()=> { - let sdk: NodeSDK; - before(() => { - sdk = new NodeSDK({ - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: 'nodejs-context-test', - }), - traceExporter: new InMemorySpanExporter(), + describe('parseOtelContext', () => { + let sdk: NodeSDK; + before(() => { + sdk = new NodeSDK({ + resource: new Resource({ + [SEMRESATTRS_SERVICE_NAME]: 'nodejs-context-test', + }), + traceExporter: new InMemorySpanExporter(), + }); + + sdk.start(); }); - - sdk.start(); - }); - after(() => { - sdk.shutdown(); - }); + after(() => { + sdk.shutdown(); + }); - it('should extract trace context from open telemetry context', () => { - trace.getTracer('nodejs-context-test').startActiveSpan('boo', (parentSpan) => { - const req = {headers: {}} as http.IncomingMessage; - const projectId = 'myProj'; - const context = getOrInjectContext(req, projectId); - const traceId = parentSpan.spanContext().traceId; - const spanId = parentSpan.spanContext().spanId; - const traceSampled = (parentSpan.spanContext().traceFlags & 1) !== 0; - assert.strictEqual(context.trace, `projects/${projectId}/traces/${traceId}`); - assert.strictEqual(context.spanId, spanId); - assert.strictEqual(context.traceSampled, traceSampled); - }) - }); -}); + it('should extract trace context from open telemetry context', () => { + trace + .getTracer('nodejs-context-test') + .startActiveSpan('boo', parentSpan => { + const req = {headers: {}} as http.IncomingMessage; + const projectId = 'myProj'; + const context = getOrInjectContext(req, projectId); + const traceId = parentSpan.spanContext().traceId; + const spanId = parentSpan.spanContext().spanId; + const traceSampled = + (parentSpan.spanContext().traceFlags & 1) !== 0; + assert.strictEqual( + context.trace, + `projects/${projectId}/traces/${traceId}` + ); + assert.strictEqual(context.spanId, spanId); + assert.strictEqual(context.traceSampled, traceSampled); + }); + }); + }); - describe('parseTraceParentHeader', () => { - it('should extract trace properties from traceparent', () => { - const tests = [ - { - header: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01', - expected: { - trace: '0af7651916cd43dd8448eb211c80319c', - spanId: 'b7ad6b7169203331', - traceSampled: true, + describe('parseTraceParentHeader', () => { + it('should extract trace properties from traceparent', () => { + const tests = [ + { + header: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01', + expected: { + trace: '0af7651916cd43dd8448eb211c80319c', + spanId: 'b7ad6b7169203331', + traceSampled: true, + }, }, - }, - // TraceSampled is false - { - header: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00', - expected: { - trace: '0af7651916cd43dd8448eb211c80319c', - spanId: 'b7ad6b7169203331', - traceSampled: false, + // TraceSampled is false + { + header: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00', + expected: { + trace: '0af7651916cd43dd8448eb211c80319c', + spanId: 'b7ad6b7169203331', + traceSampled: false, + }, }, - }, - { - // No input - header: '', - expected: { - trace: undefined, - spanId: undefined, - traceSampled: false, + { + // No input + header: '', + expected: { + trace: undefined, + spanId: undefined, + traceSampled: false, + }, }, - }, - ]; - for (const test of tests) { - const req = { - method: 'GET', - } as unknown as http.IncomingMessage; - req.headers = { - traceparent: test.header, - }; + ]; + for (const test of tests) { + const req = { + method: 'GET', + } as unknown as http.IncomingMessage; + req.headers = { + traceparent: test.header, + }; - const wrapper = makeHeaderWrapper(req); - const context = parseTraceParentHeader(wrapper!); - if (context) { - assert.strictEqual( - context.trace, - test.expected.trace, - `From ${test.header}; Expected trace: ${test.expected.trace}; Got: ${context.trace}` - ); - assert.strictEqual( - context.spanId, - test.expected.spanId, - `From ${test.header}; Expected spanId: ${test.expected.spanId}; Got: ${context.spanId}` - ); - assert.strictEqual( - context.traceSampled, - test.expected.traceSampled, - `From ${test.header}; Expected traceSampled: ${test.expected.traceSampled}; Got: ${context.traceSampled}` - ); - } else { - // This is the header: '' test case; - assert.strictEqual(test.header, ''); + const wrapper = makeHeaderWrapper(req); + const context = parseTraceParentHeader(wrapper!); + if (context) { + assert.strictEqual( + context.trace, + test.expected.trace, + `From ${test.header}; Expected trace: ${test.expected.trace}; Got: ${context.trace}` + ); + assert.strictEqual( + context.spanId, + test.expected.spanId, + `From ${test.header}; Expected spanId: ${test.expected.spanId}; Got: ${context.spanId}` + ); + assert.strictEqual( + context.traceSampled, + test.expected.traceSampled, + `From ${test.header}; Expected traceSampled: ${test.expected.traceSampled}; Got: ${context.traceSampled}` + ); + } else { + // This is the header: '' test case; + assert.strictEqual(test.header, ''); + } } - } + }); }); }); -}) -}) \ No newline at end of file +});