@mdaemon/logfile
v3.6.3
Published
A node logging utility
Maintainers
Readme
@mdaemon/logfile, A node only async logging utility
Not applicable to a browser context.
Install
$ npm install @mdaemon/logfile --saveNode CommonJS
const LogFile = require("@mdaemon/logfile");Node Modules
import LogFile from "@mdaemon/logfile";LogFile
LogFile Initialization Options
/* default LogFileOptions
* logLevel: 1 (INFO)
* dir: "./logs"
* fileFormat: "log-%DATE%.log"
* logToConsole: false
* rollover: true
* maxFileSize: 104857600 (100 MB)
* registerProcessHandlers: false
* onError: undefined
* logStr: "%DATE% %TIME% | %LEVEL% | %MESSAGE%";
* startLog: "-----------------------------------------\n" +
* "------- Log Started: %DATETIME%\n" +
* "-----------------------------------------\n";
*
* endLog: "-----------------------------------------\n" +
* "------- Log Ended: %DATETIME%\n" +
* "-----------------------------------------\n";
*/LogFile Example
const { INFO, ERROR, WARNING, CRITICAL, DEBUG } = LogFile;
const logFile = new LogFile({ logLevel: DEBUG });
logFile.start();
logFile.log("There was an error", ERROR);
logFile.stop();
/* file result
-----------------------------------------
------- Log Started: Fri, 08 Mar 2024 16:07:19 GMT
-----------------------------------------
2024-03-08 16:07:19 | ERROR | There was an error
-----------------------------------------
------- Log Ended: Fri, 08 Mar 2024 16:07:19 GMT
-----------------------------------------
*/LogFile Options
// set the log str
logFile.setLogStr("%DATE% %TIME% | %LEVEL% | %MESSAGE%");
// set the log dir
logFile.setLogDir("./logs");
// set the rollover boolean
logFile.setRollover(true);
// set the log level
logFile.setLogLevel(DEBUG);
// set the file name format
logFile.setFileFormat("log-%DATE%.log");
// set the log to console boolean
logFile.setLogToConsole(true);
// set the start log string
logFile.setStartLog("-----------------------------------------\n");
// set the end log string
logFile.setEndLog("-----------------------------------------\n");
// set whether timestamps use server local time (true, default) or UTC (false)
logFile.setUseServerTime(true);
// log help to the console
logFile.getHelp();
// log with an explicit level (defaults to DEBUG when omitted)
logFile.log("This is an error log", LogFile.ERROR);
// log to info
logFile.info("This is an info log");
// log to warning
logFile.warning("This is a warning log");
// warn is an alias for warning
logFile.warn("This is a warn log");
// log to error
logFile.error("This is an error log");
// log to critical
logFile.critical("This is a critical log");
// log to debug
logFile.debug("This is a debug log");
// force synchronous flush to disk
logFile.flushSync();
Log File Rollover
The logger supports two types of automatic file rollover:
Date-based Rollover (when rollover: true):
- Automatically creates a new log file when the date changes
- File names use the
fileFormatpattern with%DATE%replaced by the current date - Example:
log-2024-01-01.log,log-2024-01-02.log, etc.
Size-based Rollover (controlled by maxFileSize):
- Automatically creates a new log file when the current file exceeds
maxFileSize(default: 100 MB) - New files are created with an incremental numeric suffix
- Example: If
log-2024-01-01.logexceeds the max size:- First rollover creates:
log-2024-01-01-1.log - Second rollover creates:
log-2024-01-01-2.log - And so on...
- First rollover creates:
- The suffix counter resets to 0 when a date-based rollover occurs
Combined Behavior:
- Both rollover types work together seamlessly
- Date changes always create a new base file (resetting the size suffix)
- Within a single day, size-based rollovers create numbered variants
- Each new file (date or size-based) starts with the
startLogmessage - Files being closed receive the
endLogmessage
// Example: Create a logger with a 50 MB max file size
const logFile = new LogFile({
maxFileSize: 52428800, // 50 MB in bytes
fileFormat: "app-%DATE%.log"
});
// This will create files like:
// app-2024-01-01.log (up to 50 MB)
// app-2024-01-01-1.log (up to 50 MB)
// app-2024-01-01-2.log (up to 50 MB)
// app-2024-01-02.log (new day, suffix resets)LogFile Methods
Log Levels
Available as static constants on the LogFile class:
LogFile.DEBUG= 0LogFile.INFO= 1LogFile.WARNING= 2LogFile.ERROR= 3LogFile.CRITICAL= 4
Messages below the configured logLevel are not written.
Configuration Methods
setLogStr(format)/getLogStr()- Set/get the log entry format stringsetLogDir(path)/getLogDir()- Set/get the directory for log filessetRollover(boolean)/getRollover()- Enable/disable daily log file rolloversetLogLevel(level)/getLogLevel()- Set/get the minimum log levelsetFileFormat(format)/getFileFormat()- Set/get the log filename formatsetLogToConsole(bool)/getLogToConsole()- Enable/disable console outputsetStartLog(string)/getStartLog()- Set/get the log file start stringsetEndLog(string)/getEndLog()- Set/get the log file end stringsetUseServerTime(bool)- Use server local time (default:true) or UTC for timestamps
Constructor Options
logLevel- Minimum log level (default:LogFile.INFO)dir- Log file directory (default:"./logs")fileFormat- Filename format (default:"log-%DATE%.log")logToConsole- Also log to console (default:false)rollover- Enable date-based rollover (default:true)maxFileSize- Max file size in bytes before size-based rollover (default:104857600)logStr- Log entry format stringstartLog- Message written when log file startsendLog- Message written when log file endsregisterProcessHandlers- Register SIGINT/SIGTERM/exit handlers (default:false)onError- Callback invoked on I/O errors:(error: Error) => void
Logging Methods
log(message, level)- Log a message at the given level (defaults toLogFile.DEBUG)debug(...args)- Log a debug messageinfo(...args)- Log an info messagewarning(...args)- Log a warning messagewarn(...args)- Alias forwarningerror(...args)- Log an error messagecritical(...args)- Log a critical message (automatically flushes to disk)
All logging methods return true on success and false on failure. The level-specific methods accept multiple arguments; non-string arguments are stringified and joined with spaces.
Utility Methods
getHelp()- Display help informationflushSync()- Force immediate synchronous write of buffered logs to diskfile()- Get the path to the current log filelastFile()- Get the path to the previous log filestart()- Initialize the logger and set up shutdown handlersstop()- Stop the logger, flush remaining logs, and clean up resources
Forced Shutdown Protection
The logger can optionally handle various termination scenarios to ensure logs are not lost. Set registerProcessHandlers: true to enable:
const logFile = new LogFile({
logLevel: LogFile.DEBUG,
registerProcessHandlers: true
});- Registers handlers for exit, SIGINT, and SIGTERM signals to flush logs
- Automatically logs and flushes uncaught exceptions before termination
- Handlers are removed when
stop()is called, preventing listener leaks - Critical log messages are always immediately flushed to disk (regardless of this option)
Testing
The package includes a comprehensive testing setup that allows for testing the following formats:
- TypeScript source files (index.ts) before building
- CommonJS output (logfile.cjs) after building
Running Tests
# Test TypeScript source directly
npm run test:source
# Test CommonJS output
npm run test:cjs
# Run all tests (source, build CommonJS, then test each)
npm run test:allThe testing system uses a test helper that dynamically imports the appropriate module format based on environment variables, allowing the same test suite to verify all formats.
// Example of how to use the test helper in tests
import { getLogFile } from './test-helper';
// Wait for the LogFile class to be dynamically loaded
const LogFile = await getLogFile();
const logFile = new LogFile({ logLevel: LogFile.DEBUG });Testing Challenges
Testing different module formats in Jest can be challenging. This project addresses these challenges by:
- Using different Jest configurations for different module formats
- Dynamically importing modules based on the test environment
- Properly handling imports and mocks
If you're extending the tests, be aware that different module formats may require special handling for imports, mocks, and configuration.
License
Published under the LGPL-2.1 license.
Published by MDaemon Technologies, Ltd. Simple Secure Email https://www.mdaemon.com
