hb-smart-logger 1.0.0
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/README.md +142 -0
- package/package.json +21 -0
- package/src/index.js +141 -0
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
HB Smart Logger ๐
|
|
2
|
+
|
|
3
|
+
HB Smart Logger is a production-ready logging solution for Node.js built on top of Winston, designed to be simple to use, safe by default, and scalable for real-world applications.
|
|
4
|
+
|
|
5
|
+
It works out of the box with zero configuration, yet provides advanced features like daily log rotation, safe JSON logging, and structured multi-argument logging.
|
|
6
|
+
|
|
7
|
+
โจ Key Benefits
|
|
8
|
+
|
|
9
|
+
โ
Zero-Config Setup
|
|
10
|
+
Just install and start logging โ no boilerplate required.
|
|
11
|
+
|
|
12
|
+
โ
Safe Object Logging
|
|
13
|
+
Handles circular JSON safely (no crashes, no [object Object]).
|
|
14
|
+
|
|
15
|
+
โ
Daily Log Rotation
|
|
16
|
+
Automatically rotates logs by day and size, with compression and retention.
|
|
17
|
+
|
|
18
|
+
โ
Separate & Combined Logs
|
|
19
|
+
Keeps per-level logs (error, warn, info, debug) and a full combined log.
|
|
20
|
+
|
|
21
|
+
โ
Multi-Argument Support
|
|
22
|
+
Log multiple values like console.log() โ strings, objects, and errors.
|
|
23
|
+
|
|
24
|
+
โ
logger.log() Alias
|
|
25
|
+
Drop-in replacement for console.log() โ routes to info level internally.
|
|
26
|
+
|
|
27
|
+
โ
Error Stack Traces Included
|
|
28
|
+
Errors automatically log full stack traces.
|
|
29
|
+
|
|
30
|
+
โ
Production-Ready Defaults
|
|
31
|
+
Designed for APIs, microservices, background workers, and cron jobs.
|
|
32
|
+
|
|
33
|
+
๐ฆ Installation
|
|
34
|
+
npm install hb-smart-logger
|
|
35
|
+
|
|
36
|
+
๐ Quick Start
|
|
37
|
+
const logger = require("hb-smart-logger");
|
|
38
|
+
|
|
39
|
+
logger.log("Application started");
|
|
40
|
+
logger.info("Server listening", { port: 3000 });
|
|
41
|
+
logger.warn("Slow response", { endpoint: "/users", timeMs: 1420 });
|
|
42
|
+
logger.error("Database connection failed", new Error("ECONNREFUSED"));
|
|
43
|
+
|
|
44
|
+
๐ง Smart Logging Examples
|
|
45
|
+
Log multiple arguments (like console.log)
|
|
46
|
+
logger.log("User login", userId, { role: "admin" });
|
|
47
|
+
|
|
48
|
+
Log objects safely (no crashes)
|
|
49
|
+
const obj = {};
|
|
50
|
+
obj.self = obj;
|
|
51
|
+
|
|
52
|
+
logger.info("Circular object test", obj);
|
|
53
|
+
|
|
54
|
+
Log errors with stack trace
|
|
55
|
+
try {
|
|
56
|
+
throw new Error("Something went wrong");
|
|
57
|
+
} catch (err) {
|
|
58
|
+
logger.error("Unhandled error", err);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
๐ Log Output Structure
|
|
62
|
+
|
|
63
|
+
HB Smart Logger automatically creates this structure:
|
|
64
|
+
|
|
65
|
+
logs/
|
|
66
|
+
combined/
|
|
67
|
+
combined-2026-01-05.log
|
|
68
|
+
error/
|
|
69
|
+
error-2026-01-05.log
|
|
70
|
+
warn/
|
|
71
|
+
warn-2026-01-05.log
|
|
72
|
+
info/
|
|
73
|
+
info-2026-01-05.log
|
|
74
|
+
debug/
|
|
75
|
+
debug-2026-01-05.log
|
|
76
|
+
|
|
77
|
+
What goes where?
|
|
78
|
+
Log Level File
|
|
79
|
+
log() / info() logs/info/ + logs/combined/
|
|
80
|
+
warn() logs/warn/ + logs/combined/
|
|
81
|
+
error() logs/error/ + logs/combined/
|
|
82
|
+
debug() logs/debug/ + logs/combined/
|
|
83
|
+
๐ Log Rotation (Built-In)
|
|
84
|
+
|
|
85
|
+
๐
Daily rotation
|
|
86
|
+
|
|
87
|
+
๐ฆ Max size: 10 MB per file
|
|
88
|
+
|
|
89
|
+
๐๏ธ Compressed archives
|
|
90
|
+
|
|
91
|
+
๐งน Auto-cleanup: keeps last 30 days
|
|
92
|
+
|
|
93
|
+
No extra setup required.
|
|
94
|
+
|
|
95
|
+
๐งช Environment Friendly
|
|
96
|
+
|
|
97
|
+
Works in development, staging, and production
|
|
98
|
+
|
|
99
|
+
Colorized console output for local development
|
|
100
|
+
|
|
101
|
+
File-based logging for production systems
|
|
102
|
+
|
|
103
|
+
๐ ๏ธ Use Cases
|
|
104
|
+
|
|
105
|
+
โ REST APIs
|
|
106
|
+
โ Express / Fastify servers
|
|
107
|
+
โ Background workers
|
|
108
|
+
โ Cron jobs
|
|
109
|
+
โ Microservices
|
|
110
|
+
โ Serverless (file logging disabled environments excluded)
|
|
111
|
+
|
|
112
|
+
๐ฅ Why HB Smart Logger?
|
|
113
|
+
Feature console.log Winston HB Smart Logger
|
|
114
|
+
Daily rotation โ โ โ
|
|
115
|
+
Circular JSON safe โ โ โ
|
|
116
|
+
Per-level files โ โ ๏ธ โ
|
|
117
|
+
Combined logs โ โ ๏ธ โ
|
|
118
|
+
logger.log() alias โ โ โ
|
|
119
|
+
Ready-to-use โ โ ๏ธ โ
|
|
120
|
+
๐ Requirements
|
|
121
|
+
|
|
122
|
+
Node.js >= 14
|
|
123
|
+
|
|
124
|
+
CommonJS environment
|
|
125
|
+
|
|
126
|
+
๐งญ Roadmap
|
|
127
|
+
|
|
128
|
+
Planned enhancements:
|
|
129
|
+
|
|
130
|
+
Configurable log directory
|
|
131
|
+
|
|
132
|
+
JSON-only output mode
|
|
133
|
+
|
|
134
|
+
Express request/response middleware
|
|
135
|
+
|
|
136
|
+
TypeScript typings
|
|
137
|
+
|
|
138
|
+
Cloud logging support (AWS / GCP)
|
|
139
|
+
|
|
140
|
+
๐ License
|
|
141
|
+
|
|
142
|
+
MIT ยฉ 2026 Hafiz Bilal
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hb-smart-logger",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Production-ready Winston logger with daily rotation, safe JSON handling, and logger.log() alias",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"publishConfig": { "access": "public" },
|
|
7
|
+
"keywords": [
|
|
8
|
+
"logger",
|
|
9
|
+
"winston",
|
|
10
|
+
"logging",
|
|
11
|
+
"daily-rotate",
|
|
12
|
+
"nodejs",
|
|
13
|
+
"express"
|
|
14
|
+
],
|
|
15
|
+
"author": "Hafiz Bilal",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"winston": "^3.13.0",
|
|
19
|
+
"winston-daily-rotate-file": "^5.0.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const winston = require("winston");
|
|
4
|
+
const DailyRotateFile = require("winston-daily-rotate-file");
|
|
5
|
+
|
|
6
|
+
// Ensure logs directory exists
|
|
7
|
+
const logDir = path.resolve("logs");
|
|
8
|
+
|
|
9
|
+
const subDirs = ["combined", "error", "warn", "info", "debug"];
|
|
10
|
+
subDirs.forEach((dir) => {
|
|
11
|
+
const fullPath = path.join(logDir, dir);
|
|
12
|
+
if (!fs.existsSync(fullPath)) {
|
|
13
|
+
fs.mkdirSync(fullPath, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/* ---------------------------------------------------
|
|
18
|
+
SAFE STRINGIFY
|
|
19
|
+
--------------------------------------------------- */
|
|
20
|
+
function safeStringify(obj) {
|
|
21
|
+
const seen = new WeakSet();
|
|
22
|
+
return JSON.stringify(
|
|
23
|
+
obj,
|
|
24
|
+
(key, value) => {
|
|
25
|
+
if (typeof value === "object" && value !== null) {
|
|
26
|
+
if (seen.has(value)) return "[Circular]";
|
|
27
|
+
seen.add(value);
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
},
|
|
31
|
+
2
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* ---------------------------------------------------
|
|
36
|
+
FORMATTER
|
|
37
|
+
--------------------------------------------------- */
|
|
38
|
+
const logFormat = winston.format.printf(
|
|
39
|
+
({ level, message, timestamp, stack, ...meta }) => {
|
|
40
|
+
let msg = message;
|
|
41
|
+
|
|
42
|
+
if (typeof msg === "object") {
|
|
43
|
+
msg = safeStringify(msg);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const metaString =
|
|
47
|
+
Object.keys(meta).length ? " " + safeStringify(meta) : "";
|
|
48
|
+
|
|
49
|
+
return `${timestamp} [${level.toUpperCase()}]: ${
|
|
50
|
+
stack || msg
|
|
51
|
+
}${metaString}`;
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
/* ---------------------------------------------------
|
|
56
|
+
BASE LOGGER
|
|
57
|
+
--------------------------------------------------- */
|
|
58
|
+
const baseLogger = winston.createLogger({
|
|
59
|
+
level: "info",
|
|
60
|
+
format: winston.format.combine(
|
|
61
|
+
winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
|
|
62
|
+
winston.format.errors({ stack: true }),
|
|
63
|
+
logFormat
|
|
64
|
+
),
|
|
65
|
+
transports: [],
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/* ---------------------------------------------------
|
|
69
|
+
ROTATING FILES
|
|
70
|
+
--------------------------------------------------- */
|
|
71
|
+
|
|
72
|
+
// Combined logs (ALL levels)
|
|
73
|
+
baseLogger.add(
|
|
74
|
+
new DailyRotateFile({
|
|
75
|
+
dirname: path.join(logDir, "combined"),
|
|
76
|
+
filename: "combined-%DATE%.log",
|
|
77
|
+
datePattern: "YYYY-MM-DD",
|
|
78
|
+
zippedArchive: true,
|
|
79
|
+
maxSize: "10m",
|
|
80
|
+
maxFiles: "30d",
|
|
81
|
+
})
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Per-level logs
|
|
85
|
+
["error", "warn", "info", "debug"].forEach((level) => {
|
|
86
|
+
baseLogger.add(
|
|
87
|
+
new DailyRotateFile({
|
|
88
|
+
dirname: path.join(logDir, level),
|
|
89
|
+
filename: `${level}-%DATE%.log`,
|
|
90
|
+
level,
|
|
91
|
+
datePattern: "YYYY-MM-DD",
|
|
92
|
+
zippedArchive: true,
|
|
93
|
+
maxSize: "10m",
|
|
94
|
+
maxFiles: "30d",
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Console output
|
|
100
|
+
baseLogger.add(
|
|
101
|
+
new winston.transports.Console({
|
|
102
|
+
format: winston.format.combine(
|
|
103
|
+
winston.format.colorize(),
|
|
104
|
+
winston.format.simple()
|
|
105
|
+
),
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
/* ---------------------------------------------------
|
|
110
|
+
WRAPPER (MULTI-ARGS + logger.log)
|
|
111
|
+
--------------------------------------------------- */
|
|
112
|
+
const wrapLogger = (logger) => {
|
|
113
|
+
const levels = ["info", "warn", "error", "debug"];
|
|
114
|
+
|
|
115
|
+
for (const level of levels) {
|
|
116
|
+
const original = logger[level].bind(logger);
|
|
117
|
+
|
|
118
|
+
logger[level] = (...args) => {
|
|
119
|
+
const merged = args
|
|
120
|
+
.map((arg) => {
|
|
121
|
+
if (arg instanceof Error) {
|
|
122
|
+
return `${arg.message}\n${arg.stack}`;
|
|
123
|
+
}
|
|
124
|
+
if (typeof arg === "object") {
|
|
125
|
+
return safeStringify(arg);
|
|
126
|
+
}
|
|
127
|
+
return String(arg);
|
|
128
|
+
})
|
|
129
|
+
.join(" ");
|
|
130
|
+
|
|
131
|
+
return original(merged);
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Alias: logger.log() โ logger.info()
|
|
136
|
+
logger.log = (...args) => logger.info(...args);
|
|
137
|
+
|
|
138
|
+
return logger;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
module.exports = wrapLogger(baseLogger);
|