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

feat: useLogger API #12

Merged
merged 1 commit into from
Nov 28, 2023
Merged
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
32 changes: 28 additions & 4 deletions src/decorator/Bunyamin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { deflateCategories, mergeCategories } from './categories';
import { isActionable, isError, isObject, isPromiseLike } from '../utils';
import { isSelfDebug } from '../is-debug';
import type { ThreadGroupConfig } from '../streams';
import type { ThreadID } from '../types';
import { isActionable, isError, isObject, isPromiseLike } from '../utils';
import type {
BunyaminLogMethod,
BunyaminConfig,
Expand All @@ -10,6 +11,7 @@
BunyanLogLevel,
} from './types';
import { MessageStack } from './message-stack';
import { StackTraceError } from './StackTraceError';

export class Bunyamin<Logger extends BunyanLikeLogger = BunyanLikeLogger> {
public readonly fatal = this.#setupLogMethod('fatal');
Expand All @@ -33,7 +35,7 @@
this.#fields = undefined;
this.#shared = {
...config,
threadGroups: config.threadGroups ?? [],
loggerPriority: 0,
messageStack: new MessageStack({
noBeginMessage: config.noBeginMessage,
}),
Expand All @@ -44,15 +46,20 @@
}
}

/** @deprecated */

Check warning on line 49 in src/decorator/Bunyamin.ts

View workflow job for this annotation

GitHub Actions / Lint

Missing JSDoc @returns declaration
get threadGroups(): ThreadGroupConfig[] {
return this.#shared.threadGroups!;
return [];
}

get logger(): Logger {
return this.#shared.logger;
}

set logger(logger: Logger) {
this.useLogger(logger);
}

useLogger(logger: Logger, priority = 0): void {
if (this.#shared.immutable) {
throw new Error('Cannot change a logger of an immutable instance');
}
Expand All @@ -61,7 +68,23 @@
throw new Error('Cannot change a logger of a child instance');
}

this.#shared.logger = logger;
const { stack } = isSelfDebug() ? new StackTraceError() : StackTraceError.empty();
const currentPriority = this.#shared.loggerPriority;
if (priority >= currentPriority) {
this.#shared.loggerPriority = priority;
this.#shared.logger = logger;
stack &&
this.#shared.logger.trace(
{ cat: 'bunyamin' },
`bunyamin logger changed (${priority} >= ${currentPriority}), caller was:\n${stack}`,
);
} else {
stack &&
this.#shared.logger.trace(
{ cat: 'bunyamin' },
`bunyamin logger not changed (${priority} < ${currentPriority}), caller was:\n${stack}`,
);
}
}

child(overrides?: UserFields): Bunyamin<Logger> {
Expand Down Expand Up @@ -226,5 +249,6 @@
};

type SharedBunyaminConfig<Logger extends BunyanLikeLogger> = BunyaminConfig<Logger> & {
loggerPriority: number;
messageStack: MessageStack;
};
14 changes: 14 additions & 0 deletions src/decorator/StackTraceError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export class StackTraceError extends Error {
constructor() {
super('Providing stack trace below:');
// eslint-disable-next-line unicorn/custom-error-definition
this.name = 'StackTrace';
}

static empty() {
return {
message: '',
stack: '',
};
}
}
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ export * from './noopLogger';
export * from './traceEventStream';
export * from './uniteTraceEvents';
export * from './wrapLogger';
export * from './is-debug';
export { isDebug } from './is-debug';

export const bunyamin = realm.bunyamin;
export const nobunyamin = realm.nobunyamin;
export const threadGroups = realm.threadGroups;

export default bunyamin;
2 changes: 2 additions & 0 deletions src/is-debug/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { createIsDebug } from './createIsDebug';

export const isDebug = createIsDebug(process.env.DEBUG || '');

export const isSelfDebug = () => isDebug('bunyamin');
30 changes: 21 additions & 9 deletions src/realm.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import type { BunyanLikeLogger } from './decorator';
import { Bunyamin } from './decorator';
import { noopLogger } from './noopLogger';
import { isSelfDebug } from './is-debug';
import { ThreadGroups } from './thread-groups';

type Realm = {
bunyamin: Bunyamin<BunyanLikeLogger>;
nobunyamin: Bunyamin<BunyanLikeLogger>;
bunyamin: Bunyamin;
nobunyamin: Bunyamin;
threadGroups: ThreadGroups;
};

function create() {
const threadGroups: any[] = [];
const bunyamin = new Bunyamin<BunyanLikeLogger>({ logger: noopLogger(), threadGroups });
const nobunyamin = new Bunyamin<BunyanLikeLogger>({
const selfDebug = isSelfDebug();
const bunyamin = new Bunyamin({ logger: noopLogger() });
const nobunyamin = new Bunyamin({
logger: noopLogger(),
threadGroups,
immutable: true,
});
const threadGroups = new ThreadGroups(bunyamin);

return { bunyamin, nobunyamin };
if (selfDebug) {
bunyamin.trace({ cat: 'bunyamin' }, 'bunyamin global instance created');
}

return { bunyamin, nobunyamin, threadGroups };
}

function getCached(): Realm | undefined {
return (globalThis as any).__BUNYAMIN__;
const result = (globalThis as any).__BUNYAMIN__;

Check warning on line 29 in src/realm.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type

if (isSelfDebug() && result) {
result.bunyamin.trace({ cat: 'bunyamin' }, 'bunyamin global instance retrieved from cache');
}

return result;
}

function setCached(realm: Realm) {
(globalThis as any).__BUNYAMIN__ = realm;

Check warning on line 39 in src/realm.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
return realm;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type TraceEventStreamOptions = {
* running in parallel, and you want to group them together in the trace
* viewer under the same thread name and keep the thread IDs together.
*/
threadGroups?: (string | ThreadGroupConfig)[];
threadGroups?: Iterable<string | ThreadGroupConfig>;
/**
* Default maximum number of concurrent threads in each thread group.
* Must be a positive integer.
Expand Down
2 changes: 1 addition & 1 deletion src/streams/bunyan-trace-event/options/normalizeOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function normalizeOptions(
options.defaultThreadName = options.defaultThreadName ?? 'Main Thread';
options.maxConcurrency = options.maxConcurrency ?? 100;
options.strict = options.strict ?? false;
options.threadGroups = (options.threadGroups ?? []).map((threadGroup, index) =>
options.threadGroups = [...(options.threadGroups ?? [])].map((threadGroup, index) =>
typeof threadGroup === 'string'
? {
id: threadGroup,
Expand Down
62 changes: 62 additions & 0 deletions src/thread-groups/ThreadGroups.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { beforeEach, describe, expect, jest, it } from '@jest/globals';
import type { ThreadGroups } from './ThreadGroups';
import { wrapLogger } from '../wrapLogger';
import type { Bunyamin } from '../decorator';

describe('ThreadGroups', () => {
let ThreadGroups: new (logger: Bunyamin) => ThreadGroups;
let threadGroups: ThreadGroups;
let isDebug: jest.Mocked<any>;
let logger: Bunyamin;

beforeEach(() => {
jest.mock('../is-debug');
isDebug = jest.requireMock<any>('../is-debug');
ThreadGroups = jest.requireActual<any>('./ThreadGroups').ThreadGroups;
logger = wrapLogger({
trace: jest.fn(),
debug: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
fatal: jest.fn(),
});
});

describe('in regular mode', () => {
beforeEach(() => {
isDebug.isSelfDebug.mockReturnValue(false);
threadGroups = new ThreadGroups(logger);
});

it('should be empty by default', () => {
expect([...threadGroups]).toEqual([]);
});

it('should add a thread group', () => {
const group = { id: 'foo', displayName: 'Foo' };
threadGroups.add(group);
expect([...threadGroups]).toEqual([group]);
});

it('should not call logger.trace', () => {
expect(logger.logger.trace).not.toHaveBeenCalled();
});
});

describe('in debug mode', () => {
beforeEach(() => {
isDebug.isSelfDebug.mockReturnValue(true);
threadGroups = new ThreadGroups(logger);
});

it('should call logger.trace upon addition', () => {
const group = { id: 'foo', displayName: 'Foo' };
threadGroups.add(group);
expect(logger.logger.trace).toHaveBeenCalledWith(
{ cat: 'bunyamin' },
expect.stringContaining(__filename),
);
});
});
});
40 changes: 40 additions & 0 deletions src/thread-groups/ThreadGroups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { Bunyamin } from '../decorator';
import type { ThreadGroupConfig } from '../streams';
import { isSelfDebug } from '../is-debug';
import { StackTraceError } from '../decorator/StackTraceError';

export class ThreadGroups {
readonly #bunyamin: Bunyamin;
readonly #debugMode = isSelfDebug();
readonly #groups = new Map<string, ThreadGroupConfig>();

constructor(bunyamin: Bunyamin) {
this.#bunyamin = bunyamin;
this.#groups = new Map();
}

add(group: ThreadGroupConfig) {
if (this.#debugMode) {
if (this.#groups.has(group.id)) {
this.#logAddition(group, 'overwritten');
} else {
this.#logAddition(group, 'added');
}
}

this.#groups.set(group.id, group);
return this;
}

[Symbol.iterator]() {
return this.#groups.values();
}

#logAddition(group: ThreadGroupConfig, action: string) {
const { stack } = new StackTraceError();
this.#bunyamin.trace(
{ cat: 'bunyamin' },
`thread group ${action}: ${group.id} (${group.displayName})\n\n${stack}`,
);
}
}
1 change: 1 addition & 0 deletions src/thread-groups/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ThreadGroups';
Loading