40 lines
1.6 KiB
Go
40 lines
1.6 KiB
Go
// Package logctx переносит scoped-логдер загрузки через context.Context.
|
||
//
|
||
// На приёме/реконсиляции загрузки заводим логгер с её ключами
|
||
// (download_id [+ infohash], capability) и кладём в ctx; стадии (скачивание →
|
||
// распознавание → раскладка → ревью) достают его через From и пишут с уже
|
||
// дописанными ключами — без ручного доклеивания download_id в каждый вызов.
|
||
package logctx
|
||
|
||
import (
|
||
"context"
|
||
"log/slog"
|
||
)
|
||
|
||
type ctxKey struct{}
|
||
|
||
// With возвращает ctx со вложенным логгером.
|
||
func With(ctx context.Context, log *slog.Logger) context.Context {
|
||
return context.WithValue(ctx, ctxKey{}, log)
|
||
}
|
||
|
||
// From достаёт логгер из ctx; при отсутствии — slog.Default().
|
||
func From(ctx context.Context) *slog.Logger {
|
||
return FromOr(ctx, slog.Default())
|
||
}
|
||
|
||
// FromOr достаёт логгер из ctx; при отсутствии — fallback (или slog.Default(),
|
||
// если fallback nil). Удобно во внешних клиентах: внутри стадии загрузки вернёт
|
||
// scoped-логгер с download_id, при автономном вызове — собственный логгер клиента.
|
||
func FromOr(ctx context.Context, fallback *slog.Logger) *slog.Logger {
|
||
if ctx != nil {
|
||
if log, ok := ctx.Value(ctxKey{}).(*slog.Logger); ok && log != nil {
|
||
return log
|
||
}
|
||
}
|
||
if fallback != nil {
|
||
return fallback
|
||
}
|
||
return slog.Default()
|
||
}
|