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.
- package/LICENSE +674 -674
- package/README.md +89 -89
- package/index.js +57 -57
- package/lib/logger.js +219 -209
- 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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
// new winston.transports.File({ filename: `${path}/${filename}`, format:fileFormat,
|
|
144
|
-
// )
|
|
145
|
-
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
new winston.transports.File({ filename: `${path}/
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
*
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
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.
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
}
|