Nik Afiq 39b7d6d4b4
All checks were successful
CI / changes (push) Successful in 19s
CI / test (push) Successful in 31s
CI / build-ai-gateway (push) Successful in 1m8s
CI / build-ha-gateway (push) Successful in 1m19s
CI / build-discord-bot (push) Successful in 59s
CI / build-alexa-bridge (push) Successful in 1m8s
CI / build-alert-bridge (push) Successful in 1m17s
CI / build-tts-gateway (push) Successful in 1m10s
CI / build-tts-sidecar (push) Has been skipped
CI / build-tts-model (push) Has been skipped
feat: add alert-bridge service for external cronjob -> Discord alerts
New standalone service that receives authenticated HTTP POSTs (e.g. from a
cronjob elsewhere on the home network) and posts them to a Discord channel
via an Incoming Webhook. Fire-and-forget, no dependency on discord-bot's bot
session at all - mirrors alexa-bridge's precedent of a small bridge service
with its own HTTP listener and auth rather than adding an inbound edge to an
existing internal service.

Wires alert-bridge into go.work, CI (changes filter, test job, new
build-alert-bridge job), and the other five Dockerfiles' COPY lines.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 22:45:18 +09:00

39 lines
1013 B
Go

package logger
import (
"context"
"fmt"
"log/slog"
"os"
)
type contextKey struct{}
// New constructs a root logger for the configured format and level.
func New(format, level string) *slog.Logger {
var parsed slog.Level
if err := parsed.UnmarshalText([]byte(level)); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "invalid log level %q, falling back to info\n", level)
parsed = slog.LevelInfo
}
opts := &slog.HandlerOptions{Level: parsed}
if format == "json" {
return slog.New(slog.NewJSONHandler(os.Stdout, opts))
}
return slog.New(slog.NewTextHandler(os.Stdout, opts))
}
// WithLogger attaches a logger to the provided context.
func WithLogger(ctx context.Context, l *slog.Logger) context.Context {
return context.WithValue(ctx, contextKey{}, l)
}
// FromContext retrieves a logger from context and falls back to slog.Default().
func FromContext(ctx context.Context) *slog.Logger {
if l, ok := ctx.Value(contextKey{}).(*slog.Logger); ok && l != nil {
return l
}
return slog.Default()
}