Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom json replacer function - addresses issues #46 #47

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/buffer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const send = async (lines: LogDNALogLine[]) => {
Authorization: `Basic ${btoa(`${opts.ingestionKey}:`)}`,
'Content-Type': 'application/json',
},
body: utils.stringify({ lines }),
body: utils.stringify({ lines }, opts.jsonReplacer),
});

if (response.ok) {
Expand Down
2 changes: 1 addition & 1 deletion src/capture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const generateLogLine = ({ level = 'log', message, lineContext = {}, errorContex
process({
timestamp: Math.floor(Date.now() / 1000),
app: opts.app || window.location.host,
line: typeof data.message === 'string' ? data.message : utils.stringify(data.message),
line: typeof data.message === 'string' ? data.message : utils.stringify(data.message, opts.jsonReplacer),
level: data.level,
meta: {
sessionId: getSessionId(),
Expand Down
5 changes: 3 additions & 2 deletions src/logdna.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GlobalErrorHandlerPlugin } from './plugins/global-handler';
declare module 'logdna-browser-2' { }
declare module 'logdna-browser-2' {}

interface LogDNAMethods { }
interface LogDNAMethods {}

// This is fallback to 3rd party plugin methods
// Until TS has better Module Augmentation without
Expand Down Expand Up @@ -54,6 +54,7 @@ export type LogDNABrowserOptions = {
ingestionKey?: string;
hooks?: HooksOption;
internalErrorLogger?: Function;
jsonReplacer?: (key: string, value: any) => any | undefined;
};

export type LineContext = object;
Expand Down
5 changes: 3 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import safeStringify from 'fast-safe-stringify';
import { HOSTNAME_CHECK, DEFAULT_TAG, SESSION_SCORE_KEY } from './constants';
import { getOptions } from './init';

import { Tags } from './logdna';

Expand All @@ -17,7 +18,7 @@ const parseTags = (tags: Tags = []) => {
return [DEFAULT_TAG, ...tags].filter(tag => tag !== '').join(',');
};

const stringify = (obj: unknown) => safeStringify(obj);
const stringify = (obj: unknown, replacer?: ((key: string, value: any) => any) | undefined) => safeStringify(obj, replacer);

const getStackTrace = () => {
const stack = new Error().stack || '';
Expand Down Expand Up @@ -48,7 +49,7 @@ const _randomBetween = (min: number, max: number) => {
const backOffWithJitter = (base: number, cap: number, lastSleep: number) => Math.min(cap, _randomBetween(base, lastSleep * 3));

const jsonByteSize = (obj: unknown) => {
const stringified = stringify(obj);
const stringified = stringify(obj, getOptions().jsonReplacer);
if (window.TextEncoder) {
return new TextEncoder().encode(stringified).length;
}
Expand Down
11 changes: 11 additions & 0 deletions tests/init.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ describe('init.ts', () => {
expect(addDefaultPlugins).toHaveBeenCalled();
expect(addPluginMethods).toHaveBeenCalled();
});

it('should add the JSON replacer', () => {
let jsonReplacer = (key: string, value: any) => {
if (key === 'password') {
return '[redacted]';
}
return value;
};
config(INGESTION_KEY, { jsonReplacer });
expect(getOptions().jsonReplacer).toEqual(jsonReplacer);
});
});

describe('init', () => {
Expand Down
13 changes: 13 additions & 0 deletions tests/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ describe('Utils', () => {
};
expect(utils.stringify(encode)).toEqual('{"data":{"obj":{"obj":"[Circular]"}}}');
});
it('should properly use the JSON replacer function', () => {
let obj: any = {
email: '[email protected]',
password: 'SuperSecretPassword',
};
let jsonReplacer = (key: string, value: any) => {
if (key === 'password') {
return '[redacted]';
}
return value;
};
expect(utils.stringify(obj, jsonReplacer)).toEqual('{"email":"[email protected]","password":"[redacted]"}');
});
});

describe('jsonByteSize', () => {
Expand Down