ntlogger 2.2.3 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/LICENSE +674 -674
  2. package/README.md +89 -89
  3. package/index.js +57 -57
  4. package/lib/logger.js +219 -209
  5. package/package.json +38 -29
package/lib/logger.js CHANGED
@@ -1,210 +1,220 @@
1
- /**
2
- * NightTimeLogger: A Custom Ready-To-Go Logging Wrapper Built on Winston
3
- *
4
- * This utility is a customized wrapper around the Winston logging library.
5
- * It offers different log levels and formats and can be easily integrated into
6
- * any Node.js project.
7
- *
8
- * Author: Kevin R. (Kvrnn#6940, Syntax#5569)
9
- * Date: 03/31/2024
10
- * Current Version: 2.1.2
11
- * License: GPL-3.0
12
- */
13
- const winston = require('winston');
14
- const crypto = require('crypto');
15
-
16
- // Define a map to hold the logger instances by their location
17
- const loggerInstances = new Map();
18
-
19
- const customSettings = {
20
- levels: {
21
- internal: 6,
22
- trace: 5,
23
- debug: 4,
24
- info: 3,
25
- warn: 2,
26
- error: 1,
27
- fatal: 0,
28
- },
29
- colors: {
30
- internal: '\x1b[93m', // Bright yellow
31
- trace: '\x1b[90m', // Light gray
32
- debug: '\x1b[37m', // White
33
- info: '\x1b[32m', // Green
34
- warn: '\x1b[33m', // Yellow
35
- error: '\x1b[31m', // Red
36
- fatal: '\x1b[35m', // Magenta
37
- },
38
- };
39
-
40
-
41
- const randomBrightColor = () => {
42
- // Configuration variables
43
- const minLuminanceThreshold = 0.03928;
44
- const linearConversionDivider = 12.92;
45
- const linearConversionBase = 1.055;
46
- const linearConversionExponent = 2.4;
47
- const luminanceCoefficients = { r: 0.2126, g: 0.7152, b: 0.0722 };
48
- // const minContrastRatio = 4.5; // WCAG AA standard for normal text
49
- const minContrastRatio = 2.5; // I like 2.5 will change if any issues arise
50
-
51
- // Helper function to convert sRGB to linear RGB
52
- const convertToLinear = (colorComponent) => {
53
- const scaledComponent = colorComponent / 255;
54
- return scaledComponent <= minLuminanceThreshold ? scaledComponent / linearConversionDivider
55
- : Math.pow((scaledComponent + 0.055) / linearConversionBase, linearConversionExponent);
56
- };
57
-
58
- while (true) {
59
- // Generate random RGB values
60
- const [red, green, blue] = [0, 1, 2].map(() => Math.floor(Math.random() * 256));
61
-
62
- // Convert to linear RGB values
63
- const [rLinear, gLinear, bLinear] = [red, green, blue].map(convertToLinear);
64
-
65
- // Calculate luminance
66
- const luminance = luminanceCoefficients.r * rLinear + luminanceCoefficients.g * gLinear + luminanceCoefficients.b * bLinear;
67
-
68
- // Calculate contrast ratio against black (which has a luminance of 0)
69
- const contrastRatio = (luminance + 0.05) / 0.05;
70
-
71
- // Check if the color meets the contrast ratio criterion
72
- if (contrastRatio >= minContrastRatio) {
73
- return `#${[red, green, blue].map(x => x.toString(16).padStart(2, '0')).join('')}`;
74
- }
75
- }
76
- };
77
-
78
- const generateSessionId = () => {
79
- return crypto.createHash('sha256').update(Date.now().toString()).digest('hex');
80
- };
81
-
82
- const sessionId = generateSessionId(); // Generate session ID once
83
- const color = randomBrightColor();
84
-
85
- // Custom console formatter with random color for session ID and set color for log level and message
86
- const consoleFormatter = (config) => winston.format.combine(
87
- winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
88
- winston.format.printf(({ timestamp, level, message, ...meta }) => {
89
- const shortSessionId = sessionId.substring(sessionId.length - 6); // Get the last 6 characters of the session ID
90
- const paddedLevel = level.padEnd(8); // Pad the level to ensure consistent spacing
91
-
92
- // Retrieve the corresponding ANSI color code for the level from custom settings
93
- const levelColor = customSettings.colors[level] || ''; // Default to no color if the level is unknown
94
- const resetCode = '\x1b[0m';
95
-
96
- // Apply the color to the padded level and the session ID
97
- // Note: The session ID color remains based on the 'color' variable
98
- return `${timestamp} [${levelColor}${paddedLevel}${resetCode}] [\x1b[38;2;${parseInt(color.substring(1, 3), 16)};${parseInt(color.substring(3, 5), 16)};${parseInt(color.substring(5, 7), 16)}mID: ${shortSessionId}${resetCode}] [${meta.location || 'Unknown'}]: ${levelColor}${message}${resetCode}`;
99
- }),
100
- );
101
-
102
- // Formatter for file logging which shows the full session ID
103
- const fileFormatter = (config) => winston.format.combine(
104
- winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
105
- winston.format.printf(({ timestamp, level, message, ...meta }) => {
106
- const paddedLevel = level.padEnd(8); // Pad the level to ensure consistent spacing
107
-
108
- return `${timestamp} [${paddedLevel}] [ID: ${sessionId}] [${meta.location || 'Unknown'}]: ${message} ${
109
- Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''
110
- }`;
111
- }),
112
- );
113
-
114
- const createLoggerInstance = (location = "Unknown", config = {}) => {
115
- // Configuration options
116
- const {
117
- level = 'info',
118
- console = true,
119
- debug = false,
120
- file = true,
121
- filename = `${location}.log`,
122
- path = './logs',
123
- maxSize = 1048576,
124
- maxFiles = 5,
125
- timestamp = true
126
- } = config;
127
-
128
- let logTransport = [].filter(Boolean);
129
-
130
- if (console) {
131
- const consoleFormat = consoleFormatter(config);
132
-
133
- logTransport.push(new winston.transports.Console({ format: consoleFormat }),);
134
- }
135
-
136
- if (file) {
137
- const fileFormat = fileFormatter(config);
138
-
139
- // If you want really verbose logging, such as, log files per new logging instance with each level, follow this example
140
- // logTransport.push(
141
- // new winston.transports.File({ filename: `${path}/${filename}`, level: 'fatal', format:fileFormat ,maxsize: maxSize, maxFiles: maxFiles }),
142
- // new winston.transports.File({ filename: `${path}/${filename}`, level: 'error', format:fileFormat ,maxsize: maxSize, maxFiles: maxFiles }),
143
- // new winston.transports.File({ filename: `${path}/${filename}`, format:fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
144
- // );
145
-
146
- // If you want to logger instance of same level to the same file, follow this example (default)
147
- logTransport.push(
148
- new winston.transports.File({ filename: `${path}/fatal.log`, level: 'fatal', format: fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
149
- new winston.transports.File({ filename: `${path}/error.log`, level: 'error', format: fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
150
- new winston.transports.File({ filename: `${path}/combined.log`, format: fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
151
- );
152
- }
153
-
154
- // Create a new logger instance
155
- const logger = winston.createLogger({
156
- level: level,
157
- levels: customSettings.levels,
158
- transports: logTransport,
159
- defaultMeta: {
160
- location,
161
- timeCreated: new Date().toLocaleTimeString('en-US', {hour12: true, hour: '2-digit', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3})
162
- }
163
- });
164
-
165
- // Cache the newly created logger instance
166
- loggerInstances.set(location, logger);
167
-
168
- if (debug === true) {
169
- // Extract RGB components from the color string
170
- const rgb = {
171
- r: parseInt(color.slice(1, 3), 16),
172
- g: parseInt(color.slice(3, 5), 16),
173
- b: parseInt(color.slice(5, 7), 16)
174
- };
175
-
176
- // Construct ANSI escape code for the RGB color
177
- const colorCode = `\x1b[38;2;${rgb.r};${rgb.g};${rgb.b}m`;
178
- const resetCode = `\x1b[0m`;
179
-
180
- logger.internal(`Logger instance created from ${location} with session ID: ${colorCode}${sessionId.slice(-6)}${resetCode}`);
181
- logger.internal(`Logger instance created from ${location} with color: ${colorCode}${color}${resetCode}`);
182
- logger.internal(`Logger instance created from ${location} with log level: ${colorCode}${logger.level}${resetCode}`);
183
- }
184
-
185
- return logger;
186
- }
187
-
188
- /***
189
- * Logger function
190
- *
191
- * @param {string} location - The location of the logger instance
192
- * @param {object} config - Configuration options for the logger instance
193
- * @returns {object} - The logger instance
194
- */
195
- const logger = (location = "Unknown", config = {}) => {
196
- // Check if a logger for the given location already exists
197
- if (loggerInstances.has(location)) {
198
- // If it does, grab the existing logger instance from the map
199
- const logger = loggerInstances.get(location);
200
-
201
- logger.internal(`Logger instance retrieved for location ${location}`); // Log the retrieval of the logger instance
202
- return logger;
203
- }
204
-
205
- // If not, create a new logger instance for the location
206
- return createLoggerInstance(location, config);
207
- };
208
-
209
- // Export a function to create or return the existing logger instance
1
+ /**
2
+ * NightTimeLogger: A Custom Ready-To-Go Logging Wrapper Built on Winston
3
+ *
4
+ * This utility is a customized wrapper around the Winston logging library.
5
+ * It offers different log levels and formats and can be easily integrated into
6
+ * any Node.js project.
7
+ *
8
+ * Author: Kevin R. (Kvrnn#6940, Syntax#5569)
9
+ * Date: 03/31/2024
10
+ * Current Version: 2.1.2
11
+ * License: GPL-3.0
12
+ */
13
+ const winston = require('winston');
14
+ const crypto = require('crypto');
15
+
16
+ const { initPlugins, compilePluginComponents} = require('../plugins/index.js');
17
+
18
+ // Define a map to hold the logger instances by their location
19
+ const loggerInstances = new Map();
20
+
21
+ const customSettings = {
22
+ levels: {
23
+ internal: 6,
24
+ trace: 5,
25
+ debug: 4,
26
+ info: 3,
27
+ warn: 2,
28
+ error: 1,
29
+ fatal: 0,
30
+ },
31
+ colors: {
32
+ internal: '\x1b[93m', // Bright yellow
33
+ trace: '\x1b[90m', // Light gray
34
+ debug: '\x1b[37m', // White
35
+ info: '\x1b[32m', // Green
36
+ warn: '\x1b[33m', // Yellow
37
+ error: '\x1b[31m', // Red
38
+ fatal: '\x1b[35m', // Magenta
39
+ },
40
+ };
41
+
42
+
43
+ const randomBrightColor = () => {
44
+ // Configuration variables
45
+ const minLuminanceThreshold = 0.03928;
46
+ const linearConversionDivider = 12.92;
47
+ const linearConversionBase = 1.055;
48
+ const linearConversionExponent = 2.4;
49
+ const luminanceCoefficients = { r: 0.2126, g: 0.7152, b: 0.0722 };
50
+ // const minContrastRatio = 4.5; // WCAG AA standard for normal text
51
+ const minContrastRatio = 2.5; // I like 2.5 will change if any issues arise
52
+
53
+ // Helper function to convert sRGB to linear RGB
54
+ const convertToLinear = (colorComponent) => {
55
+ const scaledComponent = colorComponent / 255;
56
+ return scaledComponent <= minLuminanceThreshold ? scaledComponent / linearConversionDivider
57
+ : Math.pow((scaledComponent + 0.055) / linearConversionBase, linearConversionExponent);
58
+ };
59
+
60
+ while (true) {
61
+ // Generate random RGB values
62
+ const [red, green, blue] = [0, 1, 2].map(() => Math.floor(Math.random() * 256));
63
+
64
+ // Convert to linear RGB values
65
+ const [rLinear, gLinear, bLinear] = [red, green, blue].map(convertToLinear);
66
+
67
+ // Calculate luminance
68
+ const luminance = luminanceCoefficients.r * rLinear + luminanceCoefficients.g * gLinear + luminanceCoefficients.b * bLinear;
69
+
70
+ // Calculate contrast ratio against black (which has a luminance of 0)
71
+ const contrastRatio = (luminance + 0.05) / 0.05;
72
+
73
+ // Check if the color meets the contrast ratio criterion
74
+ if (contrastRatio >= minContrastRatio) {
75
+ return `#${[red, green, blue].map(x => x.toString(16).padStart(2, '0')).join('')}`;
76
+ }
77
+ }
78
+ };
79
+
80
+ const generateSessionId = () => {
81
+ return crypto.createHash('sha256').update(Date.now().toString()).digest('hex');
82
+ };
83
+
84
+ const sessionId = generateSessionId(); // Generate session ID once
85
+ const color = randomBrightColor();
86
+
87
+ // Custom console formatter with random color for session ID and set color for log level and message
88
+ const consoleFormatter = (config) => winston.format.combine(
89
+ winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
90
+ winston.format.printf(({ timestamp, level, message, ...meta }) => {
91
+ const shortSessionId = sessionId.substring(sessionId.length - 6); // Get the last 6 characters of the session ID
92
+ const paddedLevel = level.padEnd(8); // Pad the level to ensure consistent spacing
93
+
94
+ // Retrieve the corresponding ANSI color code for the level from custom settings
95
+ const levelColor = customSettings.colors[level] || ''; // Default to no color if the level is unknown
96
+ const resetCode = '\x1b[0m';
97
+
98
+ // Apply the color to the padded level and the session ID
99
+ // Note: The session ID color remains based on the 'color' variable
100
+ return `${timestamp} [${levelColor}${paddedLevel}${resetCode}] [\x1b[38;2;${parseInt(color.substring(1, 3), 16)};${parseInt(color.substring(3, 5), 16)};${parseInt(color.substring(5, 7), 16)}mID: ${shortSessionId}${resetCode}] [${meta.location || 'Unknown'}]: ${levelColor}${message}${resetCode}`;
101
+ }),
102
+ );
103
+
104
+ // Formatter for file logging which shows the full session ID
105
+ const fileFormatter = (config) => winston.format.combine(
106
+ winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
107
+ winston.format.printf(({ timestamp, level, message, ...meta }) => {
108
+ const paddedLevel = level.padEnd(8); // Pad the level to ensure consistent spacing
109
+
110
+ return `${timestamp} [${paddedLevel}] [ID: ${sessionId}] [${meta.location || 'Unknown'}]: ${message} ${
111
+ Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''
112
+ }`;
113
+ }),
114
+ );
115
+
116
+ const createLoggerInstance = (location = "Unknown", config = {}, transports) => {
117
+ // Configuration options
118
+ const {
119
+ level = 'info',
120
+ console = true,
121
+ debug = false,
122
+ file = true,
123
+ filename = `${location}.log`,
124
+ path = './logs',
125
+ maxSize = 1048576,
126
+ maxFiles = 5,
127
+ timestamp = true
128
+ } = config;
129
+
130
+ let logTransport = [].filter(Boolean);
131
+
132
+ if (console) {
133
+ const consoleFormat = consoleFormatter(config);
134
+
135
+ logTransport.push(new winston.transports.Console({ format: consoleFormat }),);
136
+ }
137
+
138
+ if (file) {
139
+ const fileFormat = fileFormatter(config);
140
+
141
+ // If you want really verbose logging, such as, log files per new logging instance with each level, follow this example
142
+ // logTransport.push(
143
+ // new winston.transports.File({ filename: `${path}/${filename}`, level: 'fatal', format:fileFormat ,maxsize: maxSize, maxFiles: maxFiles }),
144
+ // new winston.transports.File({ filename: `${path}/${filename}`, level: 'error', format:fileFormat ,maxsize: maxSize, maxFiles: maxFiles }),
145
+ // new winston.transports.File({ filename: `${path}/${filename}`, format:fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
146
+ // );
147
+
148
+ // If you want to logger instance of same level to the same file, follow this example (default)
149
+ logTransport.push(
150
+ new winston.transports.File({ filename: `${path}/fatal.log`, level: 'fatal', format: fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
151
+ new winston.transports.File({ filename: `${path}/error.log`, level: 'error', format: fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
152
+ new winston.transports.File({ filename: `${path}/combined.log`, format: fileFormat, maxsize: maxSize, maxFiles: maxFiles }),
153
+ );
154
+ }
155
+ if (transports) {logTransport = logTransport.concat
156
+ (transports);}
157
+
158
+ // Create a new logger instance
159
+ const logger = winston.createLogger({
160
+ level: level,
161
+ levels: customSettings.levels,
162
+ transports: logTransport,
163
+ defaultMeta: {
164
+ location,
165
+ timeCreated: new Date().toLocaleTimeString('en-US', {hour12: true, hour: '2-digit', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3})
166
+ }
167
+ });
168
+
169
+ // Cache the newly created logger instance
170
+ loggerInstances.set(location, logger);
171
+
172
+ if (debug === true) {
173
+ // Extract RGB components from the color string
174
+ const rgb = {
175
+ r: parseInt(color.slice(1, 3), 16),
176
+ g: parseInt(color.slice(3, 5), 16),
177
+ b: parseInt(color.slice(5, 7), 16)
178
+ };
179
+
180
+ // Construct ANSI escape code for the RGB color
181
+ const colorCode = `\x1b[38;2;${rgb.r};${rgb.g};${rgb.b}m`;
182
+ const resetCode = `\x1b[0m`;
183
+
184
+ logger.internal(`Logger instance created from ${location} with session ID: ${colorCode}${sessionId.slice(-6)}${resetCode}`);
185
+ logger.internal(`Logger instance created from ${location} with color: ${colorCode}${color}${resetCode}`);
186
+ logger.internal(`Logger instance created from ${location} with log level: ${colorCode}${logger.level}${resetCode}`);
187
+ }
188
+
189
+ return logger;
190
+ }
191
+
192
+ /***
193
+ * Logger function
194
+ *
195
+ * @param {string} location - The location of the logger instance
196
+ * @param {object} config - Configuration options for the logger instance
197
+ * @returns {object} - The logger instance
198
+ */
199
+ const logger = (location = "Unknown", config = {}) => {
200
+ // Check if a logger for the given location already exists
201
+ if (loggerInstances.has(location)) {
202
+ // If it does, grab the existing logger instance from the map
203
+ const logger = loggerInstances.get(location);
204
+
205
+ logger.internal(`Logger instance retrieved for location ${location}`); // Log the retrieval of the logger instance
206
+ return logger;
207
+ }
208
+
209
+ let transports = null;
210
+ // Initialize plugins if they are provided in the configuration
211
+ if (config.plugins) {
212
+ transports = initPlugins(config.plugins)
213
+ }
214
+
215
+ // If not, create a new logger instance for the location
216
+ return createLoggerInstance(location, config, transports);
217
+ };
218
+
219
+ // Export a function to create or return the existing logger instance
210
220
  module.exports = logger;
package/package.json CHANGED
@@ -1,29 +1,38 @@
1
- {
2
- "name": "ntlogger",
3
- "version": "2.2.3",
4
- "repository": {
5
- "type": "git",
6
- "url": "git+https://github.com/NightSquawk/NightTimeLogger.git"
7
- },
8
- "author": "Kevin R. (Kvrnn#6940, Syntax#5569)",
9
- "description": "A Custom Ready-To-Go Logging Wrapper Built on Winston",
10
- "keywords": [
11
- "logger",
12
- "winston wrapper",
13
- "logger wrapper",
14
- "wrapper",
15
- "winston logger",
16
- "custom logger",
17
- "logging",
18
- "log management",
19
- "logging utility"
20
- ],
21
- "files": [
22
- "index.js",
23
- "lib/*.js"
24
- ],
25
- "license": "GPL-3.0",
26
- "dependencies": {
27
- "winston": "^3.13"
28
- }
29
- }
1
+ {
2
+ "name": "ntlogger",
3
+ "version": "2.3.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/NightSquawk/NightTimeLogger.git"
7
+ },
8
+ "author": "Kevin R. (Kvrnn#6940, Syntax#5569)",
9
+ "description": "A Custom Ready-To-Go Logging Wrapper Built on Winston",
10
+ "keywords": [
11
+ "logger",
12
+ "winston wrapper",
13
+ "logger wrapper",
14
+ "wrapper",
15
+ "winston logger",
16
+ "custom logger",
17
+ "logging",
18
+ "log management",
19
+ "logging utility",
20
+ "sentry compatible",
21
+ "mysql compatible"
22
+ ],
23
+ "files": [
24
+ "index.js",
25
+ "lib/*.js"
26
+ ],
27
+ "license": "GPL-3.0",
28
+ "dependencies": {
29
+ "@sentry/node": "^8.17.0",
30
+ "mysql2": "^3.10.2",
31
+ "winston": "^3.13.1",
32
+ "winston-transport": "^4.7.1"
33
+ },
34
+ "devDependencies": {
35
+ "@sentry/profiling-node": "^8.17.0",
36
+ "dotenv": "^16.4.5"
37
+ }
38
+ }