Documentation ¶
Overview ¶
Package syslog5424 implements syslog RFC 5424 with a complete compatibility with the standard log.Logger API.
the simpliest way to use syslog5424 is :
package main import ( "github.com/nathanaelle/syslog5424" ) func main() { // create a connection the standard error sl_conn, _, _ := syslog5424.Dial( "stdio", "stderr:" ) // create a syslog wrapper around the connection // the program is named "test-app" and you log to LogDAEMON facility at least at LogWARNING level syslog,_ := syslog5424.New( sl_conn, syslog5424.LogDAEMON|syslog5424.LogWARNING, "test-app" ) // create a channel for the level LogERR err_channel := syslog.Channel( syslog5424.LogERR ) // get a the *log.Logger for this channel with a prefix "ERR : " logger_err := err_channel.Logger( "ERR : " ) // log a message through the log.Logger logger_err.Print( "doing some stuff" ) }
Index ¶
- Constants
- Variables
- func GenericSD(i sdata.SDIDLight) sdata.StructuredData
- type Addr
- type Channel
- type Connector
- type ConnectorFunc
- type DataReader
- type Dialer
- type InvalidConnector
- type Listener
- type Message
- func (msg Message) AppName(appname string) Message
- func (msg Message) Delta(bootTs time.Time, strSec string, strNsec string) Message
- func (msg Message) Epoch(strSec string, strNsec string) Message
- func (msg Message) Host(host string) Message
- func (msg Message) LocalHost() Message
- func (msg Message) Marshal5424() ([]byte, error)
- func (msg Message) Msg(message string) Message
- func (msg Message) MsgID(msgid string) Message
- func (msg Message) Now() Message
- func (msg Message) Priority(prio Priority) Message
- func (msg Message) ProcID(procid string) Message
- func (msg Message) String() (s string)
- func (msg Message) StructuredData(data ...sdata.StructuredData) Message
- func (msg Message) Time(ts time.Time) Message
- func (msg Message) Timestamp(stamp string) Message
- type MessageImmutable
- func (msg MessageImmutable) AppName() (app string)
- func (msg MessageImmutable) Hostname() (host string)
- func (msg MessageImmutable) MsgID() (msgid string)
- func (msg MessageImmutable) Priority() (prio Priority)
- func (msg MessageImmutable) ProcID() (procid string)
- func (msg MessageImmutable) String() string
- func (msg MessageImmutable) StructuredData() (lsd sdata.List)
- func (msg MessageImmutable) Text() (text string)
- func (msg MessageImmutable) TimeStamp() (ts time.Time)
- func (msg MessageImmutable) Writable() Message
- func (msg MessageImmutable) WriteTo(w io.Writer) (n int64, err error)
- type ParseError
- type Priority
- type Receiver
- type Sender
- type Syslog
- type Transport
- type WriteCloser
Examples ¶
Constants ¶
const RFC5424TimeStamp string = "2006-01-02T15:04:05.999999Z07:00"
RFC5424TimeStamp is the format of a RFC 5424 TimeStamp
Variables ¶
var ( ErrBufferClose = errors.New("error in syslog5424 at buffer.Close()") ErrNoConnecion = errors.New("No Connection established") ErrPos0 = errors.New("Pos 0 Found") ErrPosNotFound = errors.New("Pos Not Found") ErrImpossible = errors.New("NO ONE EXPECT THE RETURN OF SPANISH INQUISITION") ErrInvalidNetwork = errors.New("Invalid Network") ErrInvalidAddress = errors.New("Invalid Address") ErrEmptyNetworkAddress = errors.New("Empty Network or Address") ErrTransportIncomplete = errors.New("Transport : Incomplete Message") ErrTransportNoHeader = errors.New("T_RFC5425 Split: no header len") ErrTransportInvHeader = errors.New("T_RFC5425 Split: invalid header len") )
var ( // Now permit to change the local default alias function for time.Now(). only usefull in case of test or debug Now = time.Now )
Functions ¶
Types ¶
type Channel ¶
type Channel interface { io.Writer IsDevNull() bool AppName(string) Channel Msgid(string) Channel Logger(string) *log.Logger Log(string, ...sdata.StructuredData) }
Channel interface describe the common API of any logging channel. a logging channel is a context set for any log message or structured data
type Connector ¶
type Connector interface {
Connect() (WriteCloser, error)
}
Connector describe the generic way to create a WriteCloser
func LocalConnector ¶
LocalConnector is a dialer that forward to a local RFC5424 syslog receiver
func StdioConnector ¶
StdioConnector returns a Connector that only forward to stderr: or stdout:
func TCPConnector ¶
TCPConnector is a dialer that forward to a local RFC5424 syslog receiver
type ConnectorFunc ¶
type ConnectorFunc func() (WriteCloser, error)
ConnectorFunc is an helper that convert an function to a Connector
func (ConnectorFunc) Connect ¶
func (f ConnectorFunc) Connect() (WriteCloser, error)
Connect implements Connector.Connect
type DataReader ¶
type DataReader interface { io.Reader io.Closer // RemoteAddr returns the remote network address. RemoteAddr() net.Addr }
DataReader describe an incoming connexion
type Dialer ¶
Dialer contains options for connecting to an address.
func (Dialer) Dial ¶
Dial opens a connection to the syslog daemon network can be "stdio", "unix", "unixgram", "tcp", "tcp4", "tcp6" Transport can be nil. if Transport is nil the "common" transport for the wished network is used.
the returned `<-chan error` is used to collect errors than may occur in goroutine
type InvalidConnector ¶
type InvalidConnector struct {
// contains filtered or unexported fields
}
InvalidConnector is a connector that always return an error
func (InvalidConnector) Connect ¶
func (ic InvalidConnector) Connect() (conn WriteCloser, err error)
Connect is part of implementation of (Connector interface)[#Connector]
type Listener ¶
type Listener interface { // Accept waits for and returns the next DataReader to the listener. Accept() (DataReader, error) // Close closes the listener. Close() error }
Listener decribe a generic way to Listen for an incoming connexion
Example (Basic) ¶
package main import ( "fmt" "log" "os" "sync" "time" ) const TestSOCKET string = "./test.socket" func main() { defer os.Remove(TestSOCKET) wg := new(sync.WaitGroup) mutex := new(sync.Mutex) mutex.Lock() Now = func() time.Time { t, _ := time.ParseInLocation("2006-01-02T15:04:00Z", "2014-12-20T14:04:00Z", time.UTC) return t } wg.Add(2) go server(wg, mutex) go client(wg, mutex) wg.Wait() mutex.Unlock() } func client(wg *sync.WaitGroup, mutex *sync.Mutex) { defer wg.Done() // waiting the creation of the socket mutex.Lock() slConn, chanErr, err := Dial("unix", TestSOCKET) if err != nil { log.Fatal(err) } go func() { if err := <-chanErr; err != nil { log.Fatal(err) } }() syslog, err := New(slConn, LogDAEMON|LogWARNING, "client-app") if err != nil { log.Fatal(err) } syslog.TestMode() loggerErrConf := syslog.Channel(LogERR).Logger("ERR : ") loggerErrConf.Print("doing some stuff") loggerErrConf.Print("doing anoter stuff") loggerErrConf.Print("doing a last stuff") slConn.End() } func server(wg *sync.WaitGroup, mutex *sync.Mutex) { defer wg.Done() listener, err := UnixListener(TestSOCKET) if err != nil { log.Fatal(err) } collect, chanErr := NewReceiver(listener, 100, TransportZeroEnded) go func() { if err := <-chanErr; err != nil { log.Fatalf("client chanErr %q", err) } }() // socket is created mutex.Unlock() count := 3 for count > 0 { count-- msg, err, _ := collect.Receive() if err != nil { log.Fatal(err) } fmt.Printf("%s\n", msg.String()) } collect.End() }
Output: <27>1 2014-12-20T14:04:00Z localhost client-app 1234 - - ERR : doing some stuff <27>1 2014-12-20T14:04:00Z localhost client-app 1234 - - ERR : doing anoter stuff <27>1 2014-12-20T14:04:00Z localhost client-app 1234 - - ERR : doing a last stuff
Example (Custom) ¶
package main import ( "fmt" "log" "os" "sync" "time" ) const TestSOCKET2 string = "./test-custom.socket" func main() { defer os.Remove(TestSOCKET2) wg := new(sync.WaitGroup) mutex := new(sync.Mutex) mutex.Lock() Now = func() time.Time { t, _ := time.ParseInLocation("2006-01-02T15:04:00Z", "2014-12-20T14:04:00Z", time.UTC) return t } wg.Add(2) go serverCustom(wg, mutex) go clientCustom(wg, mutex) wg.Wait() mutex.Unlock() } func clientCustom(wg *sync.WaitGroup, mutex *sync.Mutex) { defer wg.Done() // waiting the creation of the socket mutex.Lock() slConn, chanErr, err := (Dialer{ FlushDelay: 100 * time.Millisecond, }).Dial("unix", TestSOCKET2, TransportRFC5425) if err != nil { log.Fatal(err) } go func() { if err := <-chanErr; err != nil { log.Fatal(err) } }() syslog, err := New(slConn, LogDAEMON|LogWARNING, "custom-app") if err != nil { log.Fatal(err) } syslog.TestMode() loggerErrConf := syslog.Channel(LogERR).Logger("ERR : ") loggerErrConf.Print("doing some stuff") loggerErrConf.Print("doing anoter stuff") loggerErrConf.Print("doing a last stuff") slConn.End() } func serverCustom(wg *sync.WaitGroup, mutex *sync.Mutex) { defer wg.Done() listener, err := UnixListener(TestSOCKET2) if err != nil { log.Fatalf("server Collect %q", err) } collect, chanErr := NewReceiver(listener, 100, TransportRFC5425) go func() { if err := <-chanErr; err != nil { log.Fatalf("client chanErr %q", err) } }() // socket is created mutex.Unlock() count := 3 for count > 0 { count-- msg, err, _ := collect.Receive() if err != nil { log.Fatal(err) } fmt.Printf("%s\n", msg.String()) } collect.End() }
Output: <27>1 2014-12-20T14:04:00Z localhost custom-app 1234 - - ERR : doing some stuff <27>1 2014-12-20T14:04:00Z localhost custom-app 1234 - - ERR : doing anoter stuff <27>1 2014-12-20T14:04:00Z localhost custom-app 1234 - - ERR : doing a last stuff
func GuessListener ¶
GuessListener guess the correct Listener when network is not known at compilation time
func TCPListener ¶
TCPListener create a TCP Listener
Example ¶
package main import ( "fmt" "log" "sync" "time" ) const testTCPSocket string = "127.0.0.1:51400" func main() { wg := new(sync.WaitGroup) mutex := new(sync.Mutex) mutex.Lock() Now = func() time.Time { t, _ := time.ParseInLocation("2006-01-02T15:04:00Z", "2014-12-20T14:04:00Z", time.UTC) return t } wg.Add(2) go exTCPServer(wg, mutex) go exTCPClient(wg, mutex) wg.Wait() mutex.Unlock() } func exTCPClient(wg *sync.WaitGroup, mutex *sync.Mutex) { defer wg.Done() // waiting the creation of the socket mutex.Lock() slConn, chanErr, err := Dial("tcp", testTCPSocket) if err != nil { log.Fatal(err) } go func() { if err := <-chanErr; err != nil { log.Fatal(err) } }() syslog, err := New(slConn, LogDAEMON|LogWARNING, "client-app") if err != nil { log.Fatal(err) } syslog.TestMode() loggerErrConf := syslog.Channel(LogERR).Logger("ERR : ") loggerErrConf.Print("doing some stuff") loggerErrConf.Print("doing anoter stuff") loggerErrConf.Print("doing a last stuff") slConn.End() } func exTCPServer(wg *sync.WaitGroup, mutex *sync.Mutex) { defer wg.Done() listener, err := TCPListener("tcp", testTCPSocket) if err != nil { log.Fatal(err) } collect, chanErr := NewReceiver(listener, 100, TransportLFEnded) go func() { if err := <-chanErr; err != nil { log.Fatalf("client chanErr %q", err) } }() // socket is created mutex.Unlock() count := 3 for count > 0 { count-- msg, err, _ := collect.Receive() if err != nil { log.Fatal(err) } fmt.Printf("%s\n", msg.String()) } collect.End() }
Output: <27>1 2014-12-20T14:04:00Z localhost client-app 1234 - - ERR : doing some stuff <27>1 2014-12-20T14:04:00Z localhost client-app 1234 - - ERR : doing anoter stuff <27>1 2014-12-20T14:04:00Z localhost client-app 1234 - - ERR : doing a last stuff
func UnixListener ¶
UnixListener create a UNIX Listener careful : a previous unused socket may be removed and recreated
func UnixgramListener ¶
UnixgramListener create a Listener for UNIX datagram
type Message ¶
type Message struct {
// contains filtered or unexported fields
}
Message describe a mutable Syslog 5424 Message
func CreateMessage ¶
CreateMessage create a Message with the timestamp, hostname, appname, the priority and the message preset
func CreateWholeMessage ¶
CreateWholeMessage create a whole Message
func (Message) Marshal5424 ¶
Marshal5424 encode a message to the syslog 5424 format
func (Message) StructuredData ¶
func (msg Message) StructuredData(data ...sdata.StructuredData) Message
StructuredData set the message part of a Message
type MessageImmutable ¶
type MessageImmutable struct {
// contains filtered or unexported fields
}
MessageImmutable is an incoming message from a remote agent. So it's a read only structure.
func Parse ¶
func Parse(data []byte, transport Transport, atEOF bool) (returnMsg MessageImmutable, rest []byte, mainErr error)
Parse allow to parse a []byte and decode one ImmutableMessage
func (MessageImmutable) AppName ¶
func (msg MessageImmutable) AppName() (app string)
AppName return the appname field of a MessageImmutable
func (MessageImmutable) Hostname ¶
func (msg MessageImmutable) Hostname() (host string)
Hostname return the hostname field of a MessageImmutable
func (MessageImmutable) MsgID ¶
func (msg MessageImmutable) MsgID() (msgid string)
MsgID return the msgid field of a MessageImmutable
func (MessageImmutable) Priority ¶
func (msg MessageImmutable) Priority() (prio Priority)
Priority return the priority field of a MessageImmutable
func (MessageImmutable) ProcID ¶
func (msg MessageImmutable) ProcID() (procid string)
ProcID return the procid field of a MessageImmutable
func (MessageImmutable) String ¶
func (msg MessageImmutable) String() string
func (MessageImmutable) StructuredData ¶
func (msg MessageImmutable) StructuredData() (lsd sdata.List)
StructuredData return the Structured Data list of a MessageImmutable
func (MessageImmutable) Text ¶
func (msg MessageImmutable) Text() (text string)
Text return the text field of a MessageImmutable
func (MessageImmutable) TimeStamp ¶
func (msg MessageImmutable) TimeStamp() (ts time.Time)
TimeStamp return the timestamp field of a MessageImmutable
func (MessageImmutable) Writable ¶
func (msg MessageImmutable) Writable() Message
Writable convert a MessageImmutable to Message
type ParseError ¶
ParseError describe an error in parsing
func (ParseError) Error ¶
func (pe ParseError) Error() string
type Priority ¶
type Priority int
Priority is the encoded form of the severity and facility of a Message
Severity.
const ( LogKERN Priority = iota << 3 LogUSER LogMAIL LogDAEMON LogAUTH LogSYSLOG LogLPR LogNEWS LogUUCP LogCRON LogAUTHPRIV LogFTP LogLOCAL0 LogLOCAL1 LogLOCAL2 LogLOCAL3 LogLOCAL4 LogLOCAL5 LogLOCAL6 LogLOCAL7 )
Facility.
func (Priority) Marshal5424 ¶
Marshal5424 encode the priority to Syslog5424 format
func (*Priority) Unmarshal5424 ¶
Unmarshal5424 decode the priority to Syslog5424 format
type Receiver ¶
type Receiver struct {
// contains filtered or unexported fields
}
Receiver describe how message are received and decoded
func NewReceiver ¶
NewReceiver create a new Listener
if Transport is nil then the function returns nil, nil this case may occurs when transport is unknown at compile time
the returned `<-chan error` is used to collect errors than may occur in goroutine
type Sender ¶
type Sender struct {
// contains filtered or unexported fields
}
Sender describe the generic algorithm for sending Message through a connection
func Dial ¶
Dial opens a connection to the syslog daemon network can be "stdio", "unix", "unixgram", "tcp", "tcp4", "tcp6" used Transport is the "common" transport for the network. FlushDelay is preset to 500ms
Example (Stdio) ¶
package main import ( "log" "time" ) func main() { Now = func() time.Time { t, _ := time.ParseInLocation("2006-01-02T15:04:00Z", "2014-12-20T14:04:00Z", time.UTC) return t } slConn, _, err := Dial("stdio", "stdout:") if err != nil { log.Fatal(err) } syslog, err := New(slConn, LogDAEMON|LogWARNING, "test-app") if err != nil { log.Fatal(err) } syslog.TestMode() conflog := syslog.SubSyslog("configuration") // using standard "log" API from golang loggerInfoConf := conflog.Channel(LogINFO).Logger("INFO : ") loggerErrConf := conflog.Channel(LogERR).Logger("ERR : ") // this is not logged because line 25 tell to syslog to log LogWARNING or higher loggerInfoConf.Print("doing some stuff but not logged") loggerErrConf.Print("doing some stuff") // using internal API conflog.Channel(LogERR).Log("another message with structured data", GenericSD(someSD{"some message", 42})) // closing the connection and flushing all remaining logs slConn.End() } type someSD struct { Message string Errno int } func (someSD) GetPEN() uint64 { return uint64(32473) } func (someSD) IsIANA() bool { return false } func (someSD) String() string { return "someSD@32473" }
Output: <27>1 2014-12-20T14:04:00Z localhost test-app/configuration 1234 - - ERR : doing some stuff <27>1 2014-12-20T14:04:00Z localhost test-app/configuration 1234 - [someSD@32473 Message="some message" Errno="42"] another message with structured data
type Syslog ¶
type Syslog struct {
// contains filtered or unexported fields
}
Syslog describes a sysloger
type Transport ¶
type Transport interface { // Set the sub conn where to write the transport-encoded data Encode([]byte) []byte // Decode the prefix in case of transport that use an encoding header PrefixStrip(buffer []byte, atEOF bool) (data, rest []byte, err error) // Decode the suffix in case of transport that use an encoding terminaison SuffixStrip(buffer []byte, atEOF bool) (data, rest []byte, err error) String() string }
Transport describe a generic way to encode and decode syslog 5424 on an connexion
var ( // TransportZeroEnded is commonly used transport with "unix" and "unixgram" TransportZeroEnded Transport = tZeroEnded{} // TransportLFEnded is commonly used transport with "tcp" "tcp4" and "tcp6" TransportLFEnded Transport = tLFEnded{} // TransportRFC5425 is performant transport specified in RFC 5425 TransportRFC5425 Transport = tRFC5425{} )
Source Files ¶
- channel.go
- connector-fd.go
- connector-invalid.go
- connector-local.go
- connector-local_unix.go
- connector-tcp.go
- connector.go
- dialer.go
- doc.go
- errors.go
- helpers.go
- listener-guess.go
- listener-tcp.go
- listener-unix.go
- listener-unixdgram.go
- listener.go
- message-immutable.go
- message.go
- priority.go
- sdata-helper.go
- syslog.go
- transport.go