✨ Enhance logging configuration by introducing file output options and rotation settings in config.dev.toml. Update logger implementation to support multiple output streams, including file logging with rotation using lumberjack. Improve error handling and logging across various components, ensuring consistent logging practices. Update .gitignore to include log files and compressed logs. Add new Go module dependency for lumberjack.
This commit is contained in:
@@ -713,6 +713,12 @@ func (c *Consumer) routeToDLQ(ctx context.Context, msg *nats.Msg, cause error) e
|
||||
|
||||
data, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
c.logger.Error("failed to marshal DLQ payload",
|
||||
zap.String("stream", c.streamName),
|
||||
zap.String("consumer", c.consumerName),
|
||||
zap.String("dlq_subject", c.dlqSubject),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("marshal dlq payload: %w", err)
|
||||
}
|
||||
|
||||
@@ -722,9 +728,23 @@ func (c *Consumer) routeToDLQ(ctx context.Context, msg *nats.Msg, cause error) e
|
||||
// unavailable. Surface this explicitly to make operational diagnosis
|
||||
// easier.
|
||||
if errors.Is(err, nats.ErrNoResponders) {
|
||||
c.logger.Error("transient DLQ publish error (no responders)",
|
||||
zap.String("stream", c.streamName),
|
||||
zap.String("consumer", c.consumerName),
|
||||
zap.String("dlq_subject", c.dlqSubject),
|
||||
zap.Int("payload_size", len(data)),
|
||||
zap.Error(err),
|
||||
)
|
||||
c.telemetry.RecordDLQPublishFailure(ctx, c.streamName, c.consumerName)
|
||||
return fmt.Errorf("publish to dlq subject %s: no JetStream stream found for subject or JetStream unavailable: %w", c.dlqSubject, err)
|
||||
}
|
||||
c.logger.Error("failed to publish to DLQ",
|
||||
zap.String("stream", c.streamName),
|
||||
zap.String("consumer", c.consumerName),
|
||||
zap.String("dlq_subject", c.dlqSubject),
|
||||
zap.Int("payload_size", len(data)),
|
||||
zap.Error(err),
|
||||
)
|
||||
c.telemetry.RecordDLQPublishFailure(ctx, c.streamName, c.consumerName)
|
||||
return fmt.Errorf("publish to dlq subject %s: %w", c.dlqSubject, err)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,12 @@ func ProvideNATSConn(cfg *config.Config, logger *zap.Logger) (*nats.Conn, error)
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("failed to connect to NATS",
|
||||
zap.String("url", cfg.NATS.URL),
|
||||
zap.Duration("timeout", cfg.Timeouts.Server),
|
||||
zap.Duration("reconnect_wait", cfg.Timeouts.ReconnectWait),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("failed to connect to NATS: %w", err)
|
||||
}
|
||||
|
||||
@@ -41,6 +47,10 @@ func ProvideJetStream(nc *nats.Conn, cfg *config.Config, logger *zap.Logger) (na
|
||||
// Get JetStream context
|
||||
js, err := nc.JetStream()
|
||||
if err != nil {
|
||||
logger.Error("failed to get JetStream context",
|
||||
zap.String("url", cfg.NATS.URL),
|
||||
zap.Error(err),
|
||||
)
|
||||
nc.Close()
|
||||
return nil, fmt.Errorf("failed to get JetStream context: %w", err)
|
||||
}
|
||||
@@ -67,6 +77,11 @@ func EnsureStream(js nats.JetStreamContext, cfg *config.Config, logger *zap.Logg
|
||||
|
||||
streamSubjects := dedupeSubjects([]string{consumerSubject, publisherSubject})
|
||||
if len(streamSubjects) == 0 {
|
||||
logger.Error("no subjects configured for JetStream stream",
|
||||
zap.String("stream", streamName),
|
||||
zap.String("consumer_subject", consumerSubject),
|
||||
zap.String("publisher_subject", publisherSubject),
|
||||
)
|
||||
return fmt.Errorf("no subjects configured for JetStream stream %s", streamName)
|
||||
}
|
||||
|
||||
@@ -101,6 +116,11 @@ func EnsureStream(js nats.JetStreamContext, cfg *config.Config, logger *zap.Logg
|
||||
if errors.Is(err, nats.ErrStreamNotFound) {
|
||||
if shouldBootstrapStream() {
|
||||
if _, err = js.AddStream(streamConfig); err != nil {
|
||||
logger.Error("failed to create stream",
|
||||
zap.String("stream", streamName),
|
||||
zap.Strings("subjects", streamSubjects),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("failed to create stream %s: %w", streamName, err)
|
||||
}
|
||||
logger.Info("Created JetStream stream",
|
||||
@@ -109,8 +129,16 @@ func EnsureStream(js nats.JetStreamContext, cfg *config.Config, logger *zap.Logg
|
||||
)
|
||||
return nil
|
||||
}
|
||||
logger.Error("stream not found and auto-creation disabled",
|
||||
zap.String("stream", streamName),
|
||||
zap.Strings("expected_subjects", streamSubjects),
|
||||
)
|
||||
return fmt.Errorf("stream %s not found and auto-creation disabled", streamName)
|
||||
}
|
||||
logger.Error("failed to fetch stream info",
|
||||
zap.String("stream", streamName),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("failed to fetch stream info for %s: %w", streamName, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,12 +37,17 @@ func ProvidePublisher(
|
||||
func (p *Publisher) Publish(message interface{}) error {
|
||||
topic := p.cfg.Publisher.Topic
|
||||
if topic == "" {
|
||||
p.logger.Error("publisher topic is not configured")
|
||||
return fmt.Errorf("publisher topic is not configured")
|
||||
}
|
||||
|
||||
// Marshal message to JSON
|
||||
messageBytes, err := json.Marshal(message)
|
||||
if err != nil {
|
||||
p.logger.Error("failed to marshal message",
|
||||
zap.String("topic", topic),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("failed to marshal message: %w", err)
|
||||
}
|
||||
|
||||
@@ -66,8 +71,18 @@ func (p *Publisher) Publish(message interface{}) error {
|
||||
if err != nil {
|
||||
// Distinguish temporary JetStream unavailability from permanent config errors.
|
||||
if errors.Is(err, nats.ErrNoResponders) {
|
||||
p.logger.Error("transient publish error (no responders)",
|
||||
zap.String("topic", topic),
|
||||
zap.Int("message_size", len(messageBytes)),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("transient publish error (no responders): %w", err)
|
||||
}
|
||||
p.logger.Error("failed to publish message",
|
||||
zap.String("topic", topic),
|
||||
zap.Int("message_size", len(messageBytes)),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("failed to publish message: %w", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user