Documentation
¶
Overview ¶
Package telegram is a log/slog handler that sends records to Telegram chats, ported from the maintainer's TypeScript telegram-logger. Messages are queued and sent in the background, so logging never blocks or fails a request.
tg := telegram.NewHandler(telegram.Config{BotToken: token, ChatID: "-100123", MinLevel: slog.LevelError})
log := slog.New(slog.NewMultiHandler(base, tg))
defer tg.Close(ctx)
Without a bot token and chat id the Handler is disabled, so apps can always install it; the bot token is a config.Secret and never appears in errors.
See https://github.com/AlexGalhardo/vukem/blob/main/docs/subsystems.md#telegram-logging.
Index ¶
- Constants
- Variables
- type Config
- type Handler
- func (h *Handler) Close(ctx context.Context) error
- func (h *Handler) Contact(_ context.Context, fields map[string]string)
- func (h *Handler) Enabled(_ context.Context, l slog.Level) bool
- func (h *Handler) Handle(_ context.Context, r slog.Record) error
- func (h *Handler) Send(_ context.Context, htmlText string)
- func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler
- func (h *Handler) WithGroup(name string) slog.Handler
Examples ¶
Constants ¶
const ( LevelSuccess slog.Level = 2 LevelFatal slog.Level = 12 )
Custom levels for Success and Fatal helpers.
const MaxLength = 4096
MaxLength is Telegram's message limit.
Variables ¶
var ErrQueueFull = errors.New("telegram: queue full, message dropped")
ErrQueueFull is reported when a message is dropped.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
BotToken config.Secret
// ChatID is the default chat; ChatIDs routes levels to other chats.
ChatID string
ChatIDs map[slog.Level]string
// MinLevel filters records (default: error).
MinLevel slog.Level
AppName string
Env string
// ThreadID posts into a forum topic.
ThreadID int
// Silent sends without notification sound.
Silent bool
// QueueSize bounds pending messages (default 100); when full, new
// messages are dropped and reported to OnError.
QueueSize int
// Timeout bounds each request (default 5s).
Timeout time.Duration
// MaxRetryAfter caps the wait for one retry after HTTP 429 (default 10s).
MaxRetryAfter time.Duration
// OnError is told about delivery failures (never contains the token).
OnError func(error)
// BaseURL defaults to https://api.telegram.org (tests use a fake).
BaseURL string
// HTTP is the client (default: Timeout per request).
HTTP *http.Client
}
Config configures the handler. Without BotToken and ChatID the handler is disabled (Enabled reports false), so it can always be installed.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler implements slog.Handler.
func NewHandler ¶
NewHandler returns a handler and starts its sender goroutine (when enabled); call Close to drain it.
Example ¶
package main
import (
"context"
"encoding/json"
"fmt"
"log/slog"
"net/http"
"net/http/httptest"
"github.com/AlexGalhardo/vukem/config"
"github.com/AlexGalhardo/vukem/logging/telegram"
)
func main() {
// A fake Bot API stands in for https://api.telegram.org.
api := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var body struct {
ChatID string `json:"chat_id"`
}
_ = json.NewDecoder(r.Body).Decode(&body)
fmt.Println("sent to chat", body.ChatID)
_, _ = w.Write([]byte(`{"ok":true}`))
}))
defer api.Close()
tg := telegram.NewHandler(telegram.Config{
BotToken: config.NewSecret("123:TOKEN"),
ChatID: "-100123",
MinLevel: slog.LevelError,
BaseURL: api.URL,
})
log := slog.New(tg)
log.Info("ignored: below MinLevel")
log.Error("payment failed", "order_id", 42)
// Close flushes queued messages before shutdown.
_ = tg.Close(context.Background())
}
Output: sent to chat -100123
func (*Handler) Contact ¶
Contact queues a contact-form notification (never filtered by level); every field is escaped.
func (*Handler) Send ¶
Send queues a pre-formatted HTML message for the default chat (the caller escapes user content).