package mq import ( "context" "encoding/json" "log/slog" "time" "git.ipao.vip/rogee/go-sip/internal/logging" amqp "github.com/rabbitmq/amqp091-go" ) func messageIdentity(body []byte) []any { var m struct { EventID string `json:"event_id"` EventType string `json:"event_type"` DispatcherID string `json:"dispatcher_id"` Payload struct { TaskID string `json:"task_id"` } `json:"payload"` } if err := json.Unmarshal(body, &m); err != nil { return nil } return []any{"event_id", m.EventID, "event_type", m.EventType, "dispatcher_id", m.DispatcherID, "task_id", m.Payload.TaskID} } func observeDelivery(ctx context.Context, queue string, d *amqp.Delivery) { attrs := append(messageIdentity(d.Body), "transport", "mq", "direction", "mq->dispatcher", "queue", queue, "routing_key", d.RoutingKey, "message_id", d.MessageId, "delivery_tag", d.DeliveryTag, "redelivered", d.Redelivered) slog.InfoContext(ctx, "MQ delivery", append(attrs, "stage", "received", "body_bytes", len(d.Body))...) logging.Body(ctx, "MQ receive data", d.Body, append(attrs, "stage", "received")...) if d.Acknowledger != nil { d.Acknowledger = &observedAcknowledger{next: d.Acknowledger, ctx: ctx, attrs: attrs, started: time.Now()} } } type observedAcknowledger struct { next amqp.Acknowledger ctx context.Context attrs []any started time.Time } func (a *observedAcknowledger) report(stage string, err error) { attrs := append(append([]any{}, a.attrs...), "direction", "dispatcher->mq", "stage", stage, "duration_ms", time.Since(a.started).Milliseconds()) if err != nil { slog.ErrorContext(a.ctx, "MQ disposition failed", append(attrs, "error", err)...) } else { slog.InfoContext(a.ctx, "MQ disposition", attrs...) } } func (a *observedAcknowledger) Ack(tag uint64, multiple bool) error { err := a.next.Ack(tag, multiple) a.report("ack_sent", err) return err } func (a *observedAcknowledger) Nack(tag uint64, multiple, requeue bool) error { err := a.next.Nack(tag, multiple, requeue) stage := "nack_sent" if requeue { stage = "requeue_requested" } a.report(stage, err) return err } func (a *observedAcknowledger) Reject(tag uint64, requeue bool) error { err := a.next.Reject(tag, requeue) stage := "reject_sent" if requeue { stage = "requeue_requested" } a.report(stage, err) return err }