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

Commit

Permalink
✨ Add sentry transform stream
Browse files Browse the repository at this point in the history
Related: #28
  • Loading branch information
smolijar committed Nov 22, 2019
1 parent 36f52c2 commit 1ef451b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 19 deletions.
9 changes: 5 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ const defaultLogger = (options: AckeeLoggerOptions & { loggerName?: string } = {
serializers.disablePaths(options.disableFields);
serializers.enablePaths(options.enableFields);

if (options.sentryDsn) {
// Check library is available
require('@sentry/node');
}

const isTesting = process.env.NODE_ENV === 'test';
const defaultLevel: Level = options.defaultLevel || (isTesting ? 'silent' : 'debug');
const messageKey = 'message'; // best option for Google Stackdriver,
Expand All @@ -91,10 +96,6 @@ const defaultLogger = (options: AckeeLoggerOptions & { loggerName?: string } = {
(pinoms as any).multistream(streams)
) as PinoLogger) as AckeeLogger;

if (options.sentryDsn) {
const sentry = require('@sentry/node');
}

// Add maxLevel support to pino-multi-stream
// This could be replaced with custom pass-through stream being passed to multistream, which would filter the messages
const loggerStream = (logger as any)[(pino as any).symbols.streamSym] as any;
Expand Down
13 changes: 13 additions & 0 deletions src/sentry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Transform, TransformCallback } from 'stream';
import { captureException } from '@sentry/node';

class SentryTransformStream extends Transform {
// tslint:disable-next-line:function-name
public _transform(chunk: any, _encoding: string, callback: TransformCallback) {
const obj = JSON.parse(chunk);
captureException(obj);
this.push(chunk);
callback();
}
}
export { SentryTransformStream };
6 changes: 6 additions & 0 deletions src/streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { loggerNameKey, pkgVersionKey } from '.';
import { AckeeLoggerOptions, AckeeLoggerStream } from './interfaces';
import { levels } from './levels';
import { StackDriverFormatStream } from './stackdriver';
import { SentryTransformStream } from './sentry';

const pkgJson = JSON.parse(fs.readFileSync(path.resolve(path.join(__dirname, '..', 'package.json')), 'utf8'));

Expand Down Expand Up @@ -71,6 +72,11 @@ const initLoggerStreams = (
}

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

if (options.sentryDsn) {
streams = decorateStreams(streams, SentryTransformStream);
}

return streams;
};

Expand Down
47 changes: 41 additions & 6 deletions src/tests/sentry-mocked.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
import loggerFactory from '..';
import { testWriteStream } from './utils';
import { setContext } from '@sentry/core';

jest.mock('@sentry/node', () => {});
let loggerFactory;
const captureException = jest.fn();
const captureMessage = jest.fn();

test('can create logger with options', () => {
expect(() => loggerFactory()).not.toThrowError();
expect(() => loggerFactory({ sentryDsn: 'DSN' })).not.toThrowError();
});
describe('sentry mocked', () => {
beforeAll(() => {
jest.mock('@sentry/node', () => {
return {
captureException,
};
});
loggerFactory = require('..').default;
});
test('can create logger with options', () => {
expect(() => loggerFactory()).not.toThrowError();
expect(() => loggerFactory({ sentryDsn: 'DSN' })).not.toThrowError();
});

test('can use custom stream', async () => {
await new Promise((resolve, reject) => {
const logger = loggerFactory({
sentryDsn: 'DSN',
});
captureException.mockImplementation(x => {
resolve();
console.log({ captureException: x });
});
logger.info('Foo');
});
expect(captureException.mock.calls[0]).toMatchInlineSnapshot(`
Array [
Object {
"level": 30,
"message": "Foo",
"v": 1,
},
]
`);
});
});
21 changes: 12 additions & 9 deletions src/tests/sentry.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import loggerFactory from '..';

jest.mock('@sentry/node', () => {
throw new Error("Cannot find module '@sentry/node' from 'index.ts'");
describe('sentry not available', () => {
beforeAll(() => {
jest.mock('@sentry/node', () => {
throw new Error("Cannot find module '@sentry/node' from 'index.ts'");
});
});
test('without sentry lib works by default, but crashes on provided', () => {
expect(() => loggerFactory()).not.toThrowError();
expect(() => loggerFactory({ sentryDsn: 'DSN' })).toThrowErrorMatchingInlineSnapshot(
`"Cannot find module '@sentry/node' from 'index.ts'"`
);
});
});

test('without sentry lib works by default, but crashes on provided', () => {
expect(() => loggerFactory()).not.toThrowError();
expect(() => loggerFactory({ sentryDsn: 'DSN' })).toThrowErrorMatchingInlineSnapshot(
`"Cannot find module '@sentry/node' from 'index.ts'"`
);
});

0 comments on commit 1ef451b

Please sign in to comment.