docs: ai 协作文档体系重构与多 ai 仲裁结果落地
1.AI 协作文档体系重构(objections/worklines/contracts+matrix.md) 2.coord 仲裁文档(final-decisions/cross-review/final-rulings/orchestration) 3.各服务 01/02 文档补全 4.共享包初始化(shared-ts/shared-go/hooks/ui-components/ui-tokens) 5.Proto 契约补全 6.004 架构影响地图更新 7.端口分配表 8.设计规格文档
This commit is contained in:
65
packages/shared-go/logger/logger.go
Normal file
65
packages/shared-go/logger/logger.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Package logger provides a structured logger built on zap with OpenTelemetry
|
||||
// trace correlation.
|
||||
//
|
||||
// In production (the default) logs are emitted as JSON at Info level. When the
|
||||
// ENV environment variable is set to "development" the logger switches to a
|
||||
// console encoder at Debug level for human-readable output.
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// ctxKey is an unexported type so context values cannot collide with callers.
|
||||
type ctxKey struct{}
|
||||
|
||||
// fallback is returned by FromContext when no logger has been injected into
|
||||
// the context; it discards all output so callers never receive a nil logger.
|
||||
var fallback = zap.NewNop()
|
||||
|
||||
// New creates a structured logger tagged with serviceName. The encoder and
|
||||
// level are selected from the ENV environment variable as described in the
|
||||
// package documentation.
|
||||
func New(serviceName string) *zap.Logger {
|
||||
var cfg zap.Config
|
||||
if os.Getenv("ENV") == "development" {
|
||||
cfg = zap.NewDevelopmentConfig()
|
||||
cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||
} else {
|
||||
cfg = zap.NewProductionConfig()
|
||||
cfg.Level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
|
||||
}
|
||||
|
||||
l, err := cfg.Build(zap.Fields(zap.String("service", serviceName)))
|
||||
if err != nil {
|
||||
// A logger that cannot be constructed is a fatal misconfiguration;
|
||||
// there is no safe way to continue.
|
||||
panic(err)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// WithContext returns a copy of ctx that carries l so it can later be
|
||||
// retrieved via FromContext.
|
||||
func WithContext(ctx context.Context, l *zap.Logger) context.Context {
|
||||
return context.WithValue(ctx, ctxKey{}, l)
|
||||
}
|
||||
|
||||
// FromContext returns the logger stored in ctx. When an active OpenTelemetry
|
||||
// span is present, the returned logger is decorated with a trace_id field so
|
||||
// log lines can be correlated to traces. If no logger was stored in ctx a
|
||||
// no-op logger is returned.
|
||||
func FromContext(ctx context.Context) *zap.Logger {
|
||||
if v, ok := ctx.Value(ctxKey{}).(*zap.Logger); ok && v != nil {
|
||||
if sc := trace.SpanContextFromContext(ctx); sc.HasTraceID() {
|
||||
return v.With(zap.String("trace_id", sc.TraceID().String()))
|
||||
}
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
Reference in New Issue
Block a user