The logger module provides a logging interface used by all Nanook components and an in-memory implementation suitable for development, testing, and production use.
import {
LoggerInterface,
LoggerMemory,
getLoggerMemory
} from 'nanook-table'Abstract base class that defines the logging contract. All Nanook components accept a LoggerInterface and use it for diagnostic output. You can implement this interface to integrate with any logging framework (Winston, Pino, console, etc.).
Log levels are ordered by severity. Setting the logger to a given level means it will only output messages at that level or higher.
| Level | Numeric Value | Description |
|---|---|---|
debug |
0 |
Detailed diagnostic information |
info |
1 |
General informational messages |
warning |
2 |
Potentially problematic situations |
error |
3 |
Error conditions that allow continued operation |
fatal |
4 |
Severe errors that may cause the process to abort |
| Property | Type | Description |
|---|---|---|
level |
string | number |
The current log level. Messages below this level are suppressed. Can be set as a string ('debug', 'info', etc.) or a number (0--4) |
Clears all stored log entries. The specific behavior depends on the implementation.
Converts a log level string to its numeric value.
logger.getLevelNumber('warning') // 2
logger.getLevelNumber('debug') // 0Returns the current time formatted for log entries. The format is implementation-specific.
Logs a message at the debug level (numeric value 0).
await logger.debug('Processing table: LoginTests')
await logger.debug({ table: 'LoginTests', testcases: 5 })Logs a message at the info level (numeric value 1).
await logger.info('File loaded successfully')Logs a message at the warning level (numeric value 2).
await logger.warning('Sheet "OldFormat" uses deprecated section type')Logs a message at the error level (numeric value 3).
await logger.error('Generator "myGen" failed after 100 uniqueness retries')Logs a message at the fatal level (numeric value 4).
await logger.fatal('Cannot open file: tests.xlsx')To integrate Nanook with your own logging infrastructure, extend LoggerInterface and override the _writeLog method:
import { LoggerInterface } from 'nanook-table'
class WinstonLogger extends LoggerInterface {
private winston: WinstonInstance
constructor(winston: WinstonInstance) {
super()
this.winston = winston
}
_writeLog(level: string, entry: string | object): void {
const message = typeof entry === 'string' ? entry : JSON.stringify(entry)
this.winston.log(level, message)
}
clear(): void {
// Winston does not support clearing logs
}
}In-memory logger that stores all log entries in arrays, organized by level. Optionally also writes to the console. This is the default logger used in examples and tests.
LoggerInterface
new LoggerMemory()| Property | Type | Default | Description |
|---|---|---|---|
writeConsole |
boolean |
false |
When true, log entries are also printed to console. Set this to true during development to see output |
entries |
LogEntries |
{ debug: [], info: [], warning: [], error: [], fatal: [] } |
All stored log entries, organized by level. Each entry contains the timestamp and message |
Empties all log entry arrays.
const logger = new LoggerMemory()
await logger.info('hello')
console.log(logger.entries.info.length) // 1
logger.clear()
console.log(logger.entries.info.length) // 0import { LoggerMemory } from 'nanook-table'
const logger = new LoggerMemory()
logger.writeConsole = true
await logger.info('Starting generation')
await logger.debug('Processing sheet: LoginTests')
await logger.warning('Empty test case column found')
// Access stored entries
for (const entry of logger.entries.warning) {
console.log(`Warning at ${entry.time}: ${entry.message}`)
}
// Check for errors after processing
if (logger.entries.error.length > 0) {
console.log(`${logger.entries.error.length} errors occurred`)
}Each entry in the entries arrays is an object with:
| Field | Type | Description |
|---|---|---|
time |
string |
Formatted timestamp of when the entry was logged |
message |
string | object |
The logged message or data object |
Factory function that creates and returns a new LoggerMemory instance.
import { getLoggerMemory } from 'nanook-table'
const logger = getLoggerMemory()
logger.writeConsole = true
await logger.info('Ready')This is a convenience shorthand for new LoggerMemory().
const logger = new LoggerMemory()
logger.writeConsole = true
logger.level = 'debug'import { describe, it, expect } from 'vitest'
import { LoggerMemory } from 'nanook-table'
describe('my generator', () => {
it('logs a warning for empty config', async () => {
const logger = new LoggerMemory()
const gen = new MyGenerator({ logger })
await gen.generate('id1', testcase, directive)
expect(logger.entries.warning.length).toBe(1)
expect(logger.entries.warning[0].message).toContain('empty config')
})
})const logger = new LoggerMemory()
logger.level = 'warning' // only warning, error, and fatal are logged