Change default output to Unix socket
Some checks failed
Build RPM Package / Build RPM Packages (CentOS 7, Rocky 8/9/10) (push) Has been cancelled

- config.yml.example: Unix socket enabled by default, stdout commented out
- internal/output/writers.go: Remove all internal logging from UnixSocketWriter
  and FileWriter - only LogRecord JSON data is sent to outputs
- architecture.yml: Update description to mention 'socket UNIX par défaut'
- packaging/rpm/ja4sentinel.spec: Bump version to 1.1.1, update changelog

Diagnostic logs (error, debug, warning) now only go to stdout when enabled.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Jacquin Antoine
2026-03-02 21:19:57 +01:00
parent 52c9f2f6f4
commit 6e5addd6d4
4 changed files with 24 additions and 70 deletions

View File

@ -5,11 +5,9 @@ import (
"encoding/json"
"fmt"
"io"
"log"
"net"
"os"
"path/filepath"
"strings"
"sync"
"time"
@ -205,6 +203,7 @@ func (w *FileWriter) Reopen() error {
}
// UnixSocketWriter writes log records to a UNIX socket with reconnection logic
// No internal logging - only LogRecord JSON data is sent to the socket
type UnixSocketWriter struct {
socketPath string
conn net.Conn
@ -221,8 +220,6 @@ type UnixSocketWriter struct {
isClosed bool
pendingWrites [][]byte
pendingMu sync.Mutex
logLevel string
logger *log.Logger
}
// NewUnixSocketWriter creates a new UNIX socket writer with reconnection logic
@ -232,11 +229,6 @@ func NewUnixSocketWriter(socketPath string) (*UnixSocketWriter, error) {
// NewUnixSocketWriterWithConfig creates a new UNIX socket writer with custom configuration
func NewUnixSocketWriterWithConfig(socketPath string, dialTimeout, writeTimeout time.Duration, queueSize int) (*UnixSocketWriter, error) {
return NewUnixSocketWriterWithConfigAndLogLevel(socketPath, dialTimeout, writeTimeout, queueSize, "error")
}
// NewUnixSocketWriterWithConfigAndLogLevel creates a new UNIX socket writer with log level configuration
func NewUnixSocketWriterWithConfigAndLogLevel(socketPath string, dialTimeout, writeTimeout time.Duration, queueSize int, logLevel string) (*UnixSocketWriter, error) {
w := &UnixSocketWriter{
socketPath: socketPath,
dialTimeout: dialTimeout,
@ -248,50 +240,20 @@ func NewUnixSocketWriterWithConfigAndLogLevel(socketPath string, dialTimeout, wr
queueClose: make(chan struct{}),
queueDone: make(chan struct{}),
pendingWrites: make([][]byte, 0),
logLevel: strings.ToLower(logLevel),
logger: log.New(os.Stderr, "[UnixSocket] ", log.LstdFlags|log.Lmicroseconds),
}
// Start the queue processor
go w.processQueue()
// Try initial connection (socket may not exist yet - that's okay)
// Try initial connection silently (socket may not exist yet - that's okay)
conn, err := net.DialTimeout("unix", socketPath, w.dialTimeout)
if err == nil {
w.conn = conn
w.log("INFO", "connected to %s", socketPath)
} else {
w.log("WARNING", "initial connection to %s failed: %v (will retry on write)", socketPath, err)
}
return w, nil
}
// log emits a log message if the level is enabled
func (w *UnixSocketWriter) log(level, format string, args ...interface{}) {
if !w.isLogLevelEnabled(level) {
return
}
w.logger.Printf("[%s] UnixSocketWriter: "+format, append([]interface{}{level}, args...)...)
}
// isLogLevelEnabled checks if a log level should be emitted
func (w *UnixSocketWriter) isLogLevelEnabled(level string) bool {
level = strings.ToLower(level)
switch w.logLevel {
case "debug":
return true
case "info":
return level != "debug"
case "warn", "warning":
return level != "debug" && level != "info"
case "error":
return level == "error"
default:
return false
}
}
// processQueue handles queued writes with reconnection logic
func (w *UnixSocketWriter) processQueue() {
defer close(w.queueDone)
@ -317,12 +279,6 @@ func (w *UnixSocketWriter) processQueue() {
}
w.pendingMu.Unlock()
if consecutiveFailures >= w.maxReconnects {
w.log("ERROR", "max reconnection attempts reached for %s (failures: %d)", w.socketPath, consecutiveFailures)
} else if consecutiveFailures > 1 {
w.log("WARNING", "write failed to %s: %v (attempt %d/%d)", w.socketPath, err, consecutiveFailures, w.maxReconnects)
}
// Exponential backoff
if consecutiveFailures > w.maxReconnects {
time.Sleep(backoff)
@ -332,7 +288,6 @@ func (w *UnixSocketWriter) processQueue() {
}
}
} else {
w.log("DEBUG", "wrote %d bytes to %s", len(data), w.socketPath)
consecutiveFailures = 0
backoff = w.reconnectBackoff
// Try to flush pending data
@ -380,12 +335,10 @@ func (w *UnixSocketWriter) writeWithReconnect(data []byte) error {
return fmt.Errorf("failed to connect to socket %s: %w", w.socketPath, err)
}
w.conn = conn
w.log("INFO", "connected to %s", w.socketPath)
return nil
}
if err := ensureConn(); err != nil {
w.log("ERROR", "connection failed to %s: %v", w.socketPath, err)
return err
}
@ -398,7 +351,6 @@ func (w *UnixSocketWriter) writeWithReconnect(data []byte) error {
}
// Connection failed, try to reconnect
w.log("WARNING", "write failed, attempting reconnect to %s", w.socketPath)
_ = w.conn.Close()
w.conn = nil
@ -457,7 +409,6 @@ func (w *UnixSocketWriter) Close() error {
w.isClosed = true
if w.conn != nil {
w.log("INFO", "closing connection to %s", w.socketPath)
w.conn.Close()
w.conn = nil
}
@ -578,12 +529,7 @@ func (b *BuilderImpl) NewFromConfig(cfg api.AppConfig) (api.Writer, error) {
if socketPath == "" {
return nil, fmt.Errorf("unix_socket output requires 'socket_path' parameter")
}
// Get log level (default: error)
logLevel := outputCfg.Params["log_level"]
if logLevel == "" {
logLevel = "error"
}
writer, err = NewUnixSocketWriterWithConfigAndLogLevel(socketPath, DefaultDialTimeout, DefaultWriteTimeout, queueSize, logLevel)
writer, err = NewUnixSocketWriterWithConfig(socketPath, DefaultDialTimeout, DefaultWriteTimeout, queueSize)
if err != nil {
return nil, err
}