fix: create socket parent directory on startup
- Create /var/run/logcorrelator/ if missing before binding sockets - Fixes issue with tmpfs /var/run being cleared on reboot - Add filepath import for directory handling Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -7,6 +7,7 @@ import (
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -67,6 +68,12 @@ func (s *UnixSocketSource) Start(ctx context.Context, eventChan chan<- *domain.N
|
||||
return fmt.Errorf("socket path cannot be empty")
|
||||
}
|
||||
|
||||
// Create parent directory if it doesn't exist
|
||||
socketDir := filepath.Dir(s.config.Path)
|
||||
if err := os.MkdirAll(socketDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create socket directory %s: %w", socketDir, err)
|
||||
}
|
||||
|
||||
// Remove existing socket file if present
|
||||
if info, err := os.Stat(s.config.Path); err == nil {
|
||||
if info.Mode()&os.ModeSocket != 0 {
|
||||
|
||||
@ -5,28 +5,37 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/logcorrelator/logcorrelator/internal/domain"
|
||||
"github.com/logcorrelator/logcorrelator/internal/observability"
|
||||
)
|
||||
|
||||
// Config holds the stdout sink configuration.
|
||||
type Config struct {
|
||||
Enabled bool
|
||||
Level string // DEBUG, INFO, WARN, ERROR - filters output verbosity
|
||||
}
|
||||
|
||||
// StdoutSink writes correlated logs to stdout as JSON lines.
|
||||
type StdoutSink struct {
|
||||
config Config
|
||||
mu sync.Mutex
|
||||
enc *json.Encoder
|
||||
config Config
|
||||
mu sync.Mutex
|
||||
enc *json.Encoder
|
||||
minLevel observability.LogLevel
|
||||
}
|
||||
|
||||
// NewStdoutSink creates a new stdout sink.
|
||||
func NewStdoutSink(config Config) *StdoutSink {
|
||||
level := observability.INFO
|
||||
if config.Level != "" {
|
||||
level = observability.ParseLogLevel(strings.ToUpper(config.Level))
|
||||
}
|
||||
return &StdoutSink{
|
||||
config: config,
|
||||
enc: json.NewEncoder(os.Stdout),
|
||||
config: config,
|
||||
enc: json.NewEncoder(os.Stdout),
|
||||
minLevel: level,
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +54,12 @@ func (s *StdoutSink) Write(ctx context.Context, log domain.CorrelatedLog) error
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
// Filter output based on correlation status and log level
|
||||
// DEBUG: all logs, INFO: only correlated, WARN: only correlated with issues, ERROR: none
|
||||
if !s.shouldEmit(log) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.enc.Encode(log); err != nil {
|
||||
return fmt.Errorf("failed to write to stdout: %w", err)
|
||||
}
|
||||
@ -52,6 +67,26 @@ func (s *StdoutSink) Write(ctx context.Context, log domain.CorrelatedLog) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// shouldEmit determines if a log should be emitted based on its correlation status and configured level.
|
||||
func (s *StdoutSink) shouldEmit(log domain.CorrelatedLog) bool {
|
||||
switch s.minLevel {
|
||||
case observability.DEBUG:
|
||||
// Emit everything including orphans
|
||||
return true
|
||||
case observability.INFO:
|
||||
// Emit all correlated logs, skip orphans
|
||||
return log.Correlated
|
||||
case observability.WARN:
|
||||
// Emit only correlated logs (same as INFO for now, can be extended)
|
||||
return log.Correlated
|
||||
case observability.ERROR:
|
||||
// Never emit to stdout at ERROR level
|
||||
return false
|
||||
default:
|
||||
return log.Correlated
|
||||
}
|
||||
}
|
||||
|
||||
// Flush flushes any buffered data (no-op for stdout).
|
||||
func (s *StdoutSink) Flush(ctx context.Context) error {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user