Skip to content

Commit

Permalink
feat: 🎸 rename LumberjackLog property context to scope (#53)
Browse files Browse the repository at this point in the history
* feat: 🎸 rename LumberjackLog property context to scope

BREAKING CHANGE: LumberjackLog property context was renamed to scope

* feat: 🎸 rename remaning context references as ponted in PR

* feat: 🎸 apply PR suggestions
  • Loading branch information
NachoVazquez authored Dec 9, 2020
1 parent 14f4c4f commit 4738a16
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 93 deletions.
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class MyComponent implements OnInit {
this.lumberjack.log({
level: LumberjackLogLevel.Info,
message: 'Hello, World!',
context: 'MyComponent',
scope: 'MyComponent',
createdAt: Date.now(),
});
}
Expand All @@ -154,8 +154,8 @@ Lumberjack replaces omitted options with defaults.
When the `format` option is not configured, Lumberjack will use the following default formatter.

```ts
function lumberjackFormatLog({ context, createdAt: timestamp, level, message }: LumberjackLog) {
return `${level} ${utcTimestampFor(timestamp)}${context ? ` [${context}]` : ''} ${message}`;
function lumberjackFormatLog({ scope, createdAt: timestamp, level, message }: LumberjackLog) {
return `${level} ${utcTimestampFor(timestamp)}${scope ? ` [${scope}]` : ''} ${message}`;
}
```

Expand Down Expand Up @@ -337,7 +337,7 @@ For a more advanced log driver implementation, see [LumberjackHttpDriver](https:

## Best practices

Every log can be represented as a combination of its level, creation time, message, and context. Using inline logs with the `LumberjackService` can cause structure duplication and/or de-standardization.
Every log can be represented as a combination of its level, creation time, message, and scope. Using inline logs with the `LumberjackService` can cause structure duplication and/or de-standardization.

The following practices are recommended to mitigate these problems.

Expand All @@ -355,18 +355,18 @@ import { LumberjackService, LumberjackTimeService } from '@ngworker/lumberjack';
export abstract class LumberjackLogger {
constructor(lumberjack: LumberjackService, time: LumberjackTimeService) {}

protected createCriticalLogger(message: string, context?: string): () => void {}
protected createDebugLogger(message: string, context?: string): () => void {}
protected createErrorLogger(message: string, context?: string): () => void {}
protected createInfoLogger(message: string, context?: string): () => void {}
protected createTraceLogger(message: string, context?: string): () => void {}
protected createWarningLogger(message: string, context?: string): () => void {}
protected createCriticalLogger(message: string, scope?: string): () => void {}
protected createDebugLogger(message: string, scope?: string): () => void {}
protected createErrorLogger(message: string, scope?: string): () => void {}
protected createInfoLogger(message: string, scope?: string): () => void {}
protected createTraceLogger(message: string, scope?: string): () => void {}
protected createWarningLogger(message: string, scope?: string): () => void {}
}
```

By extending `LumberjackLogger`, we only have to be worry about the message and context of our pre-defined logs.
By extending `LumberjackLogger`, we only have to be worry about the message and scope of our pre-defined logs.

All logger factory methods are protected as it is recommended to create a custom logger per _context_ rather than using logger factories directly in a consumer.
All logger factory methods are protected as it is recommended to create a custom logger per _scope_ rather than using logger factories directly in a consumer.

As an example, let's create a custom logger for our example application.

Expand All @@ -378,11 +378,11 @@ import { LumberjackLogger } from '@ngworker/lumberjack';
providedIn: 'root',
})
export class AppLogger extends LumberjackLogger {
public static logContext = 'Forest App';
public static scope = 'Forest App';

forestOnFire = this.createCriticalLogger('The forest is on fire!', AppLogger.logContext);
forestOnFire = this.createCriticalLogger('The forest is on fire!', AppLogger.scope);

helloForest = this.createInfoLogger('Hello, forest!', AppLogger.logContext);
helloForest = this.createInfoLogger('Hello, forest!', AppLogger.scope);
}
```

Expand Down
6 changes: 3 additions & 3 deletions apps/lumberjack-app/src/app/app-logger.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { LumberjackLogger, LumberjackService, LumberjackTimeService } from '@ngw
providedIn: 'root',
})
export class AppLogger extends LumberjackLogger {
public static logContext = 'Forest App';
public static scope = 'Forest App';

constructor(lumberjack: LumberjackService, time: LumberjackTimeService) {
super(lumberjack, time);
}

forestOnFire = this.createCriticalLogger('The forest is on fire', AppLogger.logContext);
forestOnFire = this.createCriticalLogger('The forest is on fire', AppLogger.scope);

helloForest = this.createInfoLogger('HelloForest', AppLogger.logContext);
helloForest = this.createInfoLogger('HelloForest', AppLogger.scope);
}
23 changes: 10 additions & 13 deletions libs/internal/test-util/src/lib/logs/log-creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ import { LumberjackLevel, LumberjackLogLevel, LumberjackTimeService } from '@ngw

import { resolveDependency } from '../angular/resolve-dependency';

const createLog = (level: LumberjackLogLevel, message = '', context = 'Test') => ({
context,
const createLog = (level: LumberjackLogLevel, message = '', scope = 'Test') => ({
scope,
createdAt: resolveDependency(LumberjackTimeService).getUnixEpochTicks(),
level,
message,
});
export const createCriticalLog = (message?: string, context?: string) =>
createLog(LumberjackLevel.Critical, message, context);
export const createDebugLog = (message?: string, context?: string) =>
createLog(LumberjackLevel.Debug, message, context);
export const createErrorLog = (message?: string, context?: string) =>
createLog(LumberjackLevel.Error, message, context);
export const createInfoLog = (message?: string, context?: string) => createLog(LumberjackLevel.Info, message, context);
export const createTraceLog = (message?: string, context?: string) =>
createLog(LumberjackLevel.Trace, message, context);
export const createWarningLog = (message?: string, context?: string) =>
createLog(LumberjackLevel.Warning, message, context);
export const createCriticalLog = (message?: string, scope?: string) =>
createLog(LumberjackLevel.Critical, message, scope);
export const createDebugLog = (message?: string, scope?: string) => createLog(LumberjackLevel.Debug, message, scope);
export const createErrorLog = (message?: string, scope?: string) => createLog(LumberjackLevel.Error, message, scope);
export const createInfoLog = (message?: string, scope?: string) => createLog(LumberjackLevel.Info, message, scope);
export const createTraceLog = (message?: string, scope?: string) => createLog(LumberjackLevel.Trace, message, scope);
export const createWarningLog = (message?: string, scope?: string) =>
createLog(LumberjackLevel.Warning, message, scope);
Original file line number Diff line number Diff line change
Expand Up @@ -122,37 +122,37 @@ describe(LumberjackModule.name, () => {
fakeTimestamp = utcTimestampFor(fakeTicks);
});

it('formats a log with a context', () => {
const logWithContext: LumberjackLog = {
context: 'TestSuite',
it('formats a log with a scope', () => {
const logWithScope: LumberjackLog = {
scope: 'TestSuite',
createdAt: fakeTicks,
level: LumberjackLevel.Critical,
message: 'Test Message',
};

const { context, level, message } = logWithContext;
const { scope, level, message } = logWithScope;

const expectedFormattedLog = `${level} ${fakeTimestamp} [${context}] ${message}`;
const expectedFormattedLog = `${level} ${fakeTimestamp} [${scope}] ${message}`;

const { format } = resolveDependency(lumberjackConfigToken);

expect(format(logWithContext)).toBe(expectedFormattedLog);
expect(format(logWithScope)).toBe(expectedFormattedLog);
});

it('formats a log with no context', () => {
const logWithoutContext: LumberjackLog = {
it('formats a log with no scope', () => {
const logWithoutScope: LumberjackLog = {
createdAt: fakeTicks,
level: LumberjackLevel.Critical,
message: 'Test Message',
};

const { level, message } = logWithoutContext;
const { level, message } = logWithoutScope;

const expectedFormattedLog = `${level} ${fakeTimestamp} ${message}`;

const { format } = resolveDependency(lumberjackConfigToken);

expect(format(logWithoutContext)).toEqual(expectedFormattedLog);
expect(format(logWithoutScope)).toEqual(expectedFormattedLog);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import { lumberjackFormatLog } from './lumberjack-format-log';

function parseFormattedLog(formattedLog: string) {
const formattedLogPattern = /^([a-z]+) ([0-9\.:\-TZ]+) (\[(.+)\] )?(.*)$/;
const [_, level, timestamp, taggedContextWithEndingSpace = '', context = '', message] =
const [_, level, timestamp, taggedScopeWithEndingSpace = '', scope = '', message] =
formattedLogPattern.exec(formattedLog) || [];
const taggedContext = taggedContextWithEndingSpace ? taggedContextWithEndingSpace.slice(0, -1) : '';
const taggedScope = taggedScopeWithEndingSpace ? taggedScopeWithEndingSpace.slice(0, -1) : '';

return {
context,
scope,
level,
message,
taggedContext,
taggedScope,
timestamp,
};
}
Expand All @@ -38,7 +38,7 @@ describe(lumberjackFormatLog.name, () => {
createdAt: new Date().valueOf(),
level: expectedLevel,
message: 'Test message',
context: 'Test context',
scope: 'Test scope',
};

const formattedLog = lumberjackFormatLog(log);
Expand All @@ -62,7 +62,7 @@ describe(lumberjackFormatLog.name, () => {
createdAt: unixEpochTicks,
level: LumberjackLevel.Debug,
message: 'Test message',
context: 'Test context',
scope: 'Test scope',
};

const formattedLog = lumberjackFormatLog(log);
Expand All @@ -73,46 +73,46 @@ describe(lumberjackFormatLog.name, () => {
});
});

describe('Context', () => {
const contexts = ['Test context', 'TestContext', 'test.context'];
describe('Scope', () => {
const scopes = ['Test scope', 'TestScope', 'test.scope'];

contexts.forEach((expectedContext) => {
it('tags the specified context', () => {
const log = createDebugLog(undefined, expectedContext);
scopes.forEach((expectedScope) => {
it('tags the specified scope', () => {
const log = createDebugLog(undefined, expectedScope);

const formattedLog = lumberjackFormatLog(log);

const { context: actualContext, taggedContext } = parseFormattedLog(formattedLog);
expect(actualContext).toBe(expectedContext);
expect(taggedContext).toBe(`[${expectedContext}]`);
const { scope: actualScope, taggedScope } = parseFormattedLog(formattedLog);
expect(actualScope).toBe(expectedScope);
expect(taggedScope).toBe(`[${expectedScope}]`);
});
});

it('does not add a tag without a context', () => {
it('does not add a tag without a scope', () => {
const log = createDebugLog('Test message', '');

const formattedLog = lumberjackFormatLog(log);

const { context: actualContext, taggedContext } = parseFormattedLog(formattedLog);
expect(actualContext).toBe('');
expect(taggedContext).toBe('');
const { scope: actualScope, taggedScope } = parseFormattedLog(formattedLog);
expect(actualScope).toBe('');
expect(taggedScope).toBe('');
});
});

describe('Message', () => {
const messages = ['The forest is on fire!', 'Lumber is gold', 'Saving the Amazon Jungle'];

messages.forEach((expectedMessage) => {
it(`places the message at the end with a context`, () => {
const log = createDebugLog(expectedMessage, 'Test context');
it(`places the message at the end with a scope`, () => {
const log = createDebugLog(expectedMessage, 'Test scope');

const formattedLog = lumberjackFormatLog(log);

const { message: actualMessage } = parseFormattedLog(formattedLog);
expect(actualMessage).toBe(expectedMessage);
});

it(`places the message at the end without a context`, () => {
it(`places the message at the end without a scope`, () => {
const log = createDebugLog(expectedMessage, '');

const formattedLog = lumberjackFormatLog(log);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { LumberjackLog } from '../logs/lumberjack.log';

import { utcTimestampFor } from './utc-timestamp-for';

export function lumberjackFormatLog({ context, createdAt: timestamp, level, message }: LumberjackLog) {
return `${level} ${utcTimestampFor(timestamp)}${context ? ` [${context}]` : ''} ${message}`;
export function lumberjackFormatLog({ scope, createdAt: timestamp, level, message }: LumberjackLog) {
return `${level} ${utcTimestampFor(timestamp)}${scope ? ` [${scope}]` : ''} ${message}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { LumberjackLogFormatter } from './lumberjack-log-formatter.service';
function createFormattingErrorLog(formattingErrorMessage: string, log: LumberjackLog): LumberjackLog {
return createErrorLog(
`Could not format message "${log.message}". Error: "${formattingErrorMessage}"`,
logFormattingErrorContext
logFormattingErrorScope
);
}

Expand All @@ -36,7 +36,7 @@ class FakeTimeService extends LumberjackTimeService {
}
}

const logFormattingErrorContext = 'LumberjackLogFormattingError';
const logFormattingErrorScope = 'LumberjackLogFormattingError';

describe(LumberjackLogFormatter.name, () => {
function setup(options?: LumberjackOptions) {
Expand Down Expand Up @@ -107,7 +107,7 @@ describe(LumberjackLogFormatter.name, () => {
const { formattedLog: actualFormattedLog } = service.formatLog(criticalLog);

expect(actualFormattedLog).toBe(
`${formattingErrorLog.level} ${nowTimestamp} [${logFormattingErrorContext}] ${formattingErrorLog.message}`
`${formattingErrorLog.level} ${nowTimestamp} [${logFormattingErrorScope}] ${formattingErrorLog.message}`
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class LumberjackLogFormatter {
const formattingErrorMessage = (formatError as Error).message || String(formatError);

return {
context: 'LumberjackLogFormattingError',
scope: 'LumberjackLogFormattingError',
createdAt: this.time.getUnixEpochTicks(),
level: LumberjackLevel.Error,
message: `Could not format message "${log.message}". Error: "${formattingErrorMessage}"`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import { LumberjackService } from './lumberjack.service';
providedIn: 'root',
})
export class TestLogger extends LumberjackLogger {
static context = 'Test';

criticalLogger = this.createCriticalLogger('', TestLogger.context);
debugLogger = this.createDebugLogger('', TestLogger.context);
errorLogger = this.createErrorLogger('', TestLogger.context);
infoLogger = this.createInfoLogger('', TestLogger.context);
traceLogger = this.createTraceLogger('', TestLogger.context);
warningLogger = this.createWarningLogger('', TestLogger.context);
static scope = 'Test';

criticalLogger = this.createCriticalLogger('', TestLogger.scope);
debugLogger = this.createDebugLogger('', TestLogger.scope);
errorLogger = this.createErrorLogger('', TestLogger.scope);
infoLogger = this.createInfoLogger('', TestLogger.scope);
traceLogger = this.createTraceLogger('', TestLogger.scope);
warningLogger = this.createWarningLogger('', TestLogger.scope);
}

const fakeDate = new Date('2020-02-02T02:02:02.000Z');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,33 @@ import { LumberjackService } from './lumberjack.service';
export abstract class LumberjackLogger {
constructor(private lumberjack: LumberjackService, private time: LumberjackTimeService) {}

protected createCriticalLogger(message: string, context?: string): () => void {
return this.createLogger(LumberjackLevel.Critical, message, context);
protected createCriticalLogger(message: string, scope?: string): () => void {
return this.createLogger(LumberjackLevel.Critical, message, scope);
}

protected createDebugLogger(message: string, context?: string): () => void {
return this.createLogger(LumberjackLevel.Debug, message, context);
protected createDebugLogger(message: string, scope?: string): () => void {
return this.createLogger(LumberjackLevel.Debug, message, scope);
}

protected createErrorLogger(message: string, context?: string): () => void {
return this.createLogger(LumberjackLevel.Error, message, context);
protected createErrorLogger(message: string, scope?: string): () => void {
return this.createLogger(LumberjackLevel.Error, message, scope);
}

protected createInfoLogger(message: string, context?: string): () => void {
return this.createLogger(LumberjackLevel.Info, message, context);
protected createInfoLogger(message: string, scope?: string): () => void {
return this.createLogger(LumberjackLevel.Info, message, scope);
}

protected createTraceLogger(message: string, context?: string): () => void {
return this.createLogger(LumberjackLevel.Trace, message, context);
protected createTraceLogger(message: string, scope?: string): () => void {
return this.createLogger(LumberjackLevel.Trace, message, scope);
}

protected createWarningLogger(message: string, context?: string): () => void {
return this.createLogger(LumberjackLevel.Warning, message, context);
protected createWarningLogger(message: string, scope?: string): () => void {
return this.createLogger(LumberjackLevel.Warning, message, scope);
}

private createLogger(level: LumberjackLogLevel, message: string, context?: string): () => void {
private createLogger(level: LumberjackLogLevel, message: string, scope?: string): () => void {
return () => {
this.lumberjack.log({ context, createdAt: this.time.getUnixEpochTicks(), level, message });
this.lumberjack.log({ scope, createdAt: this.time.getUnixEpochTicks(), level, message });
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class LumberjackService {

private createDriverErrorLog(driverError: LumberjackLogDriverError): LumberjackLog {
return {
context: 'LumberjackLogDriverError',
scope: 'LumberjackLogDriverError',
createdAt: this.time.getUnixEpochTicks(),
level: LumberjackLevel.Error,
message: formatLogDriverError(driverError),
Expand Down
Loading

0 comments on commit 4738a16

Please sign in to comment.