Logging
Environment-aware built-in logging and how to plug in your own logger.
MarzbanSDK ships with a built-in colored logger and a flexible interface that lets you swap it out for any logger you prefer — Winston, Pino, NestJS Logger, or anything else.
Default behaviour
When you don't set logger at all, the SDK picks the log level based on the environment:
NODE_ENV | Default level |
|---|---|
development | info |
| anything else (production) | error |
Built-in logger options
To tune the built-in logger, pass an options object to logger:
const sdk = await createMarzbanSDK({
// ...
logger: {
level: 'debug', // 'debug' | 'info' | 'warn' | 'error'
timestamp: true, // prepend ISO timestamp to each line (default: true)
},
})LoggerOptions
The shape of the options object. Both fields are optional — omit one to keep its default.
import type { LoggerOptions } from 'marzban-sdk'| Field | Type | Required | Description |
|---|---|---|---|
level | 'debug' | 'info' | 'warn' | 'error' | No | Minimum level to emit. Defaults to the environment-based level (info in development, error in production). |
timestamp | boolean | No | Prepend an ISO timestamp to each line. Default: true. |
Log levels
| Level | When to use |
|---|---|
debug | Verbose internal traces (HTTP calls, retry attempts, WS events) |
info | Major lifecycle events (auth success, connections opened) |
warn | Non-fatal issues (auth retry, token refresh) |
error | Failures and exceptions |
Each level also emits every more severe level. For example, warn also logs error messages.
Log output format
The built-in logger outputs lines like:
[MarzbanSDK] 2024-01-15T10:23:05.123Z INFO [AuthManager] Authentication successful, token stored
[MarzbanSDK] 2024-01-15T10:23:05.200Z DEBUG [HttpClient] Configuring HTTP client: baseURL=https://..., timeout=30000ms, retries=3Fields: [MarzbanSDK] prefix · ISO timestamp · level (padded) · [context] · message.
Disable logging
Pass logger: false to suppress all SDK output:
const sdk = await createMarzbanSDK({
// ...
logger: false,
})Custom logger
Provide any object that implements the interface:
interface Logger {
debug(message: string, context?: string): void
info(message: string, context?: string): void
warn(message: string, context?: string): void
error(message: string, trace?: unknown, context?: string): void
}Example: Winston
import winston from 'winston'
import { createMarzbanSDK } from 'marzban-sdk'
const winstonLogger = winston.createLogger({
level: 'info',
transports: [new winston.transports.Console()],
})
const sdk = await createMarzbanSDK({
// ...
logger: {
debug: (msg, ctx) => winstonLogger.debug(msg, { context: ctx }),
info: (msg, ctx) => winstonLogger.info(msg, { context: ctx }),
warn: (msg, ctx) => winstonLogger.warn(msg, { context: ctx }),
error: (msg, trace, ctx) => winstonLogger.error(msg, { context: ctx, trace }),
},
})Example: Pino
import pino from 'pino'
import { createMarzbanSDK } from 'marzban-sdk'
const logger = pino({ level: 'debug' })
const sdk = await createMarzbanSDK({
// ...
logger: {
debug: (msg, ctx) => logger.debug({ ctx }, msg),
info: (msg, ctx) => logger.info({ ctx }, msg),
warn: (msg, ctx) => logger.warn({ ctx }, msg),
error: (msg, trace, ctx) => logger.error({ ctx, trace }, msg),
},
})Example: NestJS Logger
import { Logger as NestLogger } from '@nestjs/common'
import { createMarzbanSDK } from 'marzban-sdk'
const nestLogger = new NestLogger('MarzbanSDK')
const sdk = await createMarzbanSDK({
// ...
logger: {
debug: (msg, ctx) => nestLogger.debug(msg, ctx),
info: (msg, ctx) => nestLogger.log(msg, ctx),
warn: (msg, ctx) => nestLogger.warn(msg, ctx),
error: (msg, trace, ctx) => nestLogger.error(msg, trace, ctx),
},
})