Documentation
¶
Overview ¶
Package hooksyslog provides a logrus hook for writing log entries to syslog.
Overview ¶
The hooksyslog package implements a logrus hook that sends log messages to system syslog. It supports both Unix/Linux syslog (via log/syslog) and Windows Event Log (via golang.org/x/sys/windows/svc/eventlog). The hook provides asynchronous, buffered logging with automatic reconnection and graceful shutdown.
Design Philosophy ¶
- Cross-platform: Transparent support for Unix/Linux syslog and Windows Event Log
- Asynchronous: Non-blocking writes using buffered channels (capacity: 250)
- Flexible: Configurable levels, formatters, and syslog facilities
- Robust: Automatic reconnection on connection failures
- Standard: Full compliance with RFC 5424 syslog severity levels
Architecture ¶
The package consists of several key components:
┌─────────────────────────────────────────────┐
│ HookSyslog Interface │
│ (logrus.Hook + Done + WriteSev) │
└──────────────┬──────────────────────────────┘
│
┌─────────▼─────────┐
│ hks struct │
│ - channels │
│ - options │
│ - running state │
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ Run() goroutine │
│ - reads channel │
│ - writes syslog │
│ - reconnects │
└─────────┬─────────┘
│
┌───────┴───────┐
│ │
┌──────▼──────┐ ┌─────▼──────┐
│ _Syslog │ │ _WinLog │
│ (Unix) │ │ (Windows) │
└─────────────┘ └────────────┘
Platform-Specific Implementation ¶
Unix/Linux (sys_syslog.go):
- Uses log/syslog package
- Supports network protocols: tcp, udp, unixgram
- Full RFC 5424 severity and facility support
- Build tags: linux || darwin
Windows (sys_winlog.go):
- Uses golang.org/x/sys/windows/svc/eventlog
- Maps severity to Windows event types (Error, Warning, Info)
- Automatic Windows Event Source registration
- Build tags: windows
Key Features ¶
Asynchronous Buffered Writing:
- Buffered channel capacity: 250 entries
- Non-blocking Fire() method (unless buffer full)
- Background goroutine handles actual syslog writes
- Graceful shutdown with Done() channel
Automatic Reconnection:
- Retries connection on startup (1-second intervals)
- Continues logging even if syslog temporarily unavailable
- Connection errors printed to stdout (not propagated to logrus)
Level Mapping:
- logrus.PanicLevel → SyslogSeverityAlert
- logrus.FatalLevel → SyslogSeverityCrit
- logrus.ErrorLevel → SyslogSeverityErr
- logrus.WarnLevel → SyslogSeverityWarning
- logrus.InfoLevel → SyslogSeverityInfo
- logrus.DebugLevel → SyslogSeverityDebug
Field Filtering:
- DisableStack: Remove "stack" field
- DisableTimestamp: Remove "time" field
- EnableTrace: Include "caller", "file", "line" fields
Access Log Mode:
- EnableAccessLog: true → writes entry.Message, ignores fields
- EnableAccessLog: false → writes formatted fields, ignores Message
Advantages ¶
- Non-blocking: Logrus calls don't wait for syslog I/O
- Reliable: Buffering prevents log loss during temporary unavailability
- Flexible: Works with any logrus.Formatter (JSON, Text, custom)
- Cross-platform: Single API for Unix and Windows
- Standard: RFC 5424 compliant severity and facility
Disadvantages ¶
- Memory overhead: Buffered channel holds up to 250 entries (~250KB typical)
- Latency: Async writes introduce small delay before syslog write
- Errors silent: Syslog write errors printed to stdout, not returned to caller
- Requires Run(): Must call Run(ctx) in goroutine, not automatic
- No batching: Each log entry results in separate syslog write
Limitations ¶
- Buffer overflow: If buffer fills (>250 entries), Fire() blocks
- Platform-specific: Windows has limited severity mapping (3 types)
- Network only: Windows remote logging requires network protocol
- No TLS: Unix syslog over network doesn't support TLS
- Tag immutable: Syslog tag set at creation, can't change per-entry
Typical Use Cases ¶
- System service logging to local syslog
- Application logging to remote syslog server
- Windows service logging to Event Log
- Structured logging with JSON formatter
- HTTP access logs (EnableAccessLog mode)
- Multi-destination logging (syslog + file + console)
Performance Considerations ¶
- Channel capacity: 250 entries is default, suitable for most use cases
- Write throughput: Limited by syslog server/daemon, not this package
- Memory usage: ~1KB per buffered entry (depends on entry size)
- Goroutine overhead: Single goroutine per hook instance
- Reconnection: 1-second retry interval on connection failures
Example Usage ¶
See the example_test.go file for complete examples, including:
- Basic setup with local syslog
- Remote syslog via TCP/UDP
- Windows Event Log
- Custom formatter with JSON
- Access log mode
- Graceful shutdown pattern
Example (AccessLog) ¶
Example_accessLog demonstrates using access log mode for HTTP request logging. In this mode, behavior is reversed: the message IS written, fields are IGNORED.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "http-access",
EnableAccessLog: true, // Message-only mode
LogLevel: []string{"info"},
}
hook, err := logsys.New(opts, nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer hook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// IMPORTANT: In AccessLog mode, behavior is REVERSED!
// The message "GET /api/users - 200 OK - 45ms" IS output.
// The fields (method, path, status) are IGNORED.
logger.WithFields(logrus.Fields{
"method": "GET",
"path": "/api/users",
"status": 200,
}).Info("GET /api/users - 200 OK - 45ms")
time.Sleep(100 * time.Millisecond)
fmt.Println("Access log sent to syslog")
}
Output: Access log sent to syslog
Example (Basic) ¶
Example_basic demonstrates the simplest use case: creating a hook that writes to local syslog. Note: This example uses UDP which doesn't require an actual syslog daemon to be running.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Configure the hook with minimal settings
// In this example, we use UDP protocol which doesn't fail if no server is running
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514", // UDP doesn't fail without server
Tag: "myapp",
LogLevel: []string{"info", "warning", "error"},
}
// Create the hook
hook, err := logsys.New(opts, &logrus.TextFormatter{
DisableTimestamp: true, // Disable timestamp for predictable output
})
if err != nil {
fmt.Printf("Error creating hook: %v\n", err)
return
}
defer hook.Close()
// Start async writer goroutine
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
// Wait for hook to be ready
time.Sleep(100 * time.Millisecond)
// Create and configure logger
logger := logrus.New()
logger.SetOutput(os.Stderr) // Use Stderr to separate from syslog output
logger.AddHook(hook)
// IMPORTANT: The message parameter "ignored" is NOT used by the hook in standard mode.
// Only the fields (here "msg") are written to syslog.
// Exception: In AccessLog mode, only the message is used and fields are ignored.
logger.WithField("msg", "Application started successfully").Info("ignored")
// Wait for async write
time.Sleep(100 * time.Millisecond)
fmt.Println("Log sent to syslog")
}
Output: Log sent to syslog
Example (FieldFiltering) ¶
Example_fieldFiltering demonstrates filtering specific fields from output.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Configure to filter out stack and timestamp
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "clean-app",
DisableStack: true, // Remove stack fields
DisableTimestamp: true, // Remove time fields
EnableTrace: false, // Remove caller/file/line fields
LogLevel: []string{"info"},
}
hook, err := logsys.New(opts, &logrus.TextFormatter{
DisableTimestamp: true,
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer hook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// IMPORTANT: message "ignored" is NOT used, only fields
logger.WithFields(logrus.Fields{
"msg": "Filtered log entry",
"stack": "will be filtered out",
"caller": "will be filtered out",
"user": "john",
"action": "login",
}).Info("ignored")
time.Sleep(100 * time.Millisecond)
fmt.Println("Filtered log sent to syslog")
}
Output: Filtered log sent to syslog
Example (GracefulShutdown) ¶
Example_gracefulShutdown demonstrates proper shutdown with the Done channel.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "shutdown-test",
LogLevel: []string{"info"},
}
hook, err := logsys.New(opts, nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
ctx, cancel := context.WithCancel(context.Background())
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// Send some logs
logger.WithField("msg", "Starting shutdown sequence").Info("ignored")
time.Sleep(100 * time.Millisecond)
// Signal shutdown
cancel()
hook.Close()
// Wait for completion
select {
case <-hook.Done():
fmt.Println("Hook shutdown complete")
case <-time.After(2 * time.Second):
fmt.Println("Timeout waiting for shutdown")
}
}
Output: Hook shutdown complete
Example (LevelFiltering) ¶
Example_levelFiltering demonstrates filtering logs by level.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "filtered-app",
LogLevel: []string{"error", "fatal"}, // Only errors and above
}
hook, err := logsys.New(opts, &logrus.TextFormatter{
DisableTimestamp: true,
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer hook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// This will be written (error level)
// Note: message "ignored" is NOT used, only the field "msg"
logger.WithField("msg", "Database connection failed").Error("ignored")
// This won't be written to syslog (wrong level)
logger.WithField("msg", "Request completed").Info("ignored")
time.Sleep(100 * time.Millisecond)
fmt.Println("Filtered logs sent to syslog")
}
Output: Filtered logs sent to syslog
Example (MultipleHooks) ¶
Example_multipleHooks demonstrates using multiple hooks for different destinations.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Hook for errors only
errorOpts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "errors",
LogLevel: []string{"error", "fatal"},
}
errorHook, err := logsys.New(errorOpts, nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer errorHook.Close()
// Hook for all levels
allOpts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "all-logs",
}
allHook, err := logsys.New(allOpts, nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer allHook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go errorHook.Run(ctx)
go allHook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(errorHook)
logger.AddHook(allHook)
// This goes to both hooks
logger.WithField("msg", "Critical error occurred").Error("ignored")
// This goes only to allHook
logger.WithField("msg", "Normal operation").Info("ignored")
time.Sleep(100 * time.Millisecond)
fmt.Println("Logs sent to multiple syslog destinations")
}
Output: Logs sent to multiple syslog destinations
Example (RemoteUdp) ¶
Example_remoteUdp demonstrates sending logs to a remote syslog server via UDP.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514", // Remote syslog server
Tag: "remote-app",
Facility: "LOCAL0", // Use LOCAL0 facility
LogLevel: []string{"info", "error"},
}
hook, err := logsys.New(opts, &logrus.JSONFormatter{})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer hook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// IMPORTANT: Use fields, not message parameter
logger.WithFields(logrus.Fields{
"msg": "Remote logging test",
"service": "api",
"instance": "prod-1",
}).Info("ignored")
time.Sleep(100 * time.Millisecond)
fmt.Println("Log sent to remote syslog via UDP")
}
Output: Log sent to remote syslog via UDP
Example (StructuredLogging) ¶
Example_structuredLogging demonstrates structured logging with JSON formatter.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "structured-app",
LogLevel: []string{"info"},
}
hook, err := logsys.New(opts, &logrus.JSONFormatter{})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer hook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// IMPORTANT: message parameter is NOT used, only fields
logger.WithFields(logrus.Fields{
"user_id": 12345,
"action": "purchase",
"amount": 99.99,
"currency": "USD",
"msg": "Purchase completed",
"request_id": "abc-123-def",
}).Info("ignored")
time.Sleep(100 * time.Millisecond)
fmt.Println("Structured log sent to syslog")
}
Output: Structured log sent to syslog
Example (TraceEnabled) ¶
Example_traceEnabled demonstrates enabling trace information in logs.
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/sirupsen/logrus"
logcfg "github.com/nabbar/golib/logger/config"
logsys "github.com/nabbar/golib/logger/hooksyslog"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
opts := logcfg.OptionsSyslog{
Network: libptc.NetworkUDP.Code(),
Host: "localhost:514",
Tag: "trace-app",
EnableTrace: true, // Include caller/file/line information
LogLevel: []string{"info"},
}
hook, err := logsys.New(opts, &logrus.TextFormatter{
DisableTimestamp: true,
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer hook.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hook.Run(ctx)
time.Sleep(100 * time.Millisecond)
logger := logrus.New()
logger.SetOutput(os.Stderr)
logger.AddHook(hook)
// IMPORTANT: message "ignored" is NOT used, only fields
logger.WithFields(logrus.Fields{
"msg": "Log with trace info",
"caller": "main.processRequest",
"file": "main.go",
"line": 42,
}).Info("ignored")
time.Sleep(100 * time.Millisecond)
fmt.Println("Log with trace sent to syslog")
}
Output: Log with trace sent to syslog
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type HookSyslog ¶
type HookSyslog interface {
logtps.Hook
// Done returns a receive-only channel that is closed when the hook's
// Run goroutine terminates. This allows graceful shutdown coordination.
//
// The channel is closed when:
// - The context passed to Run() is cancelled
// - Close() is called on the hook
//
// Use this to wait for all buffered log entries to be written before
// terminating the application:
//
// cancel() // Stop the Run goroutine
// hook.Close() // Close the channels
// <-hook.Done() // Wait for completion
//
// Note: This channel is safe to read from multiple goroutines, but
// each reader will only receive the close signal once.
Done() <-chan struct{}
// WriteSev writes a log entry to the syslog buffer with the specified
// severity level and data.
//
// This method bypasses the logrus.Entry mechanism and directly writes
// to syslog. It's useful for custom logging scenarios or when you need
// explicit control over the severity level.
//
// Parameters:
// - s: Syslog severity (Emergency, Alert, Critical, Error, Warning, Notice, Info, Debug)
// - p: Log message data (will be sent as-is to syslog)
//
// Returns:
// - n: Number of bytes accepted (len(p)) if successful
// - err: Error if the channel is closed or buffer is full
//
// Behavior:
// - Non-blocking if buffer has space (typical case)
// - Blocks if buffer is full (250 entries) until space is available
// - Returns error if Close() was called (channel closed)
//
// The data is queued to a buffered channel and written asynchronously
// by the Run() goroutine. There's no guarantee of immediate delivery.
//
// Example:
//
// hook, _ := New(opts, nil)
// go hook.Run(ctx)
// _, err := hook.WriteSev(SyslogSeverityInfo, []byte("Custom log entry"))
// if err != nil {
// log.Printf("Failed to write: %v", err)
// }
WriteSev(s SyslogSeverity, p []byte) (n int, err error)
}
HookSyslog is a logrus hook that writes log entries to syslog. It extends the standard logrus.Hook interface with additional methods for lifecycle management and direct syslog writing.
The hook operates asynchronously using a buffered channel (capacity: 250) to prevent blocking the logging goroutine. A background goroutine (started via Run) processes the buffered entries and writes them to syslog.
Platform support:
- Unix/Linux: Uses log/syslog with TCP, UDP, or Unix domain sockets
- Windows: Uses Windows Event Log via golang.org/x/sys/windows/svc/eventlog
Thread safety:
- Fire() is safe for concurrent calls (buffered channel)
- WriteSev() is safe for concurrent calls (buffered channel)
- Done() and Close() should only be called once during shutdown
Example:
opts := logcfg.OptionsSyslog{
Network: "unixgram",
Host: "/dev/log",
Tag: "myapp",
LogLevel: []string{"info", "error"},
}
hook, _ := New(opts, &logrus.JSONFormatter{})
go hook.Run(ctx)
logger.AddHook(hook)
func New ¶
func New(opt logcfg.OptionsSyslog, format logrus.Formatter) (HookSyslog, error)
New creates a new HookSyslog instance with the specified configuration.
This function initializes the hook but does NOT start the background writer goroutine. You must call Run(ctx) in a separate goroutine after creating the hook.
Parameters:
- opt: Configuration options including network, host, tag, facility, and filters
- format: Logrus formatter for log entries (nil for default text format)
Configuration:
- opt.Network: Protocol ("tcp", "udp", "unixgram", "unix", "" for local)
- opt.Host: Syslog server address ("host:port" for TCP/UDP, "/dev/log" for Unix)
- opt.Tag: Syslog tag/application name (appears in syslog output)
- opt.Facility: Syslog facility ("LOCAL0"-"LOCAL7", "USER", "DAEMON", etc.)
- opt.LogLevel: Filter log levels (empty = all levels)
- opt.DisableStack: Remove "stack" field from output
- opt.DisableTimestamp: Remove "time" field from output
- opt.EnableTrace: Include "caller", "file", "line" fields
- opt.EnableAccessLog: Write entry.Message instead of formatted fields
Returns:
- HookSyslog: Configured hook ready to use (call Run to start)
- error: Non-nil if unable to connect to syslog (validates connection)
The function validates the syslog connection by opening and immediately closing it. This ensures early detection of configuration errors.
Example:
opts := logcfg.OptionsSyslog{
Network: "unixgram",
Host: "/dev/log",
Tag: "myapp",
Facility: "USER",
LogLevel: []string{"info", "warning", "error"},
}
hook, err := New(opts, &logrus.JSONFormatter{})
if err != nil {
return fmt.Errorf("failed to create syslog hook: %w", err)
}
go hook.Run(context.Background())
defer hook.Close()
type SyslogFacility ¶
type SyslogFacility uint8
SyslogFacility represents the facility code of a syslog message according to RFC 5424. The facility indicates the type of program or system component generating the message.
Facilities are typically used for filtering and routing syslog messages:
- KERN: Kernel messages
- USER: User-level messages (default for applications)
- MAIL: Mail system
- DAEMON: System daemons
- AUTH: Security/authorization messages
- SYSLOG: Messages generated internally by syslogd
- LPR: Line printer subsystem
- NEWS: Network news subsystem
- UUCP: UUCP subsystem
- CRON: Clock daemon
- AUTHPRIV: Security/authorization messages (private)
- FTP: FTP daemon
- LOCAL0-LOCAL7: Reserved for local use (application-specific)
const ( SyslogFacilityKern SyslogFacility = iota + 1 SyslogFacilityUser SyslogFacilityMail SyslogFacilityDaemon SyslogFacilityAuth SyslogFacilitySyslog SyslogFacilityLpr SyslogFacilityNews SyslogFacilityUucp SyslogFacilityCron SyslogFacilityAuthPriv SyslogFacilityFTP SyslogFacilityLocal0 SyslogFacilityLocal1 SyslogFacilityLocal2 SyslogFacilityLocal3 SyslogFacilityLocal4 SyslogFacilityLocal5 SyslogFacilityLocal6 SyslogFacilityLocal7 )
func MakeFacility ¶
func MakeFacility(facility string) SyslogFacility
MakeFacility converts a facility string to a SyslogFacility value. The conversion is case-insensitive. Returns 0 if the string doesn't match any known facility.
func (SyslogFacility) String ¶
func (s SyslogFacility) String() string
String returns the RFC 5424 name of the facility in uppercase. Returns an empty string for invalid/unknown facility values.
Example:
fac := SyslogFacilityUser fmt.Println(fac.String()) // Outputs: "USER"
type SyslogSeverity ¶
type SyslogSeverity uint8
SyslogSeverity represents the severity level of a syslog message according to RFC 5424. Lower numerical values indicate higher severity.
The severity levels map to logrus levels as follows:
- Emergency (0): System is unusable
- Alert (1): Action must be taken immediately → logrus.PanicLevel
- Critical (2): Critical conditions → logrus.FatalLevel
- Error (3): Error conditions → logrus.ErrorLevel
- Warning (4): Warning conditions → logrus.WarnLevel
- Notice (5): Normal but significant condition
- Informational (6): Informational messages → logrus.InfoLevel
- Debug (7): Debug-level messages → logrus.DebugLevel
const ( SyslogSeverityEmerg SyslogSeverity = iota + 1 SyslogSeverityAlert SyslogSeverityCrit SyslogSeverityErr SyslogSeverityWarning SyslogSeverityNotice SyslogSeverityInfo SyslogSeverityDebug )
func MakeSeverity ¶
func MakeSeverity(severity string) SyslogSeverity
MakeSeverity converts a severity string to a SyslogSeverity value. The conversion is case-insensitive. Returns 0 if the string doesn't match any known severity.
func (SyslogSeverity) String ¶
func (s SyslogSeverity) String() string
String returns the RFC 5424 name of the severity level in uppercase. Returns an empty string for invalid/unknown severity values.
Example:
sev := SyslogSeverityInfo fmt.Println(sev.String()) // Outputs: "INFO"
type Wrapper ¶
type Wrapper interface {
io.WriteCloser
// Panic writes a message with ALERT severity (syslog) or ERROR (Windows).
// This is the highest severity level after EMERGENCY.
Panic(p []byte) (n int, err error)
// Fatal writes a message with CRITICAL severity (syslog) or ERROR (Windows).
// Used for critical conditions that require immediate attention.
Fatal(p []byte) (n int, err error)
// Error writes a message with ERROR severity.
// Used for error conditions.
Error(p []byte) (n int, err error)
// Warning writes a message with WARNING severity.
// Used for warning conditions.
Warning(p []byte) (n int, err error)
// Info writes a message with INFORMATIONAL severity.
// Used for informational messages.
Info(p []byte) (n int, err error)
// Debug writes a message with DEBUG severity (syslog) or INFO (Windows).
// Used for debug-level messages.
Debug(p []byte) (n int, err error)
}
Wrapper is a platform-specific interface for writing to syslog. It abstracts the differences between Unix syslog and Windows Event Log.
Implementations:
- _Syslog: Unix/Linux implementation using log/syslog
- _WinLog: Windows implementation using golang.org/x/sys/windows/svc/eventlog
The interface provides severity-specific methods that map to syslog/event log severity levels. Each method writes the provided byte slice to the underlying logging system.