parsesyslog

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2025 License: MIT Imports: 5 Imported by: 4

README

go-parsesyslog - a Go library to parse syslog messages

Go Reference Go Report Card Build Status buy ma a coffee

Supported formats

BSD syslog format (RFC3164)

go-parsesyslog fully implements the RFC3164 format including timestamp parsing and optional tags.

Please note: the RFC is not providing any message length definition and explicity states that there is "no ending delimiter to this part" for this reason we are using the newline (\n (ASCII: 10)) as delimiter. This will therefore truncate messages that have a newline in it. Additionally the RFC does specify a timestamp format that has not provide any information about the year. For this reason, we infer the year from current local time. If the parsed time is more than ~31 days in the future, assume it was from the previous year, otherwise we assume it is from the current year.

Available fields in the LogMsg:

  • AppName: this represents the TAG part of TAG[pid]: format (if given in the message) that is often used for the name off the application or process logging
  • ProcID: this represents the pid part of TAG[pid]: format (if given in the message) that is often used for the process ID
  • HostName: this represents the hostname part of the RFC3164 message
  • Priority: The Priority part of the message
  • Facility: The facility calculated from the Priority part of the message
  • Severity: The severity calculated from the Priority part of the message
  • Timestamp: The parsed timestamp of the RFC3164 message as time.Time representation
  • Message: The message part of the log message as bytes.Buffer
  • MsgLength: The length of the Message (not including any header part)
  • Type: This will be always set to RFC3164
IETF-syslog

go-parsesyslog is also fully (RFC5424) compliant. All available fields are parsed and represented accordingly in the LogMsg fields. Although the RFC5424 mandates a maximum length of 2048 bytes for a log message, go-parsesyslog does only obey the message length given in the header of the message.

Available fields in the LogMsg:

  • Priority: this represents the PRI field of the header
  • ProtoVersion: this represents the VERSION field of the header
  • Timestamp: this represents the TIMESTAMP field of the header
  • Hostname: this represents the HOSTNAME field of the header
  • AppName: this represents the APP-NAME field of the header
  • ProcID: this represents the PROCID field of the header
  • MsgID: this represents the MSGID field of the header
  • StructuredData this represents fully parsed structured data as described in the STRUCTURED-DATA section of the RFC
  • HasBOM: is set to true if the log message starts with a BOM
  • Facility: The facility calculated from the Priority part of the message
  • Severity: The severity calculated from the Priority part of the message
  • Message: The message part of the log message as bytes.Buffer
  • MsgLength: The length of the Message (not including any header part)
  • Type: This will be always set to RFC5424

Usage

go-parsesyslog implements an interface for various syslog formats, which makes it easy to extend your own log parser. As long as the Parser interface is satisfied, go-parsesyslog will be able to work.

The interface looks as following:

type Parser interface {
  ParseReader(io.Reader) (LogMsg, error)
  ParseString(string) (LogMsg, error)
}
Parsing logs

As you can see, the ParseReader() method expects an io.Reader interface as argument. This allows you to easily parse your logs from any kind of source (STDIN, a file, a network socket...). ParseString() instead takes a string and parses it accordingly.

Parsing RFC3164

This example code show how to parse a RFC3164 conformant message:

package main

import (
	"fmt"
	"github.com/wneessen/go-parsesyslog"
	"github.com/wneessen/go-parsesyslog/rfc3164"
	"os"
)

func main() {
	msg := "<34>Oct 11 22:14:15 mymachine su: 'su root' failed for lonvick on /dev/pts/8\n"
	p, err := parsesyslog.New(rfc3164.Type)
	if err != nil {
		fmt.Printf("failed to create RFC3164 parser: %s", err)
		os.Exit(1)
	}
	lm, err := p.ParseString(msg)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Log message: %+v", lm)
}
Parsing RFC5424

This example code show how to parse a RFC5424 conformant message:

package main

import (
	"fmt"
	"github.com/wneessen/go-parsesyslog"
	"github.com/wneessen/go-parsesyslog/rfc5424"
	"os"
)

func main() {
	msg := `197 <165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][foo@1234 foo="bar" blubb="bluh"] \xEF\xBB\xBFAn application event log entry..."`
	p, err := parsesyslog.New(rfc5424.Type)
	if err != nil {
		fmt.Printf("failed to create RFC3164 parser: %s", err)
		os.Exit(1)
	}
	lm, err := p.ParseString(msg)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Log message: %+v", lm)
}

An example implementation can be found in cmd/stdin-parser

$ $ echo -ne '197 <165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][foo@1234 foo="bar" blubb="bluh"] \xEF\xBB\xBFAn application event log entry...' | go run github.com/wneessen/go-parsesyslog/cmd/stdin-parser

This command will output:

Log message details:
+ Log format:         RFC5424
+ Header:
  - Priority:         165 (Facility: LOCAL4 / Severity: NOTICE)
  - Protocol Version: 1
  - Hostname:         mymachine.example.com
  - AppName:          evntslog
  - ProcID:
  - MsgID:            ID47
  - Timestamp (UTC):  2003-10-11 22:14:15.003 +0000 UTC
+ Structured Data:
  - ID:               exampleSDID@32473
    + Param 0:
      - Name:         iut
      - Value:        3
    + Param 1:
      - Name:         eventSource
      - Value:        Application
    + Param 2:
      - Name:         eventID
      - Value:        1011
  - ID:               foo@1234
    + Param 0:
      - Name:         foo
      - Value:        bar
    + Param 1:
      - Name:         blubb
      - Value:        bluh
+ Message has BOM:    true
+ Message Length:     25
+ Message:            An application event l

Log parsed in 18.745µs

Benchmark

As the main intention of this library was for me to use it in a network service that parses incoming syslog messages, quite some work has been invested to make go-parsesyslog fast and memory efficient. We are trying to allocate as less as possible and make use of buffered I/O where possible.

$ go test -run=X -bench=.\*ParseReader -benchtime=15s ./...
goos: linux
goarch: amd64
pkg: github.com/wneessen/go-parsesyslog
cpu: AMD Ryzen 9 3950X 16-Core Processor
BenchmarkRFC3164Msg_ParseReader/ParseReader-32     36575746       490 ns/op     64 B/op    1 allocs/op
BenchmarkRFC5424Msg_ParseReader/ParseReader-32     12615361      1433 ns/op    432 B/op    5 allocs/op
PASS

Documentation

Overview

Package parsesyslog implements a syslog message parser for different RFC log formats

Index

Constants

View Source
const SeverityMask = 0x07

SeverityMask is the bitmask representing the Severity in the Priority

Variables

View Source
var (
	// ErrInvalidPrio should be used if the PRI part of the message is not following the log format
	ErrInvalidPrio = errors.New("PRI header not a valid priority string")
	// ErrInvalidProtoVersion should be used if the protocol version part of the header is not following the log format
	ErrInvalidProtoVersion = errors.New("protocol version string invalid")
	// ErrInvalidTimestamp should be used if it was not possible to parse the timestamp of the log message
	ErrInvalidTimestamp = errors.New("timestamp does not conform the logging format")
	// ErrParserTypeUnknown is returned if a Parser is requested via New() which is not registered
	ErrParserTypeUnknown = errors.New("unknown parser type")
	// ErrPrematureEOF should be used in case a log message ends before the provided length
	ErrPrematureEOF = errors.New("log message is shorter than the expected length")
	// ErrWrongFormat should be used if a log messages does not comply with the logging format definitions
	ErrWrongFormat = errors.New("log message does not conform the logging format")
	// ErrWrongSDFormat should be used in case the structured data is not parsable
	ErrWrongSDFormat = errors.New("structured data does not conform the format")
	// ErrInvalidLength should be used if the length of the log message does not match the provided length
	ErrInvalidLength = errors.New("log message does not match the provided length value")
	// ErrInvalidNumber should be used if the number is not valid
	ErrInvalidNumber = errors.New("invalid number")
)

Functions

func FacilityStringFromPrio

func FacilityStringFromPrio(p Priority) string

FacilityStringFromPrio returns a string representation of the Facility of a given Priority

func ParseUintBytes added in v0.3.0

func ParseUintBytes(b []byte) (int, error)

ParseUintBytes parses a byte slice containing only numeric characters into an integer, returning an error for invalid input.

func Register

func Register(parserType ParserType, newFunc newFunc)

Register adds a new parser factory function for a specified ParserType if it is not already registered.

func SeverityStringFromPrio

func SeverityStringFromPrio(p Priority) string

SeverityStringFromPrio returns a string representation of the Severity of a given Priority

Types

type Facility

type Facility uint8

Facility represents the facility part of the Syslog PRI header

func FacilityFromPrio

func FacilityFromPrio(p Priority) Facility

FacilityFromPrio extracts the Facility from a given Priority

func (Facility) String added in v0.2.2

func (f Facility) String() string

String returns the string representation of the Facility based on its integer value. It satisfies the fmt.Stringer interface.

type LogMsg

type LogMsg struct {
	// Wide and/or bulky types first
	Message        bytes.Buffer
	Timestamp      time.Time
	App            []byte
	Host           []byte
	MsgID          []byte
	PID            []byte
	StructuredData []StructuredDataElement

	// Medium size types
	Type LogMsgType

	MsgLength    int32
	Facility     Facility
	Priority     Priority
	ProtoVersion ProtoVersion
	Severity     Severity
	HasBOM       bool
	// contains filtered or unexported fields
}

LogMsg represents a Syslog message as defined by the Parser, with fields for structured and unstructured data

func (*LogMsg) AppName

func (l *LogMsg) AppName() string

AppName returns the application name extracted from the LogMsg. It converts the App field from []byte to string.

func (*LogMsg) Hostname

func (l *LogMsg) Hostname() string

Hostname returns the hostname extracted from the LogMsg. It converts the Host field from []byte to string.

func (*LogMsg) ProcID

func (l *LogMsg) ProcID() string

ProcID returns the process ID extracted from the LogMsg. It converts the PID field from []byte to string.

type LogMsgType

type LogMsgType string

LogMsgType represents the type of a Syslog message, typically defined by RFC specifications such as RFC3164 or RFC5424.

type Parser

type Parser interface {
	ParseReader(io.Reader) (LogMsg, error)
	ParseString(s string) (LogMsg, error)
}

Parser defines an interface for parsing Syslog messages from various input sources into LogMsg objects.

func New

func New(t ParserType) (Parser, error)

New creates a new Parser instance based on the provided ParserType. Returns an error if the requested ParserType is not registered. The ParserType must correspond to a key in the internal types registry.

type ParserType

type ParserType string

ParserType is an alias type for a string. It represents a type of parser used to process and interpret log messages.

type Priority

type Priority uint8

Priority represents the Syslog PRI header

const (
	Emergency Priority = iota // System is unusable
	Alert                     // Action must be taken immediately
	Crit                      // Critical conditions
	Error                     // Error conditions
	Warning                   // Warning conditions
	Notice                    // Normal but significant conditions
	Info                      // Informational messages
	Debug                     // Debug-level messages
)

Severities

const (
	Kern        Priority = iota << 3 // Kernel messages
	User                             // User-level messages
	Mail                             // Mail system
	Daemon                           // System daemons
	Auth                             // Security/authentication messages
	Syslog                           // Messages generated internally by the syslog daemon
	LPR                              // Printer subsystem
	News                             // Network News subsystem
	UUCP                             // UUCP subsystem
	Cron                             // Cron subsystem
	AuthPriv                         // Security/authentication messages
	FTP                              // FTP daemon
	NTP                              // NTP subsystem
	Security                         // Log audit
	Console                          // Log alert
	SolarisCron                      // Scheduling daemon
	Local0                           // Locally used facilities
	Local1                           // Locally used facilities
	Local2                           // Locally used facilities
	Local3                           // Locally used facilities
	Local4                           // Locally used facilities
	Local5                           // Locally used facilities
	Local6                           // Locally used facilities
	Local7                           // Locally used facilities
)

Facilities

type ProtoVersion

type ProtoVersion uint8

ProtoVersion represents the version of the Syslog protocol as defined in RFC5424.

type Severity

type Severity uint8

Severity represents the serverity part of the Syslog PRI header

func SeverityFromPrio

func SeverityFromPrio(p Priority) Severity

SeverityFromPrio extracts the Facility from a given Priority

func (Severity) String added in v0.2.2

func (s Severity) String() string

String returns the string representation of the Severity enumeration. It satisfies the fmt.Stringer interface.

type StructuredDataElement

type StructuredDataElement struct {
	ID    []byte
	Param []StructuredDataParam
}

StructuredDataElement represents a structured data element in an RFC5424 Syslog message. See: https://datatracker.ietf.org/doc/html/rfc5424#section-6.3.1

func (*StructuredDataElement) IDString added in v0.3.0

func (s *StructuredDataElement) IDString() string

IDString returns the ID of the StructuredDataElement as a string.

type StructuredDataParam

type StructuredDataParam struct {
	Key []byte
	Val []byte
}

StructuredDataParam represents a key-value pair within a Structured Data element of an RFC5424 Syslog message. See: https://datatracker.ietf.org/doc/html/rfc5424#section-6.3.3

func (*StructuredDataParam) Name

func (s *StructuredDataParam) Name() string

Name returns the key of the StructuredDataParam as a string.

func (*StructuredDataParam) Value

func (s *StructuredDataParam) Value() string

Value returns the value of the StructuredDataParam as a string.

Directories

Path Synopsis
cmd
stdin-parser command
Package rfc3164 implements a go-parsesyslog parser for the syslog format as described in RFC3164
Package rfc3164 implements a go-parsesyslog parser for the syslog format as described in RFC3164
Package rfc5424 implements a go-parsesyslog parser for the syslog format as described in RFC5424
Package rfc5424 implements a go-parsesyslog parser for the syslog format as described in RFC5424

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL