createLogger
Creates a Tevm logger instance. Thin wrapper around pino: the returned value is a pino logger, so every pino feature works exactly as pino documents it.
function createLogger(options: LogOptions): LoggerImport
import { createLogger } from '@tevm/logger'Parameters
options
- Type:
LogOptions
| Property | Type | Description |
|---|---|---|
name | string | Added as a name field to every record this logger emits. |
level | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | Minimum severity to emit. Anything less severe is dropped. |
Both properties are required.
Returns
Logger — a pino.Logger.
Throws
Error — if options.level is not one of the six valid levels. pino validates eagerly at construction:
import { createLogger } from '@tevm/logger'
// Throws: unknown level verbose
createLogger({ name: 'app', level: 'verbose' as never })TypeScript catches this at compile time; the runtime throw matters when the level comes from an environment variable or a JSON config file. Validate before constructing:
validate-level.ts
import { createLogger, type Level, type Logger } from '@tevm/logger'
const LEVELS = ['fatal', 'error', 'warn', 'info', 'debug', 'trace'] as const
/**
* Builds a logger from an untrusted level string.
* @throws {Error} If `level` is not a valid log level.
*/
export const loggerFromUnknownLevel = (name: string, level: string): Logger => {
if (!(LEVELS as readonly string[]).includes(level)) {
throw new Error(`Invalid log level ${JSON.stringify(level)}. Expected one of: ${LEVELS.join(', ')}`)
}
return createLogger({ name, level: level as Level })
}Behavior
- Destination. Node: newline-delimited JSON on stdout (fd 1), written synchronously. Browser: routed to the
matching
consolemethod. - Every record includes
level(numeric),time(epoch ms),name, and — in Node —pidandhostname. - BigInts are serialized as strings rather than throwing, which matters for block numbers and wei values.
- No transport is configured. For file output, redaction, or async transports, construct pino directly — see Transports & redaction.
Examples
Basic
basic.ts
import { createLogger } from '@tevm/logger'
const logger = createLogger({ name: 'tevm-node', level: 'info' })
logger.info('node started')
logger.info({ chainId: 1, blockNumber: 21_000_000n }, 'forked mainnet')Logging errors
errors.ts
import { createLogger } from '@tevm/logger'
const logger = createLogger({ name: 'tevm-node', level: 'info' })
try {
throw new Error('fork provider unreachable')
} catch (error) {
// Under `err`, so pino's serializer emits type, message, and stack.
logger.error({ err: error }, 'failed to fork')
}Child logger
child.ts
import { createLogger } from '@tevm/logger'
const logger = createLogger({ name: 'tevm-node', level: 'debug' })
const requestLogger = logger.child({ requestId: '01H8X' })
requestLogger.debug({ method: 'eth_call' }, 'handling request')Methods on the returned logger
The most commonly used members. See the pino API for the full surface.
| Member | Description |
|---|---|
fatal/error/warn/info/debug/trace(...) | Emit a record. Call as (obj, msg) or (msg). |
child(bindings) | New logger with extra fields on every record. |
level | Readable and writable — change verbosity at runtime. |
isLevelEnabled(level) | Guard expensive payload construction. |
silent(...) | No-op; useful as a default logger. |
flush() | Flush buffered records (only meaningful with async transports). |

