Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Merge 6ff3d88 into d39799d
Browse files Browse the repository at this point in the history
  • Loading branch information
vlasy committed Sep 22, 2020
2 parents d39799d + 6ff3d88 commit 12ac765
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 47 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
"dependencies": {
"@types/express": "^4.16.0",
"@types/pino": "^6.0.0",
"@types/pino": "^6.3.1",
"lodash.foreach": "^4.5.0",
"lodash.isempty": "^4.4.0",
"lodash.isobject": "^3.0.2",
Expand All @@ -40,7 +40,7 @@
"on-finished": "^2.3.0",
"on-headers": "^1.0.1",
"pick-deep": "^1.0.0",
"pino": "^6.2.0",
"pino": "^6.6.1",
"pino-multi-stream": "^5.0.0"
},
"peerDependencies": {
Expand Down
9 changes: 1 addition & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,6 @@ const defaultLogger = (options: CosmasOptions & { loggerName?: string } = {}): C
serializers.disablePaths(options.disableFields);
serializers.enablePaths(options.enableFields);

if (options.sentry) {
const sentry = require('@sentry/node');
if (typeof options.sentry === 'string') {
sentry.init({ dsn: options.sentry });
}
}

const isTesting = process.env.NODE_ENV === 'test';
const defaultLevel: Level = options.defaultLevel || (isTesting ? 'silent' : 'debug');
const messageKey = 'message'; // best option for Google Stackdriver,
Expand Down Expand Up @@ -202,6 +195,6 @@ const loggerFactory = (data: string | CosmasOptions = {}, loggerOptions: CosmasO
return loggerProxy;
};

const factoryProxy = makeCallable(loggerFactory(), loggerFactory);
const factoryProxy: CosmasFactory = makeCallable(loggerFactory(), loggerFactory);

export default factoryProxy;
2 changes: 0 additions & 2 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export interface CosmasOptions {
ignoredHttpMethods?: string[];
config?: LoggerOptions;
pretty?: boolean;
sentry?: string | boolean;
sentryLevel?: pino.LevelWithSilent;
loggerName?: string;
skip?: (req: Request, res?: Response) => boolean;
}
37 changes: 20 additions & 17 deletions src/sentry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { captureException, captureMessage, Severity, withScope } from '@sentry/node';
import { Transform, TransformCallback } from 'stream';
import { CosmasOptions } from './interfaces';
import * as pino from 'pino';
import { Cosmas } from '.';
import { levels } from './levels';

const reportToSentry = (obj: any) => {
Expand All @@ -23,20 +23,23 @@ const PINO_TO_SENTRY: { [key: number]: Severity } = {
60: Severity.Critical,
};

export const createSentryTransformStream = (options: CosmasOptions): any => {
return class SentryTransformStream extends Transform {
// tslint:disable-next-line:function-name
public _transform(chunk: any, _encoding: string, callback: TransformCallback) {
const obj = JSON.parse(chunk);
if (obj.level >= (options.sentryLevel || levels.warn)) {
withScope((scope) => {
scope.setLevel(PINO_TO_SENTRY[obj.level]);
scope.setExtras(obj);
reportToSentry(obj);
});
}
this.push(chunk);
callback();
}
export const extendSentry = (logger: Cosmas, options: { sentry: string | true; sentryLevel: number }) => {
const sentry = require('@sentry/node');
if (typeof options.sentry === 'string') {
sentry.init({ dsn: options.sentry });
}

const originalWrite = (logger as any)[pino.symbols.streamSym].write;
// unfortunately, this is the only place in pino, we can hook onto, where we can be sure all
// the hooks, formatters and serializers are already applied
(logger as any)[pino.symbols.streamSym].write = function (s: string) {
originalWrite.call(this, s);
const obj = JSON.parse(s);
if (obj.level < (options.sentryLevel || levels.warn)) return;
withScope((scope) => {
scope.setLevel(PINO_TO_SENTRY[obj.level]);
scope.setExtras(obj);
reportToSentry(obj);
});
};
};
5 changes: 0 additions & 5 deletions src/streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ const initLoggerStreams = (

streams = decorateStreams(streams, getDefaultTransformStream(options));

if (options.sentry) {
const { createSentryTransformStream } = require('./sentry');
streams = decorateStreams(streams, createSentryTransformStream(options));
}

return streams;
};

Expand Down
4 changes: 2 additions & 2 deletions src/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,14 @@ test('Child logger takes parent config', () => {
});

test('Child logger inherits parent name', () => {
const logger = loggerFactory('parent', { disableStackdriverFormat: true });
const logger = loggerFactory('parent');
const childLogger = logger('child');

expect(childLogger.options.loggerName).toBe('parentchild');
});

test('Child logger can create another child', () => {
const logger = loggerFactory('parent', { disableStackdriverFormat: true });
const logger = loggerFactory('parent');
const childLogger = logger('child');
const kid = childLogger('grandkid');

Expand Down
17 changes: 10 additions & 7 deletions src/tests/sentry-mocked.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import omit = require('omit-deep');
import { CosmasFactory } from '../index';
import { levels } from '../levels';

let loggerFactory;
let loggerFactory: CosmasFactory;
let extendSentry;
const scope: any = {};
const withScope = jest.fn((fn) =>
fn({
Expand Down Expand Up @@ -44,16 +46,17 @@ describe('sentry mocked', () => {
};
});
loggerFactory = require('../index').default;
extendSentry = require('../sentry').extendSentry;
});
beforeEach(() => {
captureException.mockReset();
captureMessage.mockReset();
});
test('can create logger with options', () => {
expect(() => loggerFactory()).not.toThrowError();
expect(() => loggerFactory({ sentry: true })).not.toThrowError();
expect(() => extendSentry(loggerFactory, { sentry: true })).not.toThrowError();
expect(init).not.toHaveBeenCalled();
expect(() => loggerFactory({ sentry: 'dummy' })).not.toThrowError();
expect(() => extendSentry(loggerFactory, { sentry: 'dummy' })).not.toThrowError();
expect(init.mock.calls[0]).toMatchInlineSnapshot(`
Array [
Object {
Expand All @@ -67,7 +70,8 @@ describe('sentry mocked', () => {
const dateNow = Date.now;
Date.now = jest.fn(() => 1520343036000);
await new Promise((resolve, reject) => {
const logger = loggerFactory({
const logger = loggerFactory();
extendSentry(logger, {
sentry: 'DSN',
sentryLevel: levels.fatal,
});
Expand Down Expand Up @@ -107,9 +111,8 @@ Object {

test('sentry captureException with stack and correct levels', async () => {
await new Promise((resolve, reject) => {
const logger = loggerFactory({
sentry: 'DSN',
});
const logger = loggerFactory();
extendSentry(logger, { sentry: 'DSN' });
captureException.mockReset();
captureException.mockImplementation(createCapture(resolve));
logger.error(new Error());
Expand Down
9 changes: 5 additions & 4 deletions src/tests/sentry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import loggerFactory from '../index';
describe('sentry not available', () => {
beforeAll(() => {
jest.mock('@sentry/node', () => {
throw new Error("Cannot find module '@sentry/node' from 'index.ts'");
throw new Error("Cannot find module '@sentry/node' from 'sentry.ts'");
});
});
test('without sentry lib works by default, but crashes on provided', () => {
expect(() => loggerFactory()).not.toThrowError();
expect(() => loggerFactory({ sentry: 'DSN' })).toThrowErrorMatchingInlineSnapshot(
`"Cannot find module '@sentry/node' from 'index.ts'"`
);
expect(() => {
const extendSentry = require('../sentry').extendSentry;
extendSentry(loggerFactory);
}).toThrowErrorMatchingInlineSnapshot(`"Cannot find module '@sentry/node' from 'sentry.ts'"`);
});
});

0 comments on commit 12ac765

Please sign in to comment.