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

Commit

Permalink
✨ Add sentry level
Browse files Browse the repository at this point in the history
Related: #28
  • Loading branch information
smolijar committed Dec 5, 2019
1 parent 90ba71c commit e8b149e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ export interface CosmasOptions {
config?: LoggerOptions;
pretty?: boolean;
sentry?: string | boolean;
sentryLevel?: pino.LevelWithSilent;
skip?: (req: Request, res?: Response) => boolean;
}
33 changes: 19 additions & 14 deletions src/sentry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { captureException, captureMessage, Severity, withScope } from '@sentry/node';
import { Transform, TransformCallback } from 'stream';
import { CosmasOptions } from './interfaces';
import { levels } from './levels';

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

class SentryTransformStream extends Transform {
// tslint:disable-next-line:function-name
public _transform(chunk: any, _encoding: string, callback: TransformCallback) {
const obj = JSON.parse(chunk);
withScope(scope => {
scope.setLevel(PINO_TO_SENTRY[obj.level]);
scope.setExtras(obj);
reportToSentry(obj);
});
this.push(chunk);
callback();
}
}
export { SentryTransformStream };
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 ((options.sentryLevel || levels.warn) <= obj.level) {
withScope(scope => {
scope.setLevel(PINO_TO_SENTRY[obj.level]);
scope.setExtras(obj);
reportToSentry(obj);
});
}
this.push(chunk);
callback();
}
};
};
4 changes: 2 additions & 2 deletions src/streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ const initLoggerStreams = (
streams = decorateStreams(streams, getDefaultTransformStream(options));

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

return streams;
Expand Down
23 changes: 16 additions & 7 deletions src/tests/sentry-mocked.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { levels } from '../levels';

let loggerFactory;
const scope: any = {};
const withScope = jest.fn(fn =>
Expand Down Expand Up @@ -60,31 +62,38 @@ describe('sentry mocked', () => {
`);
});

test('sentry captureMessage is called with correct scope', async () => {
test('sentry captureMessage is called with correct scope (respects sentry level)', async () => {
await new Promise((resolve, reject) => {
const logger = loggerFactory({
sentry: 'DSN',
sentryLevel: levels.fatal,
});
captureMessage.mockImplementation(createCapture(resolve));
logger.info('Foo');
// expect to trigger only fatal
logger.trace('trace');
logger.debug('debug');
logger.info('info');
logger.warn('warn');
logger.error('error');
logger.fatal('fatal');
});
expect(captureMessage).toHaveBeenCalledTimes(1);
expect(captureException).not.toHaveBeenCalled();
expect(captureMessage.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"Foo",
"fatal",
]
`);
expect(captureMessage.mock.results[0].value).toMatchInlineSnapshot(`
Object {
"data": "Foo",
"data": "fatal",
"scope": Object {
"extras": Object {
"level": 30,
"message": "Foo",
"level": 60,
"message": "fatal",
"v": 1,
},
"level": "info",
"level": "critical",
},
}
`);
Expand Down

0 comments on commit e8b149e

Please sign in to comment.