From 479ee8fced2894848d85525995aa51d40585fd2f Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:38:48 -0700 Subject: [PATCH] feat: parse log severity number/array of object attributes + setup linting --- .changeset/mighty-humans-sparkle.md | 5 + package.json | 14 ++- packages/node-opentelemetry/.eslintrc.json | 15 ++- .../node-opentelemetry/__tests__/otel.test.ts | 15 --- .../bin/opentelemetry-instrument.ts | 2 +- packages/node-opentelemetry/examples/dummy.js | 30 +++-- packages/node-opentelemetry/jest.config.ts | 1 + .../MutableAsyncLocalStorageContextManager.ts | 1 + .../{ => src}/__tests__/logger.test.ts | 2 +- .../src/__tests__/otel.test.ts | 30 +++++ packages/node-opentelemetry/src/constants.ts | 2 +- packages/node-opentelemetry/src/gcp.ts | 4 +- .../__tests__/instrumentations.test.ts | 4 +- .../src/instrumentations/console.ts | 6 +- .../src/instrumentations/http.ts | 7 +- packages/node-opentelemetry/src/logger.ts | 5 +- .../__snapshots__/index.test.ts.snap | 35 ++++++ .../src/otel-logger/__tests__/index.test.ts | 31 ++++++ .../src/otel-logger/index.ts | 103 +++++++++++++++--- .../src/otel-logger/pino.ts | 7 +- .../src/otel-logger/winston.ts | 7 +- packages/node-opentelemetry/src/otel.ts | 43 ++++---- .../node-opentelemetry/src/spanProcessor.ts | 4 +- packages/node-opentelemetry/src/utils.ts | 2 +- .../node-opentelemetry/tsconfig.release.json | 3 +- yarn.lock | 55 +++++++++- 26 files changed, 326 insertions(+), 107 deletions(-) create mode 100644 .changeset/mighty-humans-sparkle.md delete mode 100644 packages/node-opentelemetry/__tests__/otel.test.ts rename packages/node-opentelemetry/{ => src}/__tests__/logger.test.ts (86%) create mode 100644 packages/node-opentelemetry/src/__tests__/otel.test.ts rename packages/node-opentelemetry/{ => src/instrumentations}/__tests__/instrumentations.test.ts (98%) create mode 100644 packages/node-opentelemetry/src/otel-logger/__tests__/__snapshots__/index.test.ts.snap create mode 100644 packages/node-opentelemetry/src/otel-logger/__tests__/index.test.ts diff --git a/.changeset/mighty-humans-sparkle.md b/.changeset/mighty-humans-sparkle.md new file mode 100644 index 00000000..139f60ba --- /dev/null +++ b/.changeset/mighty-humans-sparkle.md @@ -0,0 +1,5 @@ +--- +'@hyperdx/node-opentelemetry': minor +--- + +feat: use getSeverityNumber and parseLogAttributes for logger diff --git a/package.json b/package.json index ed6c7431..5dd34b16 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,13 @@ "prepare": "husky install" }, "lint-staged": { - "**/*": "prettier --write --ignore-unknown" + "**/*.{ts,tsx}": [ + "prettier --write --ignore-unknown", + "eslint --fix" + ], + "**/*.{json,yml}": [ + "prettier --write --ignore-unknown" + ] }, "devDependencies": { "@changesets/cli": "^2.26.1", @@ -29,13 +35,15 @@ "@typescript-eslint/eslint-plugin": "^5.59.9", "@typescript-eslint/parser": "^5.59.9", "eslint": "^8.42.0", - "eslint-config-prettier": "^8.8.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-simple-import-sort": "^12.1.1", "husky": "^8.0.3", "jest": "^29.5.0", "lint-staged": "^13.2.2", "nx": "^15.9.2", - "prettier": "^2.8.7", + "prettier": "^3.3.3", "rimraf": "^5.0.1", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", diff --git a/packages/node-opentelemetry/.eslintrc.json b/packages/node-opentelemetry/.eslintrc.json index f84bdc1a..da359c17 100644 --- a/packages/node-opentelemetry/.eslintrc.json +++ b/packages/node-opentelemetry/.eslintrc.json @@ -10,20 +10,19 @@ "sourceType": "module", "ecmaVersion": 2020 }, - "plugins": ["@typescript-eslint", "jest"], + "plugins": ["@typescript-eslint", "jest", "prettier", "simple-import-sort"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:jest/recommended", - "prettier" + "plugin:prettier/recommended" ], "rules": { - // The following rule is enabled only to supplement the inline suppression - // examples, and because it is not a recommended rule, you should either - // disable it, or understand what it enforces. - // https://typescript-eslint.io/rules/explicit-function-return-type/ - "@typescript-eslint/explicit-function-return-type": "warn", "@typescript-eslint/ban-ts-comment": "warn", - "@typescript-eslint/no-this-alias": "warn" + "@typescript-eslint/explicit-function-return-type": "warn", + "@typescript-eslint/no-this-alias": "warn", + "prettier/prettier": "error", + "simple-import-sort/exports": "error", + "simple-import-sort/imports": "error" } } diff --git a/packages/node-opentelemetry/__tests__/otel.test.ts b/packages/node-opentelemetry/__tests__/otel.test.ts deleted file mode 100644 index 93096729..00000000 --- a/packages/node-opentelemetry/__tests__/otel.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { initSDK, shutdown } from '../src/otel'; - -describe('otel', () => { - it('can sucessively shutdown without initialization', () => { - shutdown(); - shutdown(); - }); - - it('should initialize the SDK', () => { - initSDK({ - advancedNetworkCapture: true, - consoleCapture: true, - }); - }); -}); diff --git a/packages/node-opentelemetry/bin/opentelemetry-instrument.ts b/packages/node-opentelemetry/bin/opentelemetry-instrument.ts index 0727e286..6a1ae4f6 100755 --- a/packages/node-opentelemetry/bin/opentelemetry-instrument.ts +++ b/packages/node-opentelemetry/bin/opentelemetry-instrument.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node -import process from 'process'; import fs from 'fs'; +import process from 'process'; import { promisify } from 'util'; const realpath = promisify(fs.realpath); diff --git a/packages/node-opentelemetry/examples/dummy.js b/packages/node-opentelemetry/examples/dummy.js index 16c75536..b45fa444 100644 --- a/packages/node-opentelemetry/examples/dummy.js +++ b/packages/node-opentelemetry/examples/dummy.js @@ -292,22 +292,30 @@ app.get('/instruments', async (req, res) => { }); app.get('/logs', async (req, res) => { - console.debug({ + const nestedObj = { headers: req.headers, method: req.method, url: req.url, - query: req.query, + nested: [ + { + foo: 'bar', + }, + ], + nested2: { + nested3: { + foo: 'bar', + }, + }, + }; + console.error({ + message: 'Console πŸ•', + ...nestedObj, }); - console.error('BANG !!!'); - console.log('Console πŸ•'); - logger.info({ - message: 'Winston πŸ•', - headers: req.headers, - method: req.method, - url: req.url, + logger.info('Winston πŸ•', nestedObj); + pinoLogger.info({ + message: 'Pino πŸ•', + ...nestedObj, }); - pinoLogger.info('Pino πŸ•'); - bunyanLogger.info('Bunyan πŸ•'); console.log(await sendGetRequest()); diff --git a/packages/node-opentelemetry/jest.config.ts b/packages/node-opentelemetry/jest.config.ts index 4c887d30..f7551214 100644 --- a/packages/node-opentelemetry/jest.config.ts +++ b/packages/node-opentelemetry/jest.config.ts @@ -9,6 +9,7 @@ const config: Config = { moduleNameMapper: { '^(\\.{1,2}/.*)\\.(m)?js$': '$1', }, + modulePathIgnorePatterns: ['/build/'], testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(m)?ts$', coverageDirectory: 'coverage', collectCoverageFrom: [ diff --git a/packages/node-opentelemetry/src/MutableAsyncLocalStorageContextManager.ts b/packages/node-opentelemetry/src/MutableAsyncLocalStorageContextManager.ts index ab885368..1b49eaf9 100644 --- a/packages/node-opentelemetry/src/MutableAsyncLocalStorageContextManager.ts +++ b/packages/node-opentelemetry/src/MutableAsyncLocalStorageContextManager.ts @@ -16,6 +16,7 @@ import { Context, ROOT_CONTEXT } from '@opentelemetry/api'; import { AsyncLocalStorage } from 'async_hooks'; + import { AbstractAsyncHooksContextManager } from './AbstractAsyncHooksContextManager'; type MutableContextStore = { diff --git a/packages/node-opentelemetry/__tests__/logger.test.ts b/packages/node-opentelemetry/src/__tests__/logger.test.ts similarity index 86% rename from packages/node-opentelemetry/__tests__/logger.test.ts rename to packages/node-opentelemetry/src/__tests__/logger.test.ts index 718574ba..2e98988f 100644 --- a/packages/node-opentelemetry/__tests__/logger.test.ts +++ b/packages/node-opentelemetry/src/__tests__/logger.test.ts @@ -1,6 +1,6 @@ import winston from 'winston'; -import { getWinstonTransport } from '../src/logger'; +import { getWinstonTransport } from '../logger'; const MAX_LEVEL = 'info'; diff --git a/packages/node-opentelemetry/src/__tests__/otel.test.ts b/packages/node-opentelemetry/src/__tests__/otel.test.ts new file mode 100644 index 00000000..73434b5a --- /dev/null +++ b/packages/node-opentelemetry/src/__tests__/otel.test.ts @@ -0,0 +1,30 @@ +import { init, initSDK, shutdown } from '../otel'; + +describe('otel', () => { + it('can sucessively shutdown without initialization', () => { + shutdown(); + shutdown(); + }); + + it('should be able to initialize the SDK with initSDK', async () => { + initSDK({ + apiKey: 'blabla', + advancedNetworkCapture: true, + consoleCapture: true, + }); + + await new Promise((resolve) => setTimeout(resolve, 1000)); + + shutdown(); + }); + + it('should be able to initialize the SDK with init', async () => { + init({ + apiKey: 'blabla', + }); + + await new Promise((resolve) => setTimeout(resolve, 1000)); + + shutdown(); + }); +}); diff --git a/packages/node-opentelemetry/src/constants.ts b/packages/node-opentelemetry/src/constants.ts index d8659f98..e3004c92 100644 --- a/packages/node-opentelemetry/src/constants.ts +++ b/packages/node-opentelemetry/src/constants.ts @@ -1,5 +1,5 @@ +import { getEnv, getEnvWithoutDefaults } from '@opentelemetry/core'; import { defaultServiceName } from '@opentelemetry/resources'; -import { getEnvWithoutDefaults, getEnv } from '@opentelemetry/core'; import { stringToBoolean } from './utils'; diff --git a/packages/node-opentelemetry/src/gcp.ts b/packages/node-opentelemetry/src/gcp.ts index cc88b414..478b3ff0 100644 --- a/packages/node-opentelemetry/src/gcp.ts +++ b/packages/node-opentelemetry/src/gcp.ts @@ -1,8 +1,8 @@ +import { context, SpanKind, trace } from '@opentelemetry/api'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; -import { SpanKind, context, trace } from '@opentelemetry/api'; -import { SDKConfig, initSDK } from './otel'; import { name as PKG_NAME, version as PKG_VERSION } from '../package.json'; +import { initSDK, SDKConfig } from './otel'; export const registerGCPCloudFunctionEventHandler = ( handler: (event: any) => Promise, diff --git a/packages/node-opentelemetry/__tests__/instrumentations.test.ts b/packages/node-opentelemetry/src/instrumentations/__tests__/instrumentations.test.ts similarity index 98% rename from packages/node-opentelemetry/__tests__/instrumentations.test.ts rename to packages/node-opentelemetry/src/instrumentations/__tests__/instrumentations.test.ts index 73a49f8f..980f254a 100644 --- a/packages/node-opentelemetry/__tests__/instrumentations.test.ts +++ b/packages/node-opentelemetry/src/instrumentations/__tests__/instrumentations.test.ts @@ -1,11 +1,11 @@ import { PassThrough, Readable } from 'stream'; -import { _parseConsoleArgs } from '../src/instrumentations/console'; +import { _parseConsoleArgs } from '../console'; import { getShouldRecordBody, interceptReadableStream, splitCommaSeparatedStrings, -} from '../src/instrumentations/http'; +} from '../http'; describe('instrumentations', () => { describe('console', () => { diff --git a/packages/node-opentelemetry/src/instrumentations/console.ts b/packages/node-opentelemetry/src/instrumentations/console.ts index 2da0403a..8796223b 100644 --- a/packages/node-opentelemetry/src/instrumentations/console.ts +++ b/packages/node-opentelemetry/src/instrumentations/console.ts @@ -1,15 +1,15 @@ -import isObject from 'lodash.isobject'; -import isPlainObject from 'lodash.isplainobject'; import opentelemetry, { Attributes } from '@opentelemetry/api'; import { InstrumentationBase, InstrumentationConfig, InstrumentationNodeModuleDefinition, } from '@opentelemetry/instrumentation'; +import isObject from 'lodash.isobject'; +import isPlainObject from 'lodash.isplainobject'; +import { MutableAsyncLocalStorageContextManager } from '../MutableAsyncLocalStorageContextManager'; import { Logger, LoggerOptions } from '../otel-logger'; import { parseWinstonLog } from '../otel-logger/winston'; -import { MutableAsyncLocalStorageContextManager } from '../MutableAsyncLocalStorageContextManager'; const PACKAGE_NAME = '@hyperdx/instrumentation-console'; const PACKAGE_VERSION = '0.1.0'; diff --git a/packages/node-opentelemetry/src/instrumentations/http.ts b/packages/node-opentelemetry/src/instrumentations/http.ts index d79dd434..0bffab23 100644 --- a/packages/node-opentelemetry/src/instrumentations/http.ts +++ b/packages/node-opentelemetry/src/instrumentations/http.ts @@ -1,9 +1,8 @@ +import { diag, Span } from '@opentelemetry/api'; +import { headerCapture } from '@opentelemetry/instrumentation-http'; import * as http from 'http'; -import zlib from 'zlib'; import { PassThrough, Readable } from 'stream'; - -import { Span, diag } from '@opentelemetry/api'; -import { headerCapture } from '@opentelemetry/instrumentation-http'; +import zlib from 'zlib'; const SENSITIVE_DATA_SUBSTITUTE = '[Filtered]'; // https://github.com/getsentry/sentry-python/blob/1.18.0/sentry_sdk/scrubber.py#L17 diff --git a/packages/node-opentelemetry/src/logger.ts b/packages/node-opentelemetry/src/logger.ts index f7c862e8..2cd3c30a 100644 --- a/packages/node-opentelemetry/src/logger.ts +++ b/packages/node-opentelemetry/src/logger.ts @@ -5,11 +5,10 @@ import { DEFAULT_HDX_NODE_BETA_MODE, DEFAULT_SERVICE_NAME, } from './constants'; -import * as HyperDXPino from './otel-logger/pino'; -import HyperDXWinston from './otel-logger/winston'; - import type { HyperDXPinoOptions } from './otel-logger/pino'; +import * as HyperDXPino from './otel-logger/pino'; import type { HyperDXWinstonOptions } from './otel-logger/winston'; +import HyperDXWinston from './otel-logger/winston'; type WinstonTransportOptions = Omit< HyperDXWinstonOptions, diff --git a/packages/node-opentelemetry/src/otel-logger/__tests__/__snapshots__/index.test.ts.snap b/packages/node-opentelemetry/src/otel-logger/__tests__/__snapshots__/index.test.ts.snap new file mode 100644 index 00000000..413d417d --- /dev/null +++ b/packages/node-opentelemetry/src/otel-logger/__tests__/__snapshots__/index.test.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`otel-logger getSeverityNumber 1`] = ` +{ + "alert": 22, + "debug": 5, + "emerg": 23, + "error": 17, + "info": 9, + "verbose": 6, + "warn": 13, + "warning": 13, +} +`; + +exports[`otel-logger parseLogAttributes 1`] = ` +{ + "a": 1, + "b": "2", + "c": "[{"d":3}]", + "e": [ + 1, + 2, + 3, + ], + "f": [ + "a", + "b", + "c", + ], + "g": { + "h": "i", + }, +} +`; diff --git a/packages/node-opentelemetry/src/otel-logger/__tests__/index.test.ts b/packages/node-opentelemetry/src/otel-logger/__tests__/index.test.ts new file mode 100644 index 00000000..e0c0d6c2 --- /dev/null +++ b/packages/node-opentelemetry/src/otel-logger/__tests__/index.test.ts @@ -0,0 +1,31 @@ +import { getSeverityNumber, parseLogAttributes } from '..'; + +describe('otel-logger', () => { + it('getSeverityNumber', () => { + expect({ + alert: getSeverityNumber('alert'), + debug: getSeverityNumber('debug'), + emerg: getSeverityNumber('emerg'), + error: getSeverityNumber('error'), + info: getSeverityNumber('info'), + verbose: getSeverityNumber('verbose'), + warn: getSeverityNumber('warn'), + warning: getSeverityNumber('warning'), + }).toMatchSnapshot(); + }); + + it('parseLogAttributes', () => { + expect( + parseLogAttributes({ + a: 1, + b: '2', + c: [{ d: 3 }], + e: [1, 2, 3], + f: ['a', 'b', 'c'], + g: { + h: 'i', + }, + }), + ).toMatchSnapshot(); + }); +}); diff --git a/packages/node-opentelemetry/src/otel-logger/index.ts b/packages/node-opentelemetry/src/otel-logger/index.ts index 57556ae0..544239f9 100644 --- a/packages/node-opentelemetry/src/otel-logger/index.ts +++ b/packages/node-opentelemetry/src/otel-logger/index.ts @@ -1,22 +1,29 @@ import { Attributes, diag } from '@opentelemetry/api'; -import { getEnvWithoutDefaults } from '@opentelemetry/core'; import { - BatchLogRecordProcessor, - LoggerProvider, - NoopLogRecordProcessor, -} from '@opentelemetry/sdk-logs'; -import { Logger as OtelLogger, logs } from '@opentelemetry/api-logs'; + LogAttributes, + Logger as OtelLogger, + logs, + SeverityNumber, +} from '@opentelemetry/api-logs'; +import { getEnvWithoutDefaults } from '@opentelemetry/core'; import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'; import { - Resource, detectResourcesSync, envDetectorSync, hostDetectorSync, osDetectorSync, processDetector, + Resource, } from '@opentelemetry/resources'; +import { + BatchLogRecordProcessor, + LoggerProvider, + NoopLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; +import isPlainObject from 'lodash.isplainobject'; +import { version as PKG_VERSION } from '../../package.json'; import { DEFAULT_EXPORTER_BATCH_SIZE, DEFAULT_EXPORTER_TIMEOUT_MS, @@ -25,7 +32,7 @@ import { DEFAULT_SEND_INTERVAL_MS, DEFAULT_SERVICE_NAME, } from '../constants'; -import { version as PKG_VERSION } from '../../package.json'; +import { jsonToString } from '../utils'; const LOG_PREFIX = `⚠️ [LOGGER]`; @@ -41,6 +48,73 @@ export type LoggerOptions = { timeout?: number; // The read/write/connection timeout in milliseconds }; +// https://github.com/open-telemetry/opentelemetry-js-contrib/blob/afccd0d62a0ea81afb8f5609f3ee802c038d11c6/packages/winston-transport/src/utils.ts +const npmLevels: Record = { + error: SeverityNumber.ERROR, + warn: SeverityNumber.WARN, + info: SeverityNumber.INFO, + http: SeverityNumber.DEBUG3, + verbose: SeverityNumber.DEBUG2, + debug: SeverityNumber.DEBUG, + silly: SeverityNumber.TRACE, +}; + +const sysLoglevels: Record = { + emerg: SeverityNumber.FATAL3, + alert: SeverityNumber.FATAL2, + crit: SeverityNumber.FATAL, + error: SeverityNumber.ERROR, + warning: SeverityNumber.WARN, + notice: SeverityNumber.INFO2, + info: SeverityNumber.INFO, + debug: SeverityNumber.DEBUG, +}; + +const cliLevels: Record = { + error: SeverityNumber.ERROR, + warn: SeverityNumber.WARN, + help: SeverityNumber.INFO3, + data: SeverityNumber.INFO2, + info: SeverityNumber.INFO, + debug: SeverityNumber.DEBUG, + prompt: SeverityNumber.TRACE4, + verbose: SeverityNumber.TRACE3, + input: SeverityNumber.TRACE2, + silly: SeverityNumber.TRACE, +}; + +export function getSeverityNumber(level: string): SeverityNumber | undefined { + return npmLevels[level] ?? sysLoglevels[level] ?? cliLevels[level]; +} + +export const parseLogAttributes = ( + meta: Record, +): LogAttributes => { + try { + const attributes: LogAttributes = {}; + for (const key in meta) { + if (Object.prototype.hasOwnProperty.call(meta, key)) { + const value = meta[key]; + // stringify array of objects + if (Array.isArray(value)) { + const firstItem = value[0]; + if (isPlainObject(firstItem)) { + attributes[key] = jsonToString(value); + } + } + + if (attributes[key] === undefined) { + attributes[key] = value; + } + } + } + return attributes; + } catch (error) { + diag.error(`${LOG_PREFIX} Failed to parse log attributes. e = ${error}`); + return meta; + } +}; + export class Logger { private readonly _url: string; @@ -155,15 +229,18 @@ export class Logger { return this.processor.forceFlush(); } - postMessage(level: string, body: string, attributes: Attributes = {}): void { + postMessage( + level: string, + body: string, + meta: Record = {}, + ): void { this.logger.emit({ - // TODO: should map to otel severity number - severityNumber: 0, + severityNumber: getSeverityNumber(level), // TODO: set up the mapping between different downstream log levels severityText: level, body, - attributes, - timestamp: this.parseTimestamp(attributes), + attributes: parseLogAttributes(meta), + timestamp: this.parseTimestamp(meta), }); } } diff --git a/packages/node-opentelemetry/src/otel-logger/pino.ts b/packages/node-opentelemetry/src/otel-logger/pino.ts index e3cccc9d..ea5a6625 100644 --- a/packages/node-opentelemetry/src/otel-logger/pino.ts +++ b/packages/node-opentelemetry/src/otel-logger/pino.ts @@ -1,5 +1,3 @@ -import build from 'pino-abstract-transport'; -import isString from 'lodash.isstring'; import { Attributes, context, @@ -7,11 +5,12 @@ import { isSpanContextValid, trace, } from '@opentelemetry/api'; +import isString from 'lodash.isstring'; +import build from 'pino-abstract-transport'; -import { Logger } from './'; import { jsonToString } from '../utils'; - import type { LoggerOptions } from './'; +import { Logger } from './'; export type PinoLogLine = { level: number; diff --git a/packages/node-opentelemetry/src/otel-logger/winston.ts b/packages/node-opentelemetry/src/otel-logger/winston.ts index e16e8ab2..8f877c76 100644 --- a/packages/node-opentelemetry/src/otel-logger/winston.ts +++ b/packages/node-opentelemetry/src/otel-logger/winston.ts @@ -1,12 +1,11 @@ -import Transport from 'winston-transport'; +import { Attributes, diag } from '@opentelemetry/api'; import isPlainObject from 'lodash.isplainobject'; import isString from 'lodash.isstring'; -import { Attributes, diag } from '@opentelemetry/api'; +import Transport from 'winston-transport'; -import { Logger } from './'; import { jsonToString } from '../utils'; - import type { LoggerOptions } from './'; +import { Logger } from './'; export const parseWinstonLog = ( log: { diff --git a/packages/node-opentelemetry/src/otel.ts b/packages/node-opentelemetry/src/otel.ts index 332f03f4..5c3b0970 100644 --- a/packages/node-opentelemetry/src/otel.ts +++ b/packages/node-opentelemetry/src/otel.ts @@ -1,31 +1,27 @@ -import fetch from 'node-fetch'; -import path from 'path'; - -import * as semver from 'semver'; -import cliSpinners from 'cli-spinners'; -import ora from 'ora'; -import { wrap } from 'shimmer'; -import { Attributes, DiagLogLevel, diag } from '@opentelemetry/api'; import { ExceptionInstrumentation } from '@hyperdx/instrumentation-exception'; -import { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node'; import { SentryNodeInstrumentation } from '@hyperdx/instrumentation-sentry-node'; +import { Attributes, diag, DiagLogLevel } from '@opentelemetry/api'; +import { + getNodeAutoInstrumentations, + InstrumentationConfigMap, +} from '@opentelemetry/auto-instrumentations-node'; +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'; import { InstrumentationBase, InstrumentationModuleDefinition, } from '@opentelemetry/instrumentation'; -import { NodeSDK } from '@opentelemetry/sdk-node'; -import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'; +import { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node'; import { Resource } from '@opentelemetry/resources'; -import { - InstrumentationConfigMap, - getNodeAutoInstrumentations, -} from '@opentelemetry/auto-instrumentations-node'; import { MetricReader } from '@opentelemetry/sdk-metrics'; +import { NodeSDK } from '@opentelemetry/sdk-node'; +import cliSpinners from 'cli-spinners'; +import fetch from 'node-fetch'; +import ora from 'ora'; +import path from 'path'; +import * as semver from 'semver'; +import { wrap } from 'shimmer'; -import HyperDXConsoleInstrumentation from './instrumentations/console'; -import HyperDXSpanProcessor from './spanProcessor'; -import { Logger as OtelLogger } from './otel-logger'; -import { getHyperDXHTTPInstrumentationConfig } from './instrumentations/http'; +import { version as PKG_VERSION } from '../package.json'; import { DEFAULT_HDX_API_KEY, DEFAULT_HDX_NODE_ADVANCED_NETWORK_CAPTURE, @@ -36,8 +32,8 @@ import { DEFAULT_HDX_NODE_STOP_ON_TERMINATION_SIGNALS, DEFAULT_HDX_STARTUP_LOGS, DEFAULT_OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, - DEFAULT_OTEL_LOGS_EXPORTER, DEFAULT_OTEL_LOG_LEVEL, + DEFAULT_OTEL_LOGS_EXPORTER, DEFAULT_OTEL_METRICS_EXPORTER, DEFAULT_OTEL_METRICS_EXPORTER_URL, DEFAULT_OTEL_TRACES_EXPORTER, @@ -46,9 +42,12 @@ import { DEFAULT_OTEL_TRACES_SAMPLER_ARG, DEFAULT_SERVICE_NAME, } from './constants'; -import { MutableAsyncLocalStorageContextManager } from './MutableAsyncLocalStorageContextManager'; +import HyperDXConsoleInstrumentation from './instrumentations/console'; +import { getHyperDXHTTPInstrumentationConfig } from './instrumentations/http'; import { getHyperDXMetricReader } from './metrics'; -import { version as PKG_VERSION } from '../package.json'; +import { MutableAsyncLocalStorageContextManager } from './MutableAsyncLocalStorageContextManager'; +import { Logger as OtelLogger } from './otel-logger'; +import HyperDXSpanProcessor from './spanProcessor'; const UI_LOG_PREFIX = '[⚑HyperDX]'; diff --git a/packages/node-opentelemetry/src/spanProcessor.ts b/packages/node-opentelemetry/src/spanProcessor.ts index 54c35970..b8ea8595 100644 --- a/packages/node-opentelemetry/src/spanProcessor.ts +++ b/packages/node-opentelemetry/src/spanProcessor.ts @@ -1,8 +1,8 @@ -import { BatchSpanProcessor, Span } from '@opentelemetry/sdk-trace-base'; +import { Context } from '@opentelemetry/api'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'; +import { BatchSpanProcessor, Span } from '@opentelemetry/sdk-trace-base'; import type { MutableAsyncLocalStorageContextManager } from './MutableAsyncLocalStorageContextManager'; -import { Context } from '@opentelemetry/api'; export default class HyperDXSpanProcessor extends BatchSpanProcessor { private readonly enableHDXGlobalContext: boolean; diff --git a/packages/node-opentelemetry/src/utils.ts b/packages/node-opentelemetry/src/utils.ts index 5efe7a64..f7c22096 100644 --- a/packages/node-opentelemetry/src/utils.ts +++ b/packages/node-opentelemetry/src/utils.ts @@ -1,5 +1,5 @@ -import stringifySafe from 'json-stringify-safe'; import { diag } from '@opentelemetry/api'; +import stringifySafe from 'json-stringify-safe'; export const jsonToString = (json) => { try { diff --git a/packages/node-opentelemetry/tsconfig.release.json b/packages/node-opentelemetry/tsconfig.release.json index fa8fffa3..5afedf77 100644 --- a/packages/node-opentelemetry/tsconfig.release.json +++ b/packages/node-opentelemetry/tsconfig.release.json @@ -4,5 +4,6 @@ "sourceMap": false, "removeComments": true }, - "include": ["src/**/*", "bin/**/*"] + "include": ["src/**/*", "bin/**/*"], + "exclude": ["**/__tests__/**"] } diff --git a/yarn.lock b/yarn.lock index dc4630d4..ac92ece7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3573,6 +3573,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -7215,10 +7220,10 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^8.8.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" - integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== +eslint-config-prettier@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== eslint-plugin-jest@^27.2.1: version "27.9.0" @@ -7227,6 +7232,19 @@ eslint-plugin-jest@^27.2.1: dependencies: "@typescript-eslint/utils" "^5.10.0" +eslint-plugin-prettier@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz#d1c8f972d8f60e414c25465c163d16f209411f95" + integrity sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.9.1" + +eslint-plugin-simple-import-sort@^12.1.1: + version "12.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz#e64bfdaf91c5b98a298619aa634a9f7aa43b709e" + integrity sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== + eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -7551,6 +7569,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + fast-glob@3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" @@ -10983,7 +11006,7 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" -node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.9: +node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.9, node-fetch@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -11769,11 +11792,23 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@^2.7.1, prettier@^2.8.7: +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.7.1: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" + integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== + pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -13322,6 +13357,14 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +synckit@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.1.tgz#febbfbb6649979450131f64735aa3f6c14575c88" + integrity sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A== + dependencies: + "@pkgr/core" "^0.1.0" + tslib "^2.6.2" + tar-fs@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"