How to Enable Debug Logging in Telego: Complete Configuration Guide
Enable full debug logging in Telego by setting both Bot.debugMode (via WithDebugMode()) and logger.DebugMode (via WithDefaultDebugLogger() or a custom logger), then inspect raw API requests and responses in your console.
Telego is a fast, feature-complete Telegram Bot API library for Go. When building bots with mymmrac/telego, enabling debug logging helps you inspect raw HTTP requests, JSON payloads, and API responses during development. This guide explains the dual-flag system that controls debug output and provides production-ready configuration examples.
Understanding Telego's Dual Debug System
Telego implements debug logging through two independent flags that must both be enabled for complete visibility:
| Flag | Purpose | Location |
|---|---|---|
logger.DebugMode |
Controls whether Debugf calls actually write output. When false, debug messages are discarded at the logger level. |
logger.go lines 84-88 |
Bot.debugMode |
Controls whether the bot includes full request payload data in debug output (the "API call to ... with data: ..." line). | bot.go lines 43-49 |
Critical: If you only set Bot.debugMode without configuring the logger's DebugMode, the bot prepares payload strings but the logger discards them. Conversely, enabling the logger's DebugMode without Bot.debugMode shows response data but hides request payloads.
Enabling Debug Logging via Bot Options
Telego provides BotOption functions in bot_options.go to configure both flags. Choose the approach that matches your verbosity requirements:
-
WithDebugMode()— SetsBot.debugMode = true. Required for request payload logging. (Source:bot_options.golines 102-107) -
WithDefaultDebugLogger()— Replaces the default logger withDebugMode: trueandPrintErrors: true. Best for development. (Source:bot_options.golines 81-85) -
WithDefaultLogger(debugMode, printErrors)— Fine-grained control over the built-in logger. PasstruefordebugModeto enableDebugfoutput. (Source:bot_options.golines 50-61) -
WithExtendedDefaultLogger(debugMode, printErrors, replacer)— Same as above but accepts astrings.Replacerfor token redaction in logs. (Source:bot_options.golines 64-78) -
WithLogger(customLogger)— Inject any struct implementing theLoggerinterface. You must set itsDebugModefield totrue. (Source:bot_options.golines 92-99) -
WithDiscardLogger()— Disables all logging (production use). Equivalent toWithDefaultLogger(false, false). (Source:bot_options.golines 87-90)
Practical Implementation Examples
Quick Start: One-Liner Setup
Enable full debug output using the convenience option that configures both the bot and logger:
package main
import (
"github.com/mymmrac/telego"
)
func main() {
bot, err := telego.NewBot("YOUR_BOT_TOKEN",
telego.WithDefaultDebugLogger(), // Enables logger.DebugMode and PrintErrors
telego.WithDebugMode(), // Enables Bot.debugMode for request payloads
)
if err != nil {
panic(err)
}
// Both flags are now active; all API calls will show full request/response data
_ = bot
}
Output: Every API call prints the full URL, JSON payload, and raw response body.
Separate Control: Request Payloads Only
If you want request payload logging but prefer to handle errors separately:
bot, err := telego.NewBot("TOKEN",
telego.WithDebugMode(), // Enable request payload logging
telego.WithDefaultLogger(true, false), // Enable debug output, suppress errors
)
Result: You see "API call to ... with data: ..." lines, but error messages are suppressed.
Custom Logger Implementation
For advanced use cases (e.g., structured logging with slog or zap):
type structuredLogger struct {
debugMode bool
}
func (l *structuredLogger) Debugf(format string, args ...any) {
if l.debugMode {
slog.Debug(fmt.Sprintf(format, args...))
}
}
func (l *structuredLogger) Errorf(format string, args ...any) {
slog.Error(fmt.Sprintf(format, args...))
}
func main() {
customLog := &structuredLogger{debugMode: true}
bot, err := telego.NewBot("TOKEN",
telego.WithLogger(customLog),
telego.WithDebugMode(),
)
// ...
}
Note: Your custom logger must check its own debugMode flag inside Debugf, matching the behavior in logger.go.
Disabling Logging in Production
To completely silence the bot (default logger starts with DebugMode: false as defined in logger.go lines 45-53):
bot, err := telego.NewBot("TOKEN",
telego.WithDiscardLogger(), // Equivalent to WithDefaultLogger(false, false)
)
Key Source Files and Implementation Details
Understanding the source helps debug configuration issues:
-
logger.go— Contains the default logger implementation. TheDebugfmethod checksl.DebugModebefore writing (lines 84-88). ThenewDefaultLoggerconstructor initializesDebugMode: false(lines 45-53). -
bot.go— TheperformRequestmethod checksb.debugModebefore logging request payloads (lines 43-49). IfdebugModeistrue, it logs the API endpoint and JSON data. -
bot_options.go— Defines all configuration helpers. Options likeWithDefaultDebugLoggerwrap the logger initialization, whileWithDebugModetoggles the bot's payload logging flag.
Summary
- Two flags control debug output:
logger.DebugMode(controls whether debug messages are written) andBot.debugMode(controls whether request payloads are included in logs). - Use
WithDefaultDebugLogger()to enable the built-in logger's debug output and error printing in one option. - Always pair
WithDebugMode()with a logger configured for debug output to see full request/response traces. - For production, use
WithDiscardLogger()orWithDefaultLogger(false, false)to silence all output. - Custom loggers must implement the
Loggerinterface and respect their ownDebugModeflag insideDebugf.
Frequently Asked Questions
Why don't I see debug output after using WithDebugMode()?
You are likely missing the logger configuration. WithDebugMode() only sets Bot.debugMode, which controls whether the bot includes request payload strings in its debug calls. However, the default logger initializes with DebugMode: false (as seen in logger.go lines 45-53), causing it to discard all debug messages. You must also use WithDefaultDebugLogger() or WithDefaultLogger(true, ...) to enable the actual output.
What is the difference between WithDefaultDebugLogger() and WithDefaultLogger(true, true)?
Both enable debug output, but WithDefaultDebugLogger() is a convenience wrapper that explicitly sets both DebugMode and PrintErrors to true (source: bot_options.go lines 81-85). WithDefaultLogger(true, true) achieves the same result but requires you to pass the boolean arguments explicitly. Use WithDefaultDebugLogger() for brevity during development, and WithDefaultLogger() when you need fine-grained control over error printing.
How can I redact sensitive tokens from debug logs?
Use WithExtendedDefaultLogger(debugMode, printErrors, replacer) and provide a strings.Replacer that substitutes your token with a placeholder. For example:
replacer := strings.NewReplacer("YOUR_BOT_TOKEN", "[REDACTED]")
bot, err := telego.NewBot("YOUR_BOT_TOKEN",
telego.WithExtendedDefaultLogger(true, true, replacer),
telego.WithDebugMode(),
)
This replaces the sensitive string wherever it appears in the log output, including request payloads and URLs.
Can I use a structured logger like Zap or Slog with Telego?
Yes. Implement the Logger interface from logger.go which requires two methods: Debugf(format string, args ...any) and Errorf(format string, args ...any). In your implementation, call your structured logger's methods (e.g., slog.Debug() or logger.Info()). Ensure your wrapper checks an internal debugMode flag inside Debugf to match Telego's expected behavior, or always delegate to the underlying logger if you want unconditional debug output.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →