node-logy 0.1.4 → 0.1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-logy",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "A lightweight Node.js logging utility that outputs logs to the console and writes them to rotating log files. Supports different log levels, timestamps, and customizable formatting for production-ready applications.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/dist/server.d.ts DELETED
@@ -1,5 +0,0 @@
1
- /**
2
- * This is a self contained script that runs as the server process which accepts the binary protocol and then performs actions
3
- */
4
- export {};
5
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/dist/server.js DELETED
@@ -1,275 +0,0 @@
1
- "use strict";
2
- /**
3
- * This is a self contained script that runs as the server process which accepts the binary protocol and then performs actions
4
- */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const protocol_1 = require("./protocol");
11
- const node_fs_1 = __importDefault(require("node:fs"));
12
- /**
13
- * Used for sucess exits
14
- */
15
- const EXIT_SUCCESS = 0;
16
- /**
17
- * Holds the stream for the log file
18
- */
19
- let fileStream = null;
20
- /**
21
- * Holds the base path of where to save the log files
22
- */
23
- let basePath = "./logs";
24
- /**
25
- * Holds stdin buffer
26
- */
27
- let stdinBuffer = Buffer.alloc(0);
28
- /**
29
- * Holds the array of buffer data we will write to the log file
30
- */
31
- let fileWriteBufferArray = [];
32
- /**
33
- * How long we wait until we flush unless the buffer gets full
34
- */
35
- const FLUSH_MS = 130;
36
- // Increased to 256 buffers or 4MB, whichever comes first
37
- const FILE_WRITE_BUFFER_FLUSH_COUNT = 256;
38
- const FILE_WRITE_BUFFER_MAX_SIZE = 4 * 1024 * 1024; // 4MB
39
- let currentBufferSize = 0;
40
- /**
41
- * Holds the timeout for flush
42
- */
43
- let flushTimeout = null;
44
- /**
45
- * Used to encode and decode response binary protocol data
46
- */
47
- const responseEncoder = new protocol_1.ResponseEncoder();
48
- /**
49
- * Newline buffer for efficient concatenation
50
- */
51
- const NEWLINE_BUFFER = Buffer.from("\n");
52
- /**
53
- * Clears the pending flush timeout
54
- */
55
- const clearFlushTimeout = () => {
56
- if (flushTimeout) {
57
- clearTimeout(flushTimeout);
58
- flushTimeout = null;
59
- }
60
- };
61
- /**
62
- * Flushes the buffer array to the file and resets it
63
- */
64
- const flush = () => {
65
- if (fileWriteBufferArray.length === 0 || !fileStream) {
66
- return;
67
- }
68
- const count = fileWriteBufferArray.length;
69
- // Calculate total size: sum of all buffers + newlines (1 per entry + 1 final)
70
- let totalSize = NEWLINE_BUFFER.length; // Final newline
71
- for (let i = 0; i < count; i++) {
72
- totalSize += fileWriteBufferArray[i].length + NEWLINE_BUFFER.length;
73
- }
74
- // Allocate buffer once
75
- const joinedBuffer = Buffer.allocUnsafe(totalSize);
76
- let offset = 0;
77
- for (let i = 0; i < count; i++) {
78
- const buf = fileWriteBufferArray[i];
79
- buf.copy(joinedBuffer, offset);
80
- offset += buf.length;
81
- NEWLINE_BUFFER.copy(joinedBuffer, offset);
82
- offset += NEWLINE_BUFFER.length;
83
- }
84
- fileStream.write(joinedBuffer, (err) => {
85
- if (err) {
86
- console.error(`Write error: ${err.message}`);
87
- }
88
- });
89
- fileWriteBufferArray = [];
90
- currentBufferSize = 0;
91
- clearFlushTimeout();
92
- };
93
- /**
94
- * Starts the delayed flush timer if not already running
95
- */
96
- const startFlush = () => {
97
- if (flushTimeout !== null) {
98
- return;
99
- }
100
- flushTimeout = setTimeout(() => {
101
- flush();
102
- }, FLUSH_MS);
103
- };
104
- /**
105
- * Used to send response to the parent
106
- * @param response The response
107
- */
108
- const sendResponse = (response) => {
109
- process.stdout.write(responseEncoder.encode(response));
110
- };
111
- /**
112
- * Handle the request decoded
113
- * @param request The request that was buffer bytes extracted
114
- */
115
- const requestHandler = (request) => {
116
- const requestMethod = protocol_1.RequestEncoder.getMethod(request);
117
- const requestId = protocol_1.RequestEncoder.getId(request);
118
- const requestLevel = protocol_1.RequestEncoder.getLevel(request);
119
- switch (requestMethod) {
120
- case protocol_1.METHOD.LOG: {
121
- const payload = protocol_1.RequestEncoder.getPayloadBuffer(request);
122
- fileWriteBufferArray.push(payload);
123
- currentBufferSize += payload.length;
124
- // Flush on count OR size threshold
125
- if (fileWriteBufferArray.length >= FILE_WRITE_BUFFER_FLUSH_COUNT ||
126
- currentBufferSize >= FILE_WRITE_BUFFER_MAX_SIZE) {
127
- flush();
128
- }
129
- else {
130
- startFlush();
131
- }
132
- sendResponse({
133
- id: requestId,
134
- level: requestLevel,
135
- method: requestMethod,
136
- success: true,
137
- });
138
- break;
139
- }
140
- case protocol_1.METHOD.FLUSH:
141
- flush();
142
- if (fileStream?.writableNeedDrain) {
143
- fileStream.once("drain", () => {
144
- sendResponse({
145
- id: requestId,
146
- level: requestLevel,
147
- method: requestMethod,
148
- success: true,
149
- });
150
- });
151
- }
152
- else {
153
- sendResponse({
154
- id: requestId,
155
- level: requestLevel,
156
- method: requestMethod,
157
- success: true,
158
- });
159
- }
160
- break;
161
- case protocol_1.METHOD.RELOAD:
162
- flush();
163
- fileStream?.end(() => {
164
- fileStream = null;
165
- createStream();
166
- sendResponse({
167
- id: requestId,
168
- level: requestLevel,
169
- method: requestMethod,
170
- success: true,
171
- });
172
- });
173
- return;
174
- case protocol_1.METHOD.SHUTDOWN:
175
- flush();
176
- fileStream?.end(() => {
177
- sendResponse({
178
- id: requestId,
179
- level: requestLevel,
180
- method: requestMethod,
181
- success: true,
182
- });
183
- setImmediate(() => {
184
- process.exit(EXIT_SUCCESS);
185
- });
186
- });
187
- return;
188
- default:
189
- process.stderr.write(`request unhandled method ${requestMethod}`);
190
- sendResponse({
191
- id: requestId,
192
- level: requestLevel,
193
- method: requestMethod,
194
- success: false,
195
- });
196
- break;
197
- }
198
- };
199
- /**
200
- * Parses the buffer and moves it along with backpressure handling
201
- */
202
- function parseBuffer() {
203
- const HEADER_SIZE = protocol_1.RequestEncoder.getHeaderSize();
204
- while (stdinBuffer.length >= HEADER_SIZE) {
205
- const payloadLength = protocol_1.RequestEncoder.getPayloadLength(stdinBuffer);
206
- const totalMessageSize = HEADER_SIZE + payloadLength;
207
- if (stdinBuffer.length < totalMessageSize) {
208
- break;
209
- }
210
- const messageBuffer = stdinBuffer.subarray(0, totalMessageSize);
211
- requestHandler(messageBuffer);
212
- stdinBuffer = stdinBuffer.subarray(totalMessageSize);
213
- }
214
- if (stdinBuffer.length >= protocol_1.RequestEncoder.getHeaderSize()) {
215
- setImmediate(parseBuffer);
216
- }
217
- }
218
- /**
219
- * Generates a log filename based on current date
220
- * @returns Filename in format YYYY-MM-DD.log
221
- */
222
- const getLogFileName = () => {
223
- const date = new Date();
224
- const year = date.getFullYear();
225
- const month = String(date.getMonth() + 1).padStart(2, "0");
226
- const day = String(date.getDate()).padStart(2, "0");
227
- return `${year}-${month}-${day}.log`;
228
- };
229
- /**
230
- * Creates a stream to the file in append mode for today's log file.
231
- * Closes existing stream if one is already open.
232
- */
233
- const createStream = () => {
234
- fileStream = null;
235
- const fileName = getLogFileName();
236
- const filePath = node_path_1.default.join(basePath, fileName);
237
- // Use higher highWaterMark for better throughput
238
- fileStream = node_fs_1.default.createWriteStream(filePath, {
239
- flags: "a",
240
- highWaterMark: 64 * 1024, // 64KB internal buffer
241
- });
242
- fileStream.on("error", (err) => {
243
- console.error(`Stream error: ${err.message}`);
244
- });
245
- };
246
- /**
247
- * Graceful shutdown handler
248
- */
249
- const shutdown = () => {
250
- clearFlushTimeout();
251
- flush();
252
- fileStream?.end(() => {
253
- process.exit(EXIT_SUCCESS);
254
- });
255
- };
256
- process.on("SIGINT", shutdown);
257
- process.on("SIGTERM", shutdown);
258
- /**
259
- * Main entry point
260
- */
261
- async function main() {
262
- basePath = process.env["BASE_PATH"] ? process.env["BASE_PATH"] : "./logs";
263
- basePath = node_path_1.default.normalize(node_path_1.default.resolve(basePath));
264
- await node_fs_1.default.promises.mkdir(basePath, { recursive: true });
265
- createStream();
266
- process.stdin.on("data", (chunk) => {
267
- stdinBuffer = Buffer.concat([stdinBuffer, chunk]);
268
- parseBuffer();
269
- });
270
- process.stdin.on("end", () => {
271
- shutdown();
272
- });
273
- }
274
- main();
275
- //# sourceMappingURL=server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}