MarzbanSDK
Configuration

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_ENVDefault level
developmentinfo
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'
FieldTypeRequiredDescription
level'debug' | 'info' | 'warn' | 'error'NoMinimum level to emit. Defaults to the environment-based level (info in development, error in production).
timestampbooleanNoPrepend an ISO timestamp to each line. Default: true.

Log levels

LevelWhen to use
debugVerbose internal traces (HTTP calls, retry attempts, WS events)
infoMajor lifecycle events (auth success, connections opened)
warnNon-fatal issues (auth retry, token refresh)
errorFailures 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=3

Fields: [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),
  },
})

On this page