diff --git a/README.md b/README.md index d5e0484..6ea5b06 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,6 @@ The child processes are expected to be attached with the attach() method found i guard: '_logger', // Message guard, e.g this property has to be true in the IPC message for the logger to read it loglevel: false, // On the master logger this determines whether the output is written to console (i.e. will always be written to file), on the client this determines whether it is sent to the master at all customTypes: [], // Log types, defaults are 'error', 'warn', 'info', 'debug', 'status'. Each one of these has an associated shorthand function, the custom ones will receive one too, e.g. adding 'access' to the custom types will add a logger.access() function - - /////// MASTER EXCLUSIVE - customStreams: [], // File streams, by default there are streams for error and default - customTypeMapping: {}, // This maps a type to a stream, e.g. adding "warn": "error" will pipe any warnings to the error log file - customColors: {}, // Supports any colours chalk.js supports, e.g. "warn": "green" will turn warning outputs green - fileRotationFreq: 1, // How frequently to roate files in days - will not work with anything less than 1 day currently - directory: './logs', // Directory in which to write log files logLevelMapping: { debug: 0, info: 1, @@ -33,6 +26,13 @@ The child processes are expected to be attached with the attach() method found i warn: 3, error: 4 } + + /////// MASTER EXCLUSIVE + customStreams: [], // File streams, by default there are streams for error and default + customTypeMapping: {}, // This maps a type to a stream, e.g. adding "warn": "error" will pipe any warnings to the error log file + customColours: {}, // Supports any colours chalk.js supports, e.g. "warn": "green" will turn warning outputs green + fileRotationFreq: 1, // How frequently to roate files in days - will not work with anything less than 1 day currently + directory: './logs', // Directory in which to write log files broadcastLevel: 4, // Level at which to broadcast to webhook if supplied webhook: { url: string @@ -40,7 +40,7 @@ The child processes are expected to be attached with the attach() method found i } ``` -**Log levels** +**Built-in log levels** 0 - Debug 1 - Info 2 - Status diff --git a/index.ts b/index.ts index 3dd9f40..0516524 100644 --- a/index.ts +++ b/index.ts @@ -1,4 +1,15 @@ import MasterLogger from "./src/MasterLogger.js"; import LoggerClient from './src/LoggerClient.js'; +import Defaults, { LogLevel } from "./src/Defaults.js"; -export { MasterLogger, LoggerClient }; \ No newline at end of file +const addLogLevel = (name: string, level: number) => { + if (typeof name !== 'string') + throw new Error('Name must be a string'); + if (typeof level !== 'number') + throw new Error('Level must be a number'); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + LogLevel[LogLevel[name] = level] = name; +}; + +export { MasterLogger, LoggerClient, Defaults, LogLevel, addLogLevel }; \ No newline at end of file diff --git a/src/Defaults.ts b/src/Defaults.ts index 563182a..8092180 100644 --- a/src/Defaults.ts +++ b/src/Defaults.ts @@ -1,4 +1,13 @@ -const ColourCodes: {[key: string]: number} = { +enum LogLevel { + debug = 0, + info = 1, + status = 2, + warn = 3, + error = 4 +} +export { LogLevel }; + +const ColourCodes: { [key: string]: number } = { error: 0xe88388, warn: 0xf9d472, info: 0x76a9d8, @@ -6,56 +15,68 @@ const ColourCodes: {[key: string]: number} = { status: 0x72d4d7 }; +const Types = [ + 'error', + 'warn', + 'info', + 'debug', + 'status' +]; + +const TypeStream = { // If none defined they are sent to default + error: 'error' +}; + +const Colours = { + error: 'red', + warn: 'yellow', + info: 'blue', + debug: 'magenta', + status: 'cyanBright' +}; + +const customColours: { [key: string]: number | string } = {}; +const customTypeMapping: { [key: string]: string } = {}; +const customStreams: string[] = []; +const customTypes: string[] = []; +const guard = '_logger'; +const webhook: { url?: string, id?: string, token?: string } = {}; + +const logLevelMapping = { + debug: LogLevel.debug, + info: LogLevel.info, + status: LogLevel.status, + warn: LogLevel.warn, + error: LogLevel.error +}; + +const SharedOptions = { + guard, + customStreams, + logLevel: LogLevel.info, + logLevelMapping, +}; + +const MasterOptions = { + ...SharedOptions, + fileRotationFreq: 1, + directory: './logs', + customTypes, + customTypeMapping, + customColours, + broadcastLevel: 4, + webhook, +}; + +const ClientOptions = { + ...SharedOptions +}; + export default { - Types: [ - 'error', - 'warn', - 'info', - 'debug', - 'status' - ], - TypeStream: { // If none defined they are sent to default - error: 'error' - }, - Colours: { - error: 'red', - warn: 'yellow', - info: 'blue', - debug: 'magenta', - status: 'cyanBright' - }, + Types, + TypeStream, + Colours, ColourCodes, - MasterOptions: { - fileRotationFreq: 1, - directory: './logs', - customTypes: [], - customStreams: [], - customTypeMapping: {}, - customColors: {}, - guard: '_logger', - broadcastLevel: 4, - logLevel: 1, - logLevelMapping: { - debug: 0, - info: 1, - status: 2, - warn: 3, - error: 4 - }, - webhook: { - url: null - }, - }, - ClientOptions: { - guard: '_logger', - customStreams: [], - logLevel: 1, - logLevelMapping: { - debug: 0, - info: 1, - status: 2, - warn: 3, - error: 4 - } - } + MasterOptions, + ClientOptions }; \ No newline at end of file diff --git a/src/MasterLogger.ts b/src/MasterLogger.ts index c9de267..d44f5ca 100644 --- a/src/MasterLogger.ts +++ b/src/MasterLogger.ts @@ -9,8 +9,9 @@ import { inspect } from 'node:util'; // Own import DiscordWebhook from '@navy.gif/discord-webhook'; -import Defaults from './Defaults.js'; +import Defaults, { LogLevel } from './Defaults.js'; import { Shard, WriteOptions } from './Types.js'; +import { addLogLevel } from '../index.js'; const DAY = 1000 * 60 * 60 * 24; @@ -34,7 +35,7 @@ type WriteStreams = { class MasterLogger { #_guard: string; - #_logLevel: number; + #_logLevel: LogLevel; #_logLevelMapping: {[key: string]: number}; #_broadcastLevel: number; @@ -54,7 +55,7 @@ class MasterLogger { const { directory, customTypes, customStreams, customTypeMapping, - customColors, guard, fileRotationFreq, logLevel, logLevelMapping, + customColours, guard, fileRotationFreq, logLevel, logLevelMapping, webhook, broadcastLevel } = { ...Defaults.MasterOptions, ...config }; @@ -64,6 +65,10 @@ class MasterLogger { this.#_broadcastLevel = broadcastLevel; this.#_logLevel = logLevel; this.#_logLevelMapping = { ...Defaults.MasterOptions.logLevelMapping, ...logLevelMapping }; + if (logLevelMapping) + Object.entries(logLevelMapping).forEach(([ name, level ]) => { + addLogLevel(name, level); + }); this.#_guard = guard; this.#types = [ ...customTypes, ...Defaults.Types ]; @@ -72,7 +77,7 @@ class MasterLogger { value: (msg: string, opts: WriteOptions) => this.write(type, msg, opts) }); } - this.#colours = { ...Defaults.Colours, ...customColors }; + this.#colours = { ...Defaults.Colours, ...customColours }; this.#colourFuncs = Object.entries(this.#colours).reduce((prev: FuncsType, [ type, colour ]: (string | number)[]) => { if (typeof colour === 'number') @@ -103,7 +108,7 @@ class MasterLogger { this.#rotateTO = setTimeout(this.rotateLogFiles.bind(this), this.#startDay + this.#rotationFreq - Date.now()); if (webhook && webhook.url) { - this.#webhook = new DiscordWebhook({ url: webhook.url }); + this.#webhook = new DiscordWebhook(webhook); this.#webhook.fetch(); } @@ -121,22 +126,18 @@ class MasterLogger { return Object.keys(this.#_logLevelMapping); } - setLogLevel (level: string | number = 'info') { - if (typeof level === 'number') + setLogLevel (level: number) { + if (LogLevel[level] in this.#_logLevelMapping) this.#_logLevel = level; - else if (typeof level === 'string') - this.#_logLevel = this.#_logLevelMapping[level.toLowerCase()]; else - throw new Error(`Invalid log level type, expected string or number, got ${typeof level}`); + throw new Error(`Not a valid log level`); } - setBroadcastLevel (level: string | number) { - if (!level) - throw new Error('Missing level'); - if (typeof level === 'number') + setBroadcastLevel (level: number) { + if (LogLevel[level] in this.#_logLevelMapping) this.#_broadcastLevel = level; - else if (typeof level === 'string') - this.#_broadcastLevel = this.#_logLevelMapping[level.toLowerCase()]; + else + throw new Error('Not a valid log level'); } attach (shard: Shard) { diff --git a/src/Types.ts b/src/Types.ts index 35de323..255c877 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -10,5 +10,4 @@ type WriteOptions = { broadcast?: boolean } - export { WriteOptions, Shard }; \ No newline at end of file diff --git a/test/otherProcess.js b/test/otherProcess.js index 6243474..354cc60 100644 --- a/test/otherProcess.js +++ b/test/otherProcess.js @@ -5,7 +5,7 @@ const logger = new LoggerClient({ customTypes: [ 'access' ], customStreams: [ 'access' ], customTypeMapping: { access: 'access', warn: 'error' }, - customColors: { access: 'green' }, + customColours: { access: 'green' }, logLevelMapping: { access: 2 } }); diff --git a/test/test.cjs b/test/test.cjs index 9454e8f..ac54851 100644 --- a/test/test.cjs +++ b/test/test.cjs @@ -1,11 +1,17 @@ // eslint-disable-next-line @typescript-eslint/no-var-requires -const { MasterLogger } = require('../build/cjs'); +const { MasterLogger, LogLevel, addLogLevel } = require('../build/cjs'); +console.log(LogLevel.debug === LogLevel[0], LogLevel.debug === LogLevel[LogLevel[0]], LogLevel[0]); +// LogLevel[LogLevel.access = 6] = 'access'; +addLogLevel('access', 6); +console.log(LogLevel); + + const logger = new MasterLogger({ debug: true, customTypes: [ 'access' ], customStreams: [ 'access' ], customTypeMapping: { access: 'access', warn: 'error' }, - customColors: { + customColours: { access: 'green', // error: '#FF0000' }, @@ -17,6 +23,9 @@ const logger = new MasterLogger({ } }); console.log(logger); +logger.setLogLevel(LogLevel.access); +console.log(logger.logLevel); +process.exit(); logger.info('Test'); const spawn = (child) => { diff --git a/test/test.js b/test/test.js index 4e4ce22..6c7b090 100644 --- a/test/test.js +++ b/test/test.js @@ -17,7 +17,7 @@ const main = async () => { customTypes: [ 'access' ], customStreams: [ 'access' ], customTypeMapping: { access: 'access', warn: 'error' }, - customColors: { + customColours: { access: 'green', // error: '#FF0000' },