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 */