Skip to content

Commit

Permalink
feat(sdk-logs): added colors option to ConsoleLogRecordExporter
Browse files Browse the repository at this point in the history
  • Loading branch information
10xLaCroixDrinker committed Mar 4, 2024
1 parent 3920b15 commit 265ff31
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 47 deletions.
1 change: 1 addition & 0 deletions experimental/packages/sdk-logs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"@types/mocha": "10.0.6",
"@types/node": "18.6.5",
"@types/sinon": "10.0.20",
"ansi-regex": "^5.0.1",
"babel-plugin-istanbul": "6.1.1",
"codecov": "3.8.3",
"cross-var": "1.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import { ExportResult, hrTimeToMicroseconds } from '@opentelemetry/core';
import { ExportResultCode } from '@opentelemetry/core';

import type { ConsoleLogRecordExporterConfig } from '../types';
import type { ReadableLogRecord } from './ReadableLogRecord';
import type { LogRecordExporter } from './LogRecordExporter';

Expand All @@ -27,6 +28,15 @@ import type { LogRecordExporter } from './LogRecordExporter';

/* eslint-disable no-console */
export class ConsoleLogRecordExporter implements LogRecordExporter {
private _dirOpts: {
depth: number;
colors?: boolean;
} = { depth: 3 };

constructor(config: ConsoleLogRecordExporterConfig = {}) {
if (typeof config.colors !== 'undefined')
this._dirOpts.colors = config.colors;
}
/**
* Export logs.
* @param logs
Expand Down Expand Up @@ -73,7 +83,7 @@ export class ConsoleLogRecordExporter implements LogRecordExporter {
done?: (result: ExportResult) => void
): void {
for (const logRecord of logRecords) {
console.dir(this._exportInfo(logRecord), { depth: 3 });
console.dir(this._exportInfo(logRecord), this._dirOpts);
}
done?.({ code: ExportResultCode.SUCCESS });
}
Expand Down
1 change: 1 addition & 0 deletions experimental/packages/sdk-logs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export {
LogRecordLimits,
BufferConfig,
BatchLogRecordProcessorBrowserConfig,
ConsoleLogRecordExporterConfig,
} from './types';
export { LoggerProvider } from './LoggerProvider';
export { LogRecord } from './LogRecord';
Expand Down
5 changes: 5 additions & 0 deletions experimental/packages/sdk-logs/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ export interface BatchLogRecordProcessorBrowserConfig extends BufferConfig {
* on mobile, switches to a different app. Auto flush is enabled by default. */
disableAutoFlushOnDocumentHide?: boolean;
}

export interface ConsoleLogRecordExporterConfig {
/** Force colorization of console logs instead of relying on detection */
colors?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import * as assert from 'assert';
import * as sinon from 'sinon';
import * as ansiRegex from 'ansi-regex';
import { SeverityNumber } from '@opentelemetry/api-logs';

import {
Expand All @@ -24,60 +25,97 @@ import {
SimpleLogRecordProcessor,
} from './../../../src';

/* eslint-disable no-console */
const isColorText = (text: string) => ansiRegex().test(text);

describe('ConsoleLogRecordExporter', () => {
let previousConsoleDir: typeof console.dir;
describe('export', () => {
it('should export information about log record', () => {
const consoleExporter = new ConsoleLogRecordExporter();
const consoleSpy = sinon.spy(console, 'dir');
const spyExport = sinon.spy(consoleExporter, 'export');
const provider = new LoggerProvider();
provider.addLogRecordProcessor(
new SimpleLogRecordProcessor(consoleExporter)
);

beforeEach(() => {
previousConsoleDir = console.dir;
console.dir = () => {};
});
const stdoutStub = sinon.stub(process.stdout, 'write');
provider.getLogger('default').emit({
body: 'body1',
severityNumber: SeverityNumber.DEBUG,
severityText: 'DEBUG',
});
const consoleOutput = stdoutStub.getCalls()[0].firstArg;
stdoutStub.restore();

afterEach(() => {
console.dir = previousConsoleDir;
});
const logRecords = spyExport.args[0];
const firstLogRecord = logRecords[0][0];
const consoleArgs = consoleSpy.args[0];
const consoleLogRecord = consoleArgs[0];
const keys = Object.keys(consoleLogRecord).sort().join(',');
consoleSpy.restore();

describe('export', () => {
it('should export information about log record', () => {
assert.doesNotThrow(() => {
const consoleExporter = new ConsoleLogRecordExporter();
const spyConsole = sinon.spy(console, 'dir');
const spyExport = sinon.spy(consoleExporter, 'export');
const provider = new LoggerProvider();
provider.addLogRecordProcessor(
new SimpleLogRecordProcessor(consoleExporter)
);
const expectedKeys = [
'attributes',
'body',
'severityNumber',
'severityText',
'spanId',
'timestamp',
'traceFlags',
'traceId',
].join(',');

assert.equal(firstLogRecord.body, 'body1');
assert.equal(firstLogRecord.severityNumber, SeverityNumber.DEBUG);
assert.equal(firstLogRecord.severityText, 'DEBUG');
assert.equal(keys, expectedKeys);

provider.getLogger('default').emit({
body: 'body1',
severityNumber: SeverityNumber.DEBUG,
severityText: 'DEBUG',
});
assert.ok(spyExport.calledOnce);

const logRecords = spyExport.args[0];
const firstLogRecord = logRecords[0][0];
const consoleArgs = spyConsole.args[0];
const consoleLogRecord = consoleArgs[0];
const keys = Object.keys(consoleLogRecord).sort().join(',');
const containsColor = isColorText(consoleOutput);
assert.equal(
containsColor,
(process.env.FORCE_COLOR && process.env.FORCE_COLOR !== '0') ||
process.stdout.isTTY
);
});
it('should colorize log records', () => {
const consoleExporter = new ConsoleLogRecordExporter({ colors: true });
const provider = new LoggerProvider();
provider.addLogRecordProcessor(
new SimpleLogRecordProcessor(consoleExporter)
);

const expectedKeys = [
'attributes',
'body',
'severityNumber',
'severityText',
'spanId',
'timestamp',
'traceFlags',
'traceId',
].join(',');
const stdoutStub = sinon.stub(process.stdout, 'write');
provider.getLogger('default').emit({
body: 'body2',
severityNumber: SeverityNumber.DEBUG,
severityText: 'DEBUG',
});
const consoleOutput = stdoutStub.getCalls()[0].firstArg;
stdoutStub.restore();

assert.ok(firstLogRecord.body === 'body1');
assert.ok(firstLogRecord.severityNumber === SeverityNumber.DEBUG);
assert.ok(firstLogRecord.severityText === 'DEBUG');
assert.ok(keys === expectedKeys, 'expectedKeys');
const containsColor = isColorText(consoleOutput);
assert.ok(containsColor);
});
it('should not colorize log records', () => {
const consoleExporter = new ConsoleLogRecordExporter({ colors: false });
const provider = new LoggerProvider();
provider.addLogRecordProcessor(
new SimpleLogRecordProcessor(consoleExporter)
);

assert.ok(spyExport.calledOnce);
const stdoutStub = sinon.stub(process.stdout, 'write');
provider.getLogger('default').emit({
body: 'body3',
severityNumber: SeverityNumber.DEBUG,
severityText: 'DEBUG',
});
const consoleOutput = stdoutStub.getCalls()[0].firstArg;
stdoutStub.restore();

const doesNotContainColor = !isColorText(consoleOutput);
assert.ok(doesNotContainColor);
});
});
});
9 changes: 7 additions & 2 deletions package-lock.json

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

0 comments on commit 265ff31

Please sign in to comment.