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(common): add log filtering function #14793

Open
wants to merge 3 commits into
base: master
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
43 changes: 42 additions & 1 deletion packages/common/services/logger.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,51 @@ import { isObject } from '../utils/shared.utils';
import { ConsoleLogger } from './console-logger.service';
import { isLogLevelEnabled } from './utils';

const LOG_LEVELS = [
'verbose',
'debug',
'log',
'warn',
'error',
'fatal',
] as const satisfies string[];

/**
* @publicApi
*/
export type LogLevel = (typeof LOG_LEVELS)[number];

/**
* @publicApi
*/
export function isLogLevel(maybeLogLevel: any): maybeLogLevel is LogLevel {
return LOG_LEVELS.includes(maybeLogLevel);
}

/**
* @publicApi
*/
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose' | 'fatal';
export function filterLogLevels(parseableString = ''): LogLevel[] {
const sanitizedSring = parseableString.replaceAll(' ', '').toLowerCase();

if (sanitizedSring[0] === '>') {
const orEqual = sanitizedSring[1] === '=';

const logLevelIndex = (LOG_LEVELS as string[]).indexOf(
sanitizedSring.substring(orEqual ? 2 : 1),
);

if (logLevelIndex === -1) {
throw new Error(`parse error (unknown log level): ${sanitizedSring}`);
}

return LOG_LEVELS.slice(orEqual ? logLevelIndex : logLevelIndex + 1);
} else if (sanitizedSring.includes(',')) {
return sanitizedSring.split(',').filter(isLogLevel);
}

return isLogLevel(sanitizedSring) ? [sanitizedSring] : LOG_LEVELS;
}

/**
* @publicApi
Expand Down
44 changes: 43 additions & 1 deletion packages/common/test/services/logger.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,51 @@
import { expect } from 'chai';
import 'reflect-metadata';
import * as sinon from 'sinon';
import { ConsoleLogger, Logger, LoggerService, LogLevel } from '../../services';
import {
ConsoleLogger,
filterLogLevels,
Logger,
LoggerService,
LogLevel,
} from '../../services';

describe('Logger', () => {
describe('[log helpers]', () => {
describe('when using filterLogLevels', () => {
it('should correctly parse an exclusive range', () => {
const returned = filterLogLevels('>warn');
expect(returned).to.deep.equal(['error', 'fatal']);
});

it('should correctly parse an inclusive range', () => {
const returned = filterLogLevels('>=warn');
expect(returned).to.deep.equal(['warn', 'error', 'fatal']);
});

it('should correctly parse a string list', () => {
const returned = filterLogLevels('verbose,warn,fatal');
expect(returned).to.deep.equal(['verbose', 'warn', 'fatal']);
});

it('should correctly parse a single log level', () => {
const returned = filterLogLevels('debug');
expect(returned).to.deep.equal(['debug']);
});

it('should return all otherwise', () => {
const returned = filterLogLevels();
expect(returned).to.deep.equal([
'verbose',
'debug',
'log',
'warn',
'error',
'fatal',
]);
});
});
});

describe('[static methods]', () => {
describe('when the default logger is used', () => {
let processStdoutWriteSpy: sinon.SinonSpy;
Expand Down