Git Repository
Mini Video Library
Mini Video Library scannt lokale Medienordner, verwaltet Metadaten und Vorschaubilder und streamt kompatible Videos direkt per HTTP an den Browser.
HTTPS
https://zanvex.de/git/mini-video-library.gitinternal/logging/logging.go
Zum Verzeichnispackage logging
import (
"context"
"log/slog"
"sync"
"time"
)
type Entry struct {
Time time.Time `json:"time"`
Level string `json:"level"`
Message string `json:"message"`
Attributes map[string]string `json:"attributes,omitempty"`
}
type Store struct {
mu sync.RWMutex
entries []Entry
capacity int
}
func NewStore(capacity int) *Store {
if capacity < 1 {
capacity = 500
}
return &Store{capacity: capacity}
}
func (s *Store) Add(e Entry) {
s.mu.Lock()
defer s.mu.Unlock()
if len(s.entries) >= s.capacity {
copy(s.entries, s.entries[1:])
s.entries = s.entries[:s.capacity-1]
}
s.entries = append(s.entries, e)
}
func (s *Store) List(limit int) []Entry {
s.mu.RLock()
defer s.mu.RUnlock()
if limit <= 0 || limit > s.capacity {
limit = s.capacity
}
start := len(s.entries) - limit
if start < 0 {
start = 0
}
out := make([]Entry, len(s.entries)-start)
copy(out, s.entries[start:])
return out
}
type Handler struct {
base slog.Handler
store *Store
attrs []slog.Attr
group string
}
func NewHandler(base slog.Handler, store *Store) slog.Handler {
return &Handler{base: base, store: store}
}
func (h *Handler) Enabled(ctx context.Context, l slog.Level) bool { return h.base.Enabled(ctx, l) }
func (h *Handler) Handle(ctx context.Context, r slog.Record) error {
e := Entry{Time: r.Time, Level: r.Level.String(), Message: r.Message, Attributes: map[string]string{}}
for _, a := range h.attrs {
e.Attributes[h.key(a.Key)] = a.Value.String()
}
r.Attrs(func(a slog.Attr) bool { e.Attributes[h.key(a.Key)] = a.Value.String(); return true })
if len(e.Attributes) == 0 {
e.Attributes = nil
}
h.store.Add(e)
return h.base.Handle(ctx, r)
}
func (h *Handler) WithAttrs(a []slog.Attr) slog.Handler {
return &Handler{base: h.base.WithAttrs(a), store: h.store, attrs: append(append([]slog.Attr{}, h.attrs...), a...), group: h.group}
}
func (h *Handler) WithGroup(g string) slog.Handler {
group := g
if h.group != "" {
group = h.group + "." + g
}
return &Handler{base: h.base.WithGroup(g), store: h.store, attrs: h.attrs, group: group}
}
func (h *Handler) key(k string) string {
if h.group != "" {
return h.group + "." + k
}
return k
}