Files
log/record.go
T
lixen 2417e51da1
Test / test (push) Canceled after 0s
Test / fuzz (./compat, FuzzParseFormat) (push) Canceled after 0s
Test / fuzz (./formatter, FuzzFormatJSON) (push) Canceled after 0s
Test / fuzz (./formatter, FuzzFormatTextPolicy) (push) Canceled after 0s
Test / fuzz (./sanitizer, FuzzSanitize) (push) Canceled after 0s
Test / fuzz (./sanitizer, FuzzSerializerJSON) (push) Canceled after 0s
v0.1.11 harden logging lifecycle, sanitization, and formatter edge cases
2026-09-26 14:25:14 -04:00

81 lines
2.0 KiB
Go

package log
import (
"fmt"
"os"
"slices"
"strings"
"time"
)
// getCurrentLogChannel returns the active record channel, nil when detached
func (l *Logger) getCurrentLogChannel() chan logRecord {
ch, _ := l.state.ActiveLogChannel.Load().(chan logRecord)
return ch
}
// getFlags returns the cached default record flags
func (l *Logger) getFlags() int64 {
return l.state.Flags.Load()
}
// sendLogRecord never waits for queue capacity or I/O. The short read lock
// ensures Stop cannot finish draining while a producer still holds the old queue.
func (l *Logger) sendLogRecord(record logRecord) {
l.sendMu.RLock()
defer l.sendMu.RUnlock()
if l.state.LoggerDisabled.Load() {
l.handleFailedSend()
return
}
ch := l.getCurrentLogChannel()
select {
case ch <- record:
default:
l.handleFailedSend()
}
}
// handleFailedSend increments drop counters
func (l *Logger) handleFailedSend() {
l.state.DroppedLogs.Add(1) // Interval counter
l.state.TotalDroppedLogs.Add(1) // Total counter
}
// emit builds and queues a record; the caller has already passed the level gate
func (l *Logger) emit(ctx Context, flags, level, depth int64, args []any) {
// Depth filter hard-coded based on call stack of current package design
var trace string
if depth > 0 {
const skipTrace = 3 // Logger.Info -> emit -> getTrace
trace = getTrace(depth, skipTrace)
}
l.sendLogRecord(logRecord{
Ctx: ctx,
Flags: flags,
TimeStamp: time.Now(),
Level: level,
Trace: trace,
Args: slices.Clone(args),
})
}
// internalLog reports logger diagnostics to the registered handler, or to
// stderr when configured. Hosts owning a terminal must register a handler.
func (l *Logger) internalLog(format string, args ...any) {
if !strings.HasPrefix(format, "log: ") {
format = "log: " + format
}
if h := l.errHandler.Load(); h != nil {
(*h)(strings.TrimRight(fmt.Sprintf(format, args...), "\n"))
return
}
if !l.getConfig().InternalErrorsToStderr {
return
}
fmt.Fprintf(os.Stderr, format, args...)
}