# Telego Logging Options and Configuration: A Complete Guide

> Explore Telego logging options and configuration. Customize the built-in logger or implement your own with automatic token masking. A complete guide for mymmrac/telego.

- Repository: [Artem Yadelskyi/telego](https://github.com/mymmrac/telego)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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`](https://github.com/mymmrac/telego/blob/main/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:

```go
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`](https://github.com/mymmrac/telego/blob/main/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`](https://github.com/mymmrac/telego/blob/main/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:

```go
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:

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

```

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

```go
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:

```go
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`:

```go
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`](https://github.com/mymmrac/telego/blob/main/main/logger.go) creates a `strings.Replacer` that substitutes the real bot token with the constant `BOT_TOKEN` string before writing to output:

```go
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`](https://github.com/mymmrac/telego/blob/main/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:

```go
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`](https://github.com/mymmrac/telego/blob/main/main/logger.go).
- **Bot options** in [`main/bot_options.go`](https://github.com/mymmrac/telego/blob/main/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`](https://github.com/mymmrac/telego/blob/main/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.