Label support

This commit is contained in:
Erik 2023-11-15 22:16:54 +02:00
parent 4b6b8e22e8
commit fc4a4da6cf
4 changed files with 33 additions and 32 deletions

View File

@ -66,7 +66,9 @@ type SharedOptionsType = {
guard?: string, guard?: string,
customStreams?: string[] customStreams?: string[]
logLevel?: LogLevel, logLevel?: LogLevel,
logLevelMapping?: LogLevelType logLevelMapping?: LogLevelType,
customTypes?: string[],
labels?: string[],
} }
const SharedOptions: SharedOptionsType = { const SharedOptions: SharedOptionsType = {
@ -74,12 +76,13 @@ const SharedOptions: SharedOptionsType = {
customStreams, customStreams,
logLevel: LogLevel.info, logLevel: LogLevel.info,
logLevelMapping, logLevelMapping,
customTypes: [],
labels: []
}; };
export type LoggerMasterOptions = SharedOptionsType & { export type LoggerMasterOptions = SharedOptionsType & {
fileRotationFreq?: number, fileRotationFreq?: number,
directory?: string, directory?: string,
customTypes?: string[],
customTypeMapping?: { [key: string]: string }, customTypeMapping?: { [key: string]: string },
customColours?: { [key: string]: number | string }, customColours?: { [key: string]: number | string },
broadcastLevel?: number, broadcastLevel?: number,
@ -101,9 +104,11 @@ const MasterOptions: LoggerMasterOptions = {
skipFileWrite skipFileWrite
}; };
export type LoggerClientOptions = SharedOptionsType; export type LoggerClientOptions = SharedOptionsType & {
name?: string
};
const ClientOptions = { const ClientOptions: LoggerClientOptions = {
...SharedOptions ...SharedOptions
}; };

View File

@ -1,23 +1,12 @@
// const { inspect } = require('node:util'); import Defaults, { LoggerClientOptions } from './Defaults.js';
// const Defaults = require('./Defaults');
import Defaults from './Defaults.js';
import { inspect } from 'node:util'; import { inspect } from 'node:util';
import { LogFunction, WriteOptions } from './Types.js'; import { LogFunction, WriteOptions } from './Types.js';
import { Logger } from './LoggerInterface.js'; import { Logger } from './LoggerInterface.js';
import { makePlainError } from './Shared.js'; import { makePlainError } from './Shared.js';
type ClientOptions = {
name?: string,
guard?: string,
logLevel?: number,
customTypes?: string[],
logLevelMapping?: {
[key: string]: number
}
}
type TransportOptions = { type TransportOptions = {
type: string type: string,
labels?: string[]
} }
class LoggerClient implements Logger class LoggerClient implements Logger
@ -32,10 +21,10 @@ class LoggerClient implements Logger
#_logLevelMapping: { [key: string]: number }; #_logLevelMapping: { [key: string]: number };
#_name: string; #_name: string;
#types: string[]; #types: string[];
#labels: string[];
constructor (opts: ClientOptions = Defaults.ClientOptions) constructor (opts: LoggerClientOptions = Defaults.ClientOptions)
{ {
this.#_name = opts.name || opts.constructor.name; this.#_name = opts.name || opts.constructor.name;
if (this.#_name === 'Object') if (this.#_name === 'Object')
this.#_name = 'unknown'; this.#_name = 'unknown';
@ -49,17 +38,20 @@ class LoggerClient implements Logger
this.#_logLevelMapping = { ...Defaults.ClientOptions.logLevelMapping, ...opts.logLevelMapping }; this.#_logLevelMapping = { ...Defaults.ClientOptions.logLevelMapping, ...opts.logLevelMapping };
this.#_guard = opts.guard || Defaults.ClientOptions.guard as string; this.#_guard = opts.guard || Defaults.ClientOptions.guard as string;
this.#_logLevel = opts.logLevel ?? Defaults.ClientOptions.logLevel as number; this.#_logLevel = opts.logLevel ?? Defaults.ClientOptions.logLevel as number;
this.#labels = opts.labels ?? [];
for (const type of this.#types) for (const type of this.#types)
{ {
if (typeof this.#_logLevelMapping[type] === 'undefined') if (typeof this.#_logLevelMapping[type] === 'undefined')
throw new Error(`Missing logLevelMapping for type ${type}`); throw new Error(`Missing logLevelMapping for type ${type}`);
Object.defineProperty(this, type, { Object.defineProperty(this, type, {
value: (msg: string, o: WriteOptions) => this.#transport(msg, { ...o, type }) value: (msg: string, o: WriteOptions) =>
{
const { labels = [], ...writeOpts } = o;
this.#transport(msg, { ...writeOpts, type, labels: [ ...this.#labels, ...labels ] });
}
}); });
} }
} }
get logLevel () get logLevel ()

View File

@ -52,13 +52,14 @@ class MasterLogger implements Logger
#pruneInterval: NodeJS.Timer; #pruneInterval: NodeJS.Timer;
#pruneDays: number; #pruneDays: number;
#skipFileWrite: boolean; #skipFileWrite: boolean;
#labels: string[];
constructor (config = Defaults.MasterOptions) constructor (config = Defaults.MasterOptions)
{ {
const { const {
directory, customTypes = [], customStreams = [], customTypeMapping, directory, customTypes = [], customStreams = [], customTypeMapping,
customColours, guard, fileRotationFreq, logLevel, logLevelMapping, customColours, guard, fileRotationFreq, logLevel, logLevelMapping,
webhook, broadcastLevel, pruneDays, skipFileWrite webhook, broadcastLevel, pruneDays, skipFileWrite, labels = []
} = { ...Defaults.MasterOptions, ...config }; } = { ...Defaults.MasterOptions, ...config };
if (!directory) if (!directory)
@ -106,6 +107,7 @@ class MasterLogger implements Logger
return prev; return prev;
}, {} as FuncsType); }, {} as FuncsType);
this.#labels = labels;
this.#streamTypes = [ ...customStreams, 'error', 'default' ]; this.#streamTypes = [ ...customStreams, 'error', 'default' ];
this.#streamTypeMapping = { ...Defaults.TypeStream, ...customTypeMapping }; this.#streamTypeMapping = { ...Defaults.TypeStream, ...customTypeMapping };
if (this.#skipFileWrite) if (this.#skipFileWrite)
@ -197,15 +199,15 @@ class MasterLogger implements Logger
{ {
if (!msg[this.#_guard]) if (!msg[this.#_guard])
return; return;
const { message, type, header, broadcast } = msg; const { message, type, header, broadcast, labels } = msg;
const func = this[type] as LogFunction; const func = this[type] as LogFunction;
if (!func) if (!func)
throw new Error(`Attempted use of invalid logging function of type: ${type}, ensure client and master have the same type definitions.`); throw new Error(`Attempted use of invalid logging function of type: ${type}, ensure client and master have the same type definitions.`);
func(message, { subheader: header, shard, broadcast }); func(message, { subheader: header, shard, broadcast, labels });
}); });
} }
write (type = 'info', text: string | object | Error, { subheader = '', shard, broadcast = false }: WriteOptions = {}) write (type = 'info', text: string | object | Error, { subheader = '', shard, broadcast = false, labels = [] }: WriteOptions = {})
{ {
let colour = this.#colourFuncs[type]; let colour = this.#colourFuncs[type];
if (!colour) if (!colour)
@ -231,14 +233,14 @@ class MasterLogger implements Logger
} }
if ((broadcast || (this.#_broadcastLevel <= this.#_logLevelMapping[type])) && this.#webhook) if ((broadcast || (this.#_broadcastLevel <= this.#_logLevelMapping[type])) && this.#webhook)
{ {
const description = (subheader.length ? `**${subheader}**\n` : '') + `\`\`\`${text}\`\`\``; const description = (subheader.length ? `**${subheader}**: ${process.env.NODE_ENV ?? 'production'}\n` : '') + `\`\`\`${text}\`\`\``;
this.#webhook.send({ this.#webhook.send({
embeds: [{ embeds: [{
title: `[__${type.toUpperCase()}__] ${this._shard(shard)}`, title: `[__${type.toUpperCase()}__] ${this._shard(shard)}`,
description, description,
color: colour.int, color: colour.int,
footer: { footer: {
text: `ENV: ${process.env.NODE_ENV ?? 'production'}` text: [ ...labels, ...this.#labels ].join(', ') ?? ''
} }
}] }]
}); });

View File

@ -7,16 +7,18 @@ type Shard = {
type WriteOptions = { type WriteOptions = {
subheader?: string, subheader?: string,
shard?: Shard, shard?: Shard,
broadcast?: boolean broadcast?: boolean,
labels?: string[]
} }
type IPCMessage = { type IPCMessage = {
[key: string]: string | boolean [key: string]: string | string[] | boolean
_guard: string _guard: string
type: string, type: string,
message: string, message: string,
header: string, header: string,
broadcast: boolean broadcast: boolean,
labels: string[]
} }
type LogFunction = (str: string, opts?: WriteOptions) => void type LogFunction = (str: string, opts?: WriteOptions) => void