From d2fb09ac6f8150f7e13dc055b903336353ae9fc1 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Thu, 9 May 2024 14:16:52 -0400 Subject: [PATCH 1/3] Add support for timestampFormat --- package-lock.json | 15 +++++++++++++++ package.json | 1 + src/Logger.spec.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/Logger.ts | 27 +++++++++++++++++++++------ 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 155c228..34ce168 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "chalk": "^4.1.2", + "date-fns": "^3.6.0", "fs-extra": "^10.0.0", "parse-ms": "^2.1.0", "safe-json-stringify": "^1.2.0", @@ -1873,6 +1874,15 @@ "node": ">= 8" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -5919,6 +5929,11 @@ "which": "^2.0.1" } }, + "date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==" + }, "debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", diff --git a/package.json b/package.json index bd48b4a..db4eedc 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ }, "dependencies": { "chalk": "^4.1.2", + "date-fns": "^3.6.0", "fs-extra": "^10.0.0", "parse-ms": "^2.1.0", "safe-json-stringify": "^1.2.0", diff --git a/src/Logger.spec.ts b/src/Logger.spec.ts index aa27910..5858774 100644 --- a/src/Logger.spec.ts +++ b/src/Logger.spec.ts @@ -255,6 +255,44 @@ describe('Logger', () => { const stamp = logger.formatTimestamp(new Date()); expect(/\d\d:\d\d:\d\d\.\d\d\d/.exec(stamp)).to.exist; }); + + it('uses from original options', () => { + logger = new Logger({ timestampFormat: 'HH' }); + expect( + logger.formatTimestamp(now) + ).to.eql('04'); + }); + + it('uses from parent options', () => { + logger = new Logger({ timestampFormat: 'HH' }); + logger = logger.createLogger(); + expect( + logger.formatTimestamp(now) + ).to.eql('04'); + }); + + it('uses the default when missing from options', () => { + logger = new Logger(); + expect( + logger.formatTimestamp(now) + ).to.eql(timestamp); + }); + + it('uses the default when deleted from options', () => { + logger = new Logger({ timestampFormat: 'HH' }); + logger['options'].timestampFormat = undefined; + expect( + logger.formatTimestamp(now) + ).to.eql(timestamp); + }); + + it('uses the default when deleted from logger itself', () => { + logger = new Logger({ timestampFormat: 'HH' }); + logger.timestampFormat = undefined; + expect( + logger.formatTimestamp(now) + ).to.eql(timestamp); + }); }); describe('emit', () => { diff --git a/src/Logger.ts b/src/Logger.ts index f7f69e5..c92d08e 100644 --- a/src/Logger.ts +++ b/src/Logger.ts @@ -1,5 +1,6 @@ import * as safeJsonStringify from 'safe-json-stringify'; import { serializeError } from 'serialize-error'; +import { format } from 'date-fns'; import type { ChalkFunction } from 'chalk'; // eslint-disable-next-line @typescript-eslint/no-require-imports import Chalk = require('chalk'); @@ -20,6 +21,19 @@ export class Logger { */ private options: LoggerOptions; + /** + * The format used for timestamp. Defaults to 'HH:mm:ss.SSS' (24-hour time with milliseconds) + */ + public get timestampFormat(): string { + return this.options.timestampFormat ?? this.options.parent?.timestampFormat ?? 'HH:mm:ss.SSS'; + } + public set timestampFormat(value: string | undefined) { + this.options.timestampFormat = value; + } + + /** + * The log level of this logger. If a log level is not specified, it will inherit from the parent logger or default to 'log' + */ public get logLevel(): LogLevel | LogLevelNumeric { return this.options.logLevel ?? this.options.parent?.logLevel ?? 'log'; } @@ -175,12 +189,7 @@ export class Logger { } public formatTimestamp(date: Date) { - return date.getHours().toString().padStart(2, '0') + - ':' + - date.getMinutes().toString().padStart(2, '0') + - ':' + - date.getSeconds().toString().padStart(2, '0') + - '.' + date.getMilliseconds().toString().padEnd(3, '0').substring(0, 3); + return format(date, this.timestampFormat); } /** @@ -466,6 +475,12 @@ export enum LogLevelNumeric { export type LogLevel = 'off' | 'error' | 'warn' | 'log' | 'info' | 'debug' | 'trace'; export interface LoggerOptions { + /** + * Format string for the timestamp. Defaults to 'HH:mm:ss.SSS' (24-hour time with milliseconds) + * + * https://date-fns.org/v3.6.0/docs/format + */ + timestampFormat?: string; /** * A prefix applied to every log entry. Appears directly after the logLevel */ From 6666c970e04f8f1772205a6f60fb0fde3ff9520a Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Thu, 9 May 2024 14:51:11 -0400 Subject: [PATCH 2/3] Use older version of date-fns --- package-lock.json | 56 +++++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34ce168..b99d9a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "chalk": "^4.1.2", - "date-fns": "^3.6.0", + "date-fns": "^2.30.0", "fs-extra": "^10.0.0", "parse-ms": "^2.1.0", "safe-json-stringify": "^1.2.0", @@ -581,6 +581,17 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", @@ -1875,12 +1886,18 @@ } }, "node_modules/date-fns": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/kossnocorp" + "type": "opencollective", + "url": "https://opencollective.com/date-fns" } }, "node_modules/debug": { @@ -3852,6 +3869,11 @@ "node": ">=8.10.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -4943,6 +4965,14 @@ "integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==", "dev": true }, + "@babel/runtime": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, "@babel/template": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", @@ -5930,9 +5960,12 @@ } }, "date-fns": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==" + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "requires": { + "@babel/runtime": "^7.21.0" + } }, "debug": { "version": "4.3.3", @@ -7398,6 +7431,11 @@ "picomatch": "^2.2.1" } }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", diff --git a/package.json b/package.json index db4eedc..f2130a2 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ }, "dependencies": { "chalk": "^4.1.2", - "date-fns": "^3.6.0", + "date-fns": "^2.30.0", "fs-extra": "^10.0.0", "parse-ms": "^2.1.0", "safe-json-stringify": "^1.2.0", From 3a73ac957b2d92c4c5dcd675afd2140f3a9a958b Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Thu, 9 May 2024 15:06:47 -0400 Subject: [PATCH 3/3] Add test for brighterscript logging format --- src/Logger.spec.ts | 5 +++++ src/Logger.ts | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Logger.spec.ts b/src/Logger.spec.ts index 5858774..40df4ed 100644 --- a/src/Logger.spec.ts +++ b/src/Logger.spec.ts @@ -293,6 +293,11 @@ describe('Logger', () => { logger.formatTimestamp(now) ).to.eql(timestamp); }); + + it('supports the brighterscript log format', () => { + logger.timestampFormat = 'hh:mm:ss:SSS aa'; + expect(logger.formatTimestamp(now)).to.eql('04:05:06:789 AM'); + }); }); describe('emit', () => { diff --git a/src/Logger.ts b/src/Logger.ts index c92d08e..a523cfc 100644 --- a/src/Logger.ts +++ b/src/Logger.ts @@ -22,7 +22,9 @@ export class Logger { private options: LoggerOptions; /** - * The format used for timestamp. Defaults to 'HH:mm:ss.SSS' (24-hour time with milliseconds) + * The timestamp format string. Defaults to 'HH:mm:ss.SSS' (24-hour time with milliseconds) + * + * https://date-fns.org/v2.30.0/docs/format */ public get timestampFormat(): string { return this.options.timestampFormat ?? this.options.parent?.timestampFormat ?? 'HH:mm:ss.SSS'; @@ -476,9 +478,9 @@ export type LogLevel = 'off' | 'error' | 'warn' | 'log' | 'info' | 'debug' | 'tr export interface LoggerOptions { /** - * Format string for the timestamp. Defaults to 'HH:mm:ss.SSS' (24-hour time with milliseconds) + * The timestamp format string. Defaults to 'HH:mm:ss.SSS' (24-hour time with milliseconds) * - * https://date-fns.org/v3.6.0/docs/format + * https://date-fns.org/v2.30.0/docs/format */ timestampFormat?: string; /**