Skip to content

Commit e85be49

Browse files
committed
feat: parse log severity number/array of object attributes + setup linting
1 parent 6472326 commit e85be49

26 files changed

+327
-107
lines changed

.changeset/mighty-humans-sparkle.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hyperdx/node-opentelemetry': minor
3+
---
4+
5+
feat: use getSeverityNumber and parseLogAttributes for logger

package.json

+11-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818
"prepare": "husky install"
1919
},
2020
"lint-staged": {
21-
"**/*": "prettier --write --ignore-unknown"
21+
"**/*.{ts,tsx}": [
22+
"prettier --write --ignore-unknown",
23+
"eslint --fix"
24+
],
25+
"**/*.{json,yml}": [
26+
"prettier --write --ignore-unknown"
27+
]
2228
},
2329
"devDependencies": {
2430
"@changesets/cli": "^2.26.1",
@@ -29,13 +35,15 @@
2935
"@typescript-eslint/eslint-plugin": "^5.59.9",
3036
"@typescript-eslint/parser": "^5.59.9",
3137
"eslint": "^8.42.0",
32-
"eslint-config-prettier": "^8.8.0",
38+
"eslint-config-prettier": "^9.1.0",
3339
"eslint-plugin-jest": "^27.2.1",
40+
"eslint-plugin-prettier": "^5.2.1",
41+
"eslint-plugin-simple-import-sort": "^12.1.1",
3442
"husky": "^8.0.3",
3543
"jest": "^29.5.0",
3644
"lint-staged": "^13.2.2",
3745
"nx": "^15.9.2",
38-
"prettier": "^2.8.7",
46+
"prettier": "^3.3.3",
3947
"rimraf": "^5.0.1",
4048
"ts-jest": "^29.1.0",
4149
"ts-node": "^10.9.1",

packages/node-opentelemetry/.eslintrc.json

+7-8
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@
1010
"sourceType": "module",
1111
"ecmaVersion": 2020
1212
},
13-
"plugins": ["@typescript-eslint", "jest"],
13+
"plugins": ["@typescript-eslint", "jest", "prettier", "simple-import-sort"],
1414
"extends": [
1515
"eslint:recommended",
1616
"plugin:@typescript-eslint/recommended",
1717
"plugin:jest/recommended",
18-
"prettier"
18+
"plugin:prettier/recommended"
1919
],
2020
"rules": {
21-
// The following rule is enabled only to supplement the inline suppression
22-
// examples, and because it is not a recommended rule, you should either
23-
// disable it, or understand what it enforces.
24-
// https://typescript-eslint.io/rules/explicit-function-return-type/
25-
"@typescript-eslint/explicit-function-return-type": "warn",
2621
"@typescript-eslint/ban-ts-comment": "warn",
27-
"@typescript-eslint/no-this-alias": "warn"
22+
"@typescript-eslint/explicit-function-return-type": "warn",
23+
"@typescript-eslint/no-this-alias": "warn",
24+
"prettier/prettier": "error",
25+
"simple-import-sort/exports": "error",
26+
"simple-import-sort/imports": "error"
2827
}
2928
}

packages/node-opentelemetry/__tests__/otel.test.ts

-15
This file was deleted.

packages/node-opentelemetry/bin/opentelemetry-instrument.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env node
22

3-
import process from 'process';
43
import fs from 'fs';
4+
import process from 'process';
55
import { promisify } from 'util';
66

77
const realpath = promisify(fs.realpath);

packages/node-opentelemetry/examples/dummy.js

+19-11
Original file line numberDiff line numberDiff line change
@@ -292,22 +292,30 @@ app.get('/instruments', async (req, res) => {
292292
});
293293

294294
app.get('/logs', async (req, res) => {
295-
console.debug({
295+
const nestedObj = {
296296
headers: req.headers,
297297
method: req.method,
298298
url: req.url,
299-
query: req.query,
299+
nested: [
300+
{
301+
foo: 'bar',
302+
},
303+
],
304+
nested2: {
305+
nested3: {
306+
foo: 'bar',
307+
},
308+
},
309+
};
310+
console.error({
311+
message: 'Console 🍕',
312+
...nestedObj,
300313
});
301-
console.error('BANG !!!');
302-
console.log('Console 🍕');
303-
logger.info({
304-
message: 'Winston 🍕',
305-
headers: req.headers,
306-
method: req.method,
307-
url: req.url,
314+
logger.info('Winston 🍕', nestedObj);
315+
pinoLogger.info({
316+
message: 'Pino 🍕',
317+
...nestedObj,
308318
});
309-
pinoLogger.info('Pino 🍕');
310-
311319
bunyanLogger.info('Bunyan 🍕');
312320

313321
console.log(await sendGetRequest());

packages/node-opentelemetry/jest.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const config: Config = {
99
moduleNameMapper: {
1010
'^(\\.{1,2}/.*)\\.(m)?js$': '$1',
1111
},
12+
modulePathIgnorePatterns: ['<rootDir>/build/'],
1213
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(m)?ts$',
1314
coverageDirectory: 'coverage',
1415
collectCoverageFrom: [

packages/node-opentelemetry/src/MutableAsyncLocalStorageContextManager.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import { Context, ROOT_CONTEXT } from '@opentelemetry/api';
1818
import { AsyncLocalStorage } from 'async_hooks';
19+
1920
import { AbstractAsyncHooksContextManager } from './AbstractAsyncHooksContextManager';
2021

2122
type MutableContextStore = {

packages/node-opentelemetry/__tests__/logger.test.ts renamed to packages/node-opentelemetry/src/__tests__/logger.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import winston from 'winston';
22

3-
import { getWinstonTransport } from '../src/logger';
3+
import { getWinstonTransport } from '../logger';
44

55
const MAX_LEVEL = 'info';
66

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { init, initSDK, shutdown } from '../otel';
2+
3+
describe('otel', () => {
4+
it('can sucessively shutdown without initialization', () => {
5+
shutdown();
6+
shutdown();
7+
});
8+
9+
it('should be able to initialize the SDK with initSDK', async () => {
10+
initSDK({
11+
apiKey: 'blabla',
12+
advancedNetworkCapture: true,
13+
consoleCapture: true,
14+
});
15+
16+
await new Promise((resolve) => setTimeout(resolve, 1000));
17+
18+
shutdown();
19+
});
20+
21+
it('should be able to initialize the SDK with init', async () => {
22+
init({
23+
apiKey: 'blabla',
24+
});
25+
26+
await new Promise((resolve) => setTimeout(resolve, 1000));
27+
28+
shutdown();
29+
});
30+
});

packages/node-opentelemetry/src/constants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { getEnv, getEnvWithoutDefaults } from '@opentelemetry/core';
12
import { defaultServiceName } from '@opentelemetry/resources';
2-
import { getEnvWithoutDefaults, getEnv } from '@opentelemetry/core';
33

44
import { stringToBoolean } from './utils';
55

packages/node-opentelemetry/src/gcp.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import { context, SpanKind, trace } from '@opentelemetry/api';
12
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
2-
import { SpanKind, context, trace } from '@opentelemetry/api';
33

4-
import { SDKConfig, initSDK } from './otel';
54
import { name as PKG_NAME, version as PKG_VERSION } from '../package.json';
5+
import { initSDK, SDKConfig } from './otel';
66

77
export const registerGCPCloudFunctionEventHandler = (
88
handler: (event: any) => Promise<void>,

packages/node-opentelemetry/__tests__/instrumentations.test.ts renamed to packages/node-opentelemetry/src/instrumentations/__tests__/instrumentations.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { PassThrough, Readable } from 'stream';
22

3-
import { _parseConsoleArgs } from '../src/instrumentations/console';
3+
import { _parseConsoleArgs } from '../console';
44
import {
55
getShouldRecordBody,
66
interceptReadableStream,
77
splitCommaSeparatedStrings,
8-
} from '../src/instrumentations/http';
8+
} from '../http';
99

1010
describe('instrumentations', () => {
1111
describe('console', () => {

packages/node-opentelemetry/src/instrumentations/console.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import isObject from 'lodash.isobject';
2-
import isPlainObject from 'lodash.isplainobject';
31
import opentelemetry, { Attributes } from '@opentelemetry/api';
42
import {
53
InstrumentationBase,
64
InstrumentationConfig,
75
InstrumentationNodeModuleDefinition,
86
} from '@opentelemetry/instrumentation';
7+
import isObject from 'lodash.isobject';
8+
import isPlainObject from 'lodash.isplainobject';
99

10+
import { MutableAsyncLocalStorageContextManager } from '../MutableAsyncLocalStorageContextManager';
1011
import { Logger, LoggerOptions } from '../otel-logger';
1112
import { parseWinstonLog } from '../otel-logger/winston';
12-
import { MutableAsyncLocalStorageContextManager } from '../MutableAsyncLocalStorageContextManager';
1313

1414
const PACKAGE_NAME = '@hyperdx/instrumentation-console';
1515
const PACKAGE_VERSION = '0.1.0';

packages/node-opentelemetry/src/instrumentations/http.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1+
import { diag, Span } from '@opentelemetry/api';
2+
import { headerCapture } from '@opentelemetry/instrumentation-http';
13
import * as http from 'http';
2-
import zlib from 'zlib';
34
import { PassThrough, Readable } from 'stream';
4-
5-
import { Span, diag } from '@opentelemetry/api';
6-
import { headerCapture } from '@opentelemetry/instrumentation-http';
5+
import zlib from 'zlib';
76

87
const SENSITIVE_DATA_SUBSTITUTE = '[Filtered]';
98
// https://github.com/getsentry/sentry-python/blob/1.18.0/sentry_sdk/scrubber.py#L17

packages/node-opentelemetry/src/logger.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import {
55
DEFAULT_HDX_NODE_BETA_MODE,
66
DEFAULT_SERVICE_NAME,
77
} from './constants';
8-
import * as HyperDXPino from './otel-logger/pino';
9-
import HyperDXWinston from './otel-logger/winston';
10-
118
import type { HyperDXPinoOptions } from './otel-logger/pino';
9+
import * as HyperDXPino from './otel-logger/pino';
1210
import type { HyperDXWinstonOptions } from './otel-logger/winston';
11+
import HyperDXWinston from './otel-logger/winston';
1312

1413
type WinstonTransportOptions = Omit<
1514
HyperDXWinstonOptions,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`otel-logger getSeverityNumber 1`] = `
4+
{
5+
"alert": 22,
6+
"debug": 5,
7+
"emerg": 23,
8+
"error": 17,
9+
"fatal": undefined,
10+
"info": 9,
11+
"verbose": 6,
12+
"warn": 13,
13+
"warning": 13,
14+
}
15+
`;
16+
17+
exports[`otel-logger parseLogAttributes 1`] = `
18+
{
19+
"a": 1,
20+
"b": "2",
21+
"c": "[{"d":3}]",
22+
"e": [
23+
1,
24+
2,
25+
3,
26+
],
27+
"f": [
28+
"a",
29+
"b",
30+
"c",
31+
],
32+
"g": {
33+
"h": "i",
34+
},
35+
}
36+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { getSeverityNumber, parseLogAttributes } from '..';
2+
3+
describe('otel-logger', () => {
4+
it('getSeverityNumber', () => {
5+
expect({
6+
alert: getSeverityNumber('alert'),
7+
debug: getSeverityNumber('debug'),
8+
emerg: getSeverityNumber('emerg'),
9+
error: getSeverityNumber('error'),
10+
info: getSeverityNumber('info'),
11+
verbose: getSeverityNumber('verbose'),
12+
warn: getSeverityNumber('warn'),
13+
warning: getSeverityNumber('warning'),
14+
}).toMatchSnapshot();
15+
});
16+
17+
it('parseLogAttributes', () => {
18+
expect(
19+
parseLogAttributes({
20+
a: 1,
21+
b: '2',
22+
c: [{ d: 3 }],
23+
e: [1, 2, 3],
24+
f: ['a', 'b', 'c'],
25+
g: {
26+
h: 'i',
27+
},
28+
}),
29+
).toMatchSnapshot();
30+
});
31+
});

0 commit comments

Comments
 (0)