From 019165897cfae96d59947952511a18c5217e78c5 Mon Sep 17 00:00:00 2001 From: Cristian Barlutiu Date: Tue, 12 Mar 2024 12:24:13 +0100 Subject: [PATCH] Added option for custom level colors (#36) * enabled custom colors per level * added option to accept colors when setting up the transport * fixed linting issues --- README.md | 30 ++++++++++++++++++++++++++++++ index.js | 4 ++-- lib/messageFormatFactory.js | 9 +++++++-- test/index.test.js | 35 +++++++++++++++++++++++++++++++++++ types/index.d.ts | 7 ++++++- types/index.test-d.ts | 9 +++++---- 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e2566f4..8115333 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,36 @@ server.get("/", (request, reply) => { }); ``` +## Custom level colors + +Custom levels colors could be used by passing it into logger opts. They can also overwrite the default level's colors. Check all the supported colors [here](https://github.com/jorgebucaran/colorette?tab=readme-ov-file#supported-colors). + +```js +const server = fastify({ + logger: { + transport: { + target: "@fastify/one-line-logger", + colors: { + 35: "bgYellow", + 45: "magenta", + 60: "bgRedBright" // overwriting the `fatal` log color + } + }, + customLevels: { + foo: 35, + bar: 45, + }, + }, +}); + +server.get("/", (request, reply) => { + request.log.fatal("An error occured"); + request.log.foo("FOO!"); + request.log.bar("BAR!"); + reply.send({ foobar: true }); +}); +``` + ## License diff --git a/index.js b/index.js index ce357e2..f6f3ea1 100644 --- a/index.js +++ b/index.js @@ -4,9 +4,9 @@ const pretty = require('pino-pretty') const messageFormatFactory = require('./lib/messageFormatFactory') const oneLineLogger = (opts = {}) => { - const { colorize, levels, ...rest } = opts + const { colorize, levels, colors, ...rest } = opts - const messageFormat = messageFormatFactory(colorize, levels) + const messageFormat = messageFormatFactory(colorize, levels, colors) return pretty({ messageFormat, diff --git a/lib/messageFormatFactory.js b/lib/messageFormatFactory.js index 01af8ef..b5e31c8 100644 --- a/lib/messageFormatFactory.js +++ b/lib/messageFormatFactory.js @@ -2,8 +2,13 @@ const formatDate = require('./formatDate') const colorizerFactory = require('pino-pretty').colorizerFactory -const messageFormatFactory = (colorize, levels) => { - const colorizer = colorizerFactory(colorize === true) +const messageFormatFactory = (colorize, levels, colors) => { + const customColors = colors != null + ? Object.entries(colors).reduce((colors, [level, color]) => { + return [...colors, [level, color]] + }, []) + : undefined + const colorizer = colorizerFactory(colorize === true, customColors) const levelLookUp = { 60: colorizer('fatal').toLowerCase(), diff --git a/test/index.test.js b/test/index.test.js index c8b7396..904fbf2 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -113,3 +113,38 @@ logDescriptorColorizedLogPairs.forEach(([logDescriptor, logColorized]) => { }) }) } + +{ + const levels = { + foo: 35, + bar: 45 + } + const messageFormat = messageFormatFactory(true, levels, { 35: 'bgCyanBright', 45: 'yellow' }) + + const logCustomLevelsLogPairs = [ + [ + { time: EPOCH, level: 35, [MESSAGE_KEY]: 'basic foo log' }, + `${TIME} - \u001B[106mfoo\u001B[49m - \u001B[36mbasic foo log\u001B[39m` + ], + [ + { + time: EPOCH, + level: 45, + [MESSAGE_KEY]: 'basic incoming request bar log', + req: { + method: 'GET', + url: '/bar' + } + }, + `${TIME} - \u001B[33mbar\u001B[39m - GET /bar - \u001B[36mbasic incoming request bar log\u001B[39m` + ] + ] + logCustomLevelsLogPairs.forEach(([logDescriptor, expectedLog]) => { + test('format log correctly with custom colors per level', (t) => { + const log = messageFormat(logDescriptor, MESSAGE_KEY) + + t.equal(log, expectedLog) + t.end() + }) + }) +} diff --git a/types/index.d.ts b/types/index.d.ts index 5d57050..1db4b64 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -8,12 +8,17 @@ declare namespace oneLineLogger { url: string; } + export interface CustomColor { + [key: number]: string; + } + export type LogDescriptor = Record & { time: number; level: number; + colors?: CustomColor; req?: Request; } - export const messageFormatFactory: (colorize: boolean, levels: Record) => (log: LogDescriptor, messageKey: string) => string + export const messageFormatFactory: (colorize: boolean, levels: Record, colors?: CustomColor) => (log: LogDescriptor, messageKey: string) => string export const oneLineLogger: OneLineLogger export { oneLineLogger as default} diff --git a/types/index.test-d.ts b/types/index.test-d.ts index ec78282..a584afb 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -1,11 +1,12 @@ +import pretty from 'pino-pretty'; +import { expectType } from "tsd"; import oneLineLogger, { - Request, + CustomColor, LogDescriptor, + Request, messageFormatFactory, oneLineLogger as oneLineLoggerNamed } from ".."; -import { expectType } from "tsd" -import pretty from 'pino-pretty' expectType(({} as Request).method) expectType(({} as Request).url) @@ -14,7 +15,7 @@ expectType(({} as LogDescriptor).level) expectType(({} as LogDescriptor).time) expectType(({} as LogDescriptor).req) -expectType<(colorize: boolean, levels: Record) => (log: LogDescriptor, messageKey: string) => string>(messageFormatFactory) +expectType<(colorize: boolean, levels: Record, colors?: CustomColor) => (log: LogDescriptor, messageKey: string) => string>(messageFormatFactory) expectType(oneLineLoggerNamed) expectType<(opts?: pretty.PrettyOptions) => pretty.PrettyStream>(oneLineLogger)