Reliability

Logging & debugging

gogram emits structured logs at five levels. Plug in your own logger so they end up wherever the rest of your application logs go.

Levels

Five levels, picked with ClientConfig.LogLevel:

LogTrace
Every message in and out, every state change. Very noisy — use only when chasing a specific bug.
LogDebug
Each RPC call and response with timing. The right setting when something does not work the way you expect.
LogInfo (default)
Lifecycle events: connect, login, DC migrate, disconnect. Should be quiet in steady state.
LogWarn
Recoverable issues: dropped reconnect, retried RPC, ignored flood wait.
LogError
Fatal-ish problems that lead to a failed call.
client, _ := telegram.NewClient(telegram.ClientConfig{
	// ...
	LogLevel: telegram.LogDebug,
})
client, _ := telegram.NewClient(telegram.ClientConfig{
	// ...
	LogLevel: telegram.LogDebug,
})

Custom logger

The Logger interface is small. Adapt it to log/slog, zap, zerolog, or whatever your codebase uses:

import "log/slog"

type slogAdapter struct{ l *slog.Logger }

func (s slogAdapter) Trace(msg string, args ...any) { s.l.Debug(msg, args...) }
func (s slogAdapter) Debug(msg string, args ...any) { s.l.Debug(msg, args...) }
func (s slogAdapter) Info(msg string, args ...any)  { s.l.Info(msg, args...) }
func (s slogAdapter) Warn(msg string, args ...any)  { s.l.Warn(msg, args...) }
func (s slogAdapter) Error(msg string, args ...any) { s.l.Error(msg, args...) }
// ... plus WithError / WithField helpers expected by telegram.Logger

client, _ := telegram.NewClient(telegram.ClientConfig{
	Logger: slogAdapter{l: slog.Default()},
})
import "log/slog"

type slogAdapter struct{ l *slog.Logger }

func (s slogAdapter) Trace(msg string, args ...any) { s.l.Debug(msg, args...) }
func (s slogAdapter) Debug(msg string, args ...any) { s.l.Debug(msg, args...) }
func (s slogAdapter) Info(msg string, args ...any)  { s.l.Info(msg, args...) }
func (s slogAdapter) Warn(msg string, args ...any)  { s.l.Warn(msg, args...) }
func (s slogAdapter) Error(msg string, args ...any) { s.l.Error(msg, args...) }
// ... plus WithError / WithField helpers expected by telegram.Logger

client, _ := telegram.NewClient(telegram.ClientConfig{
	Logger: slogAdapter{l: slog.Default()},
})

Tracing RPCs

At LogDebug, every RPC is logged with method name, request id, and duration. Match the request id between the request and response lines to attribute work.

Wire dumps

At LogTrace, gogram dumps the raw bytes of every MTProto packet after decryption. Useful when reproducing a server-side bug or filing an issue against gogram itself; almost never useful for application debugging.