Enhance observability and error handling in NATS integration. Introduce comprehensive OpenTelemetry support with environment-based sampling and semantic attributes for tracing and metrics. Implement an advisory dead-letter queue (DLQ) handler for managing message delivery failures. Update NATS consumer to utilize structured logging and improve error handling strategies. Refactor configuration files for OpenTelemetry collector in both development and production environments, ensuring robust telemetry integration. Enhance documentation to reflect new features and best practices for observability.

This commit is contained in:
windyboy
2025-11-18 11:47:35 +08:00
parent 5d05237283
commit 7f44b5389d
31 changed files with 2546 additions and 476 deletions
+51 -6
View File
@@ -1,8 +1,10 @@
package nats
import (
"caatsm/internal/infra/config"
"errors"
"fmt"
"strings"
"github.com/nats-io/nats.go"
"go.uber.org/zap"
@@ -14,6 +16,7 @@ type StreamManager struct {
streamName string
subjects []string
logger *zap.Logger
cfg *config.StreamLimitsConfig
}
// NewStreamManager creates a new stream manager
@@ -26,14 +29,21 @@ func NewStreamManager(js nats.JetStreamContext, streamName string, subjects []st
}
}
// NewStreamManagerWithConfig creates a new stream manager with full stream configuration
func NewStreamManagerWithConfig(js nats.JetStreamContext, streamName string, subjects []string, streamLimits *config.StreamLimitsConfig, logger *zap.Logger) *StreamManager {
return &StreamManager{
js: js,
streamName: streamName,
subjects: subjects,
logger: logger,
cfg: streamLimits,
}
}
// EnsureStream ensures that the configured JetStream stream exists
func (sm *StreamManager) EnsureStream() error {
streamConfig := &nats.StreamConfig{
Name: sm.streamName,
Subjects: sm.subjects,
Retention: nats.LimitsPolicy,
Storage: nats.FileStorage,
}
// Build stream configuration
streamConfig := sm.buildStreamConfig()
info, err := sm.js.StreamInfo(sm.streamName)
if err != nil {
@@ -71,6 +81,41 @@ func (sm *StreamManager) EnsureStream() error {
return nil
}
// buildStreamConfig builds the stream configuration from manager settings
func (sm *StreamManager) buildStreamConfig() *nats.StreamConfig {
config := &nats.StreamConfig{
Name: sm.streamName,
Subjects: sm.subjects,
Retention: nats.LimitsPolicy,
Storage: nats.FileStorage,
}
// Apply stream limits configuration if provided
if sm.cfg != nil {
config.MaxMsgs = sm.cfg.MaxMsgs
config.MaxBytes = sm.cfg.MaxBytes
config.MaxAge = sm.cfg.MaxAge
config.Replicas = sm.cfg.Replicas
// Map storage type
switch strings.ToLower(sm.cfg.Storage) {
case "memory":
config.Storage = nats.MemoryStorage
case "file":
config.Storage = nats.FileStorage
}
// Map discard policy
if strings.EqualFold(sm.cfg.Discard, "new") {
config.Discard = nats.DiscardNew
} else {
config.Discard = nats.DiscardOld
}
}
return config
}
// validateStreamConfig validates the stream configuration
func (sm *StreamManager) validateStreamConfig(info *nats.StreamInfo) {
if info == nil {