Telego Logging Options and Configuration: A Complete Guide

Telego provides a built-in, thread-safe logger with automatic token masking that can be customized through Bot options or replaced entirely with a custom implementation.

The mymmrac/telego library ships with a lightweight, color-enhanced logging system designed specifically for Telegram bot development. Understanding the available Telego logging options and configuration methods allows you to control output verbosity, secure sensitive data, and integrate with your existing observability stack.

Understanding the Telego Logger Interface

Telego defines a minimal Logger interface in main/logger.go, making it easy to swap implementations without modifying core bot logic.

Core Logger Interface

The interface requires only two methods for debug and error output:

type Logger interface {
    Debugf(format string, args ...any)
    Errorf(format string, args ...any)
}

This design keeps the footprint small while supporting structured logging, JSON output, or third-party integrations.

Built-in Logger Implementation

The concrete logger struct in main/logger.go provides color-coded, timestamped output to io.Writer (default stderr). Key fields include:

  • Out — Destination writer for log output
  • DebugMode — Toggles Debugf output
  • PrintErrors — Toggles Errorf output
  • Replacer — strings.Replacer that masks sensitive values

The implementation uses a sync.Mutex to ensure thread-safe concurrent writes across webhook handlers and polling loops.

Configuring Telego Logging Options

All logging customization happens through Bot options defined in main/bot_options.go. These helpers allow you to adjust verbosity, disable output, or inject custom implementations.

Using Default Logger Options

The WithDefaultLogger option recreates the built-in logger with custom flags while automatically masking the bot token:

bot, err := telego.NewBot(
    os.Getenv("TOKEN"),
    telego.WithDefaultLogger(true, true), // debug=true, errors=true
)

For a shorter syntax, WithDefaultDebugLogger enables both debug and error output:

bot, err := telego.NewBot(
    os.Getenv("TOKEN"),
    telego.WithDefaultDebugLogger(),
)

To disable all logging, use WithDiscardLogger, which sets both flags to false:

bot, err := telego.NewBot(
    os.Getenv("TOKEN"),
    telego.WithDiscardLogger(),
)

Extended Logger Configuration

WithExtendedDefaultLogger provides the same control as WithDefaultLogger but accepts a custom *strings.Replacer for additional masking:

replacer := strings.NewReplacer(
    os.Getenv("SECRET"), "REDACTED",
    token, "BOT_TOKEN",
)

bot, err := telego.NewBot(
    token,
    telego.WithExtendedDefaultLogger(true, true, replacer),
)

Pass nil as the replacer to disable token masking entirely (not recommended for production).

Custom Logger Implementation

For integration with Zap, Logrus, or structured JSON logging, implement the Logger interface and inject it via WithLogger:

type jsonLogger struct{}

func (jsonLogger) Debugf(format string, args ...any) {
    msg := fmt.Sprintf(format, args...)
    fmt.Printf("{\"level\":\"debug\",\"msg\":\"%s\"}\n", msg)
}

func (jsonLogger) Errorf(format string, args ...any) {
    msg := fmt.Sprintf(format, args...)
    fmt.Printf("{\"level\":\"error\",\"msg\":\"%s\"}\n", msg)
}

// Usage
bot, err := telego.NewBot(
    token,
    telego.WithLogger(jsonLogger{}),
)

This approach gives full control over formatting, destinations, and log aggregation pipelines.

Security Features in Telego Logging

The library includes built-in protections to prevent accidental credential exposure.

Automatic Token Masking

The defaultReplacer function in main/logger.go creates a strings.Replacer that substitutes the real bot token with the constant BOT_TOKEN string before writing to output:

func defaultReplacer(token string) *strings.Replacer {
    return strings.NewReplacer(token, DefaultLoggerTokenReplacement)
}

This ensures that even if debug mode logs full API URLs or request bodies, the authentication credential remains hidden.

Debug Mode Considerations

Enabling DebugMode prints full request payloads and API responses, which may contain user data or message content. According to the source code in main/bot.go, these logs are emitted via b.log.Debugf("API call to: %q, with data: %s", url, debugData).

Use debug logging only during development or when connected to a secure, private log sink. Never enable debug mode in production environments handling sensitive user conversations.

Accessing the Logger at Runtime

After bot initialization, retrieve the logger instance via the Logger() method to emit custom log entries from your handlers:

l := bot.Logger()
l.Debugf("Current bot ID: %d", bot.ID())

This pattern maintains consistency with internal Telego logging and respects the configured verbosity settings.

Summary

  • The Telego logging system centers around a minimal Logger interface with Debugf and Errorf methods defined in main/logger.go.
  • Bot options in main/bot_options.go provide convenient helpers: WithDefaultLogger, WithDefaultDebugLogger, WithDiscardLogger, and WithExtendedDefaultLogger.
  • Security is enforced by default via token masking using strings.Replacer, substituting the real token with BOT_TOKEN in all output.
  • Custom implementations can be injected via WithLogger, enabling integration with structured logging libraries like Zap or Logrus.
  • Thread safety is guaranteed by a mutex in the default logger, ensuring safe concurrent access across goroutines.

Frequently Asked Questions

How do I disable all logging in Telego?

Pass telego.WithDiscardLogger() when creating the bot. This sets both DebugMode and PrintErrors to false, making all logging calls no-ops. This is useful in production environments where you handle observability through external monitoring systems rather than stderr output.

Can I use Logrus or Zap instead of the default Telego logger?

Yes. Implement the Logger interface from main/logger.go with your library's methods, then pass it via telego.WithLogger(myLogger). The interface only requires Debugf(format string, args ...any) and Errorf(format string, args ...any), making it compatible with most Go logging adapters.

Is the bot token automatically hidden in logs?

Yes, by default. The WithDefaultLogger and WithDefaultDebugLogger options automatically configure a strings.Replacer that masks your actual token with the string BOT_TOKEN. If you use WithExtendedDefaultLogger with a custom replacer, ensure you still include the token replacement to maintain security. If you implement a custom logger via WithLogger, you must handle token masking yourself.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →