74 lines
1.7 KiB
Go
74 lines
1.7 KiB
Go
package shared
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
|
|
"galaxy/user/internal/logging"
|
|
)
|
|
|
|
// LogServiceOutcome writes one structured service-level outcome log with a
|
|
// stable severity derived from err and with trace fields attached when ctx
|
|
// carries an active span.
|
|
func LogServiceOutcome(logger *slog.Logger, ctx context.Context, message string, err error, attrs ...any) {
|
|
if logger == nil {
|
|
logger = slog.Default()
|
|
}
|
|
|
|
attrs = append(attrs, logging.TraceAttrsFromContext(ctx)...)
|
|
|
|
switch {
|
|
case err == nil:
|
|
logger.InfoContext(ctx, message, attrs...)
|
|
case isExpectedServiceErrorCode(CodeOf(err)):
|
|
logger.WarnContext(ctx, message, append(attrs, "error", err.Error())...)
|
|
default:
|
|
logger.ErrorContext(ctx, message, append(attrs, "error", err.Error())...)
|
|
}
|
|
}
|
|
|
|
// MetricOutcome returns the stable low-cardinality outcome label derived from
|
|
// err for service metrics.
|
|
func MetricOutcome(err error) string {
|
|
if err == nil {
|
|
return "success"
|
|
}
|
|
|
|
code := CodeOf(err)
|
|
if code == "" {
|
|
return ErrorCodeInternalError
|
|
}
|
|
|
|
return code
|
|
}
|
|
|
|
// LogEventPublicationFailure writes one structured error log for an auxiliary
|
|
// post-commit event publication failure.
|
|
func LogEventPublicationFailure(logger *slog.Logger, ctx context.Context, eventType string, err error, attrs ...any) {
|
|
if err == nil {
|
|
return
|
|
}
|
|
if logger == nil {
|
|
logger = slog.Default()
|
|
}
|
|
|
|
attrs = append(attrs,
|
|
"event_type", eventType,
|
|
"error", err.Error(),
|
|
)
|
|
attrs = append(attrs, logging.TraceAttrsFromContext(ctx)...)
|
|
|
|
logger.ErrorContext(ctx, "auxiliary event publication failed", attrs...)
|
|
}
|
|
|
|
func isExpectedServiceErrorCode(code string) bool {
|
|
switch code {
|
|
case ErrorCodeInvalidRequest,
|
|
ErrorCodeConflict,
|
|
ErrorCodeSubjectNotFound:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|