feat: mail service
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
// Package logging configures the Mail Service process logger and provides
|
||||
// context-aware helpers for trace, delivery, attempt, and command fields.
|
||||
package logging
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"galaxy/mail/internal/api/streamcommand"
|
||||
"galaxy/mail/internal/domain/attempt"
|
||||
deliverydomain "galaxy/mail/internal/domain/delivery"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// New constructs the process-wide JSON logger from level.
|
||||
func New(level string) (*slog.Logger, error) {
|
||||
var slogLevel slog.Level
|
||||
if err := slogLevel.UnmarshalText([]byte(strings.TrimSpace(level))); err != nil {
|
||||
return nil, fmt.Errorf("build logger: %w", err)
|
||||
}
|
||||
|
||||
return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slogLevel,
|
||||
})), nil
|
||||
}
|
||||
|
||||
// TraceAttrsFromContext returns slog key-value pairs for the active
|
||||
// OpenTelemetry span when ctx carries a valid span context.
|
||||
func TraceAttrsFromContext(ctx context.Context) []any {
|
||||
if ctx == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
spanContext := trace.SpanContextFromContext(ctx)
|
||||
if !spanContext.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []any{
|
||||
"otel_trace_id", spanContext.TraceID().String(),
|
||||
"otel_span_id", spanContext.SpanID().String(),
|
||||
}
|
||||
}
|
||||
|
||||
// DeliveryAttrs returns structured delivery-identifying log fields.
|
||||
func DeliveryAttrs(record deliverydomain.Delivery) []any {
|
||||
attrs := []any{
|
||||
"delivery_id", record.DeliveryID.String(),
|
||||
"source", string(record.Source),
|
||||
}
|
||||
if !record.TemplateID.IsZero() {
|
||||
attrs = append(attrs, "template_id", record.TemplateID.String())
|
||||
}
|
||||
|
||||
return attrs
|
||||
}
|
||||
|
||||
// AttemptAttrs returns structured attempt-identifying log fields.
|
||||
func AttemptAttrs(record attempt.Attempt) []any {
|
||||
return []any{
|
||||
"delivery_id", record.DeliveryID.String(),
|
||||
"attempt_no", record.AttemptNo,
|
||||
}
|
||||
}
|
||||
|
||||
// DeliveryAttemptAttrs returns structured delivery and attempt fields.
|
||||
func DeliveryAttemptAttrs(deliveryRecord deliverydomain.Delivery, attemptRecord attempt.Attempt) []any {
|
||||
attrs := DeliveryAttrs(deliveryRecord)
|
||||
attrs = append(attrs, "attempt_no", attemptRecord.AttemptNo)
|
||||
return attrs
|
||||
}
|
||||
|
||||
// CommandAttrs returns structured generic-command log fields.
|
||||
func CommandAttrs(command streamcommand.Command) []any {
|
||||
attrs := []any{
|
||||
"delivery_id", command.DeliveryID.String(),
|
||||
"source", string(command.Source),
|
||||
}
|
||||
if !command.TemplateID.IsZero() {
|
||||
attrs = append(attrs, "template_id", command.TemplateID.String())
|
||||
}
|
||||
if strings.TrimSpace(command.TraceID) != "" {
|
||||
attrs = append(attrs, "trace_id", command.TraceID)
|
||||
}
|
||||
|
||||
return attrs
|
||||
}
|
||||
Reference in New Issue
Block a user