pax_global_header00006660000000000000000000000064134203672100014510gustar00rootroot0000000000000052 comment=8d1874e3e8d1862b74e0536851e218c4571066a5 go-syslog-1.0.0/000077500000000000000000000000001342036721000134315ustar00rootroot00000000000000go-syslog-1.0.0/.gitignore000066400000000000000000000003741342036721000154250ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe go-syslog-1.0.0/LICENSE000066400000000000000000000020671342036721000144430ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Armon Dadgar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. go-syslog-1.0.0/README.md000066400000000000000000000007261342036721000147150ustar00rootroot00000000000000go-syslog ========= This repository provides a very simple `gsyslog` package. The point of this package is to allow safe importing of syslog without introducing cross-compilation issues. The stdlib `log/syslog` cannot be imported on Windows systems, and without conditional compilation this adds complications. Instead, `gsyslog` provides a very simple wrapper around `log/syslog` but returns a runtime error if attempting to initialize on a non Linux or OSX system. go-syslog-1.0.0/builtin.go000066400000000000000000000126471342036721000154400ustar00rootroot00000000000000// This file is taken from the log/syslog in the standard lib. // However, there is a bug with overwhelming syslog that causes writes // to block indefinitely. This is fixed by adding a write deadline. // // +build !windows,!nacl,!plan9 package gsyslog import ( "errors" "fmt" "log/syslog" "net" "os" "strings" "sync" "time" ) const severityMask = 0x07 const facilityMask = 0xf8 const localDeadline = 20 * time.Millisecond const remoteDeadline = 50 * time.Millisecond // A builtinWriter is a connection to a syslog server. type builtinWriter struct { priority syslog.Priority tag string hostname string network string raddr string mu sync.Mutex // guards conn conn serverConn } // This interface and the separate syslog_unix.go file exist for // Solaris support as implemented by gccgo. On Solaris you can not // simply open a TCP connection to the syslog daemon. The gccgo // sources have a syslog_solaris.go file that implements unixSyslog to // return a type that satisfies this interface and simply calls the C // library syslog function. type serverConn interface { writeString(p syslog.Priority, hostname, tag, s, nl string) error close() error } type netConn struct { local bool conn net.Conn } // New establishes a new connection to the system log daemon. Each // write to the returned writer sends a log message with the given // priority and prefix. func newBuiltin(priority syslog.Priority, tag string) (w *builtinWriter, err error) { return dialBuiltin("", "", priority, tag) } // Dial establishes a connection to a log daemon by connecting to // address raddr on the specified network. Each write to the returned // writer sends a log message with the given facility, severity and // tag. // If network is empty, Dial will connect to the local syslog server. func dialBuiltin(network, raddr string, priority syslog.Priority, tag string) (*builtinWriter, error) { if priority < 0 || priority > syslog.LOG_LOCAL7|syslog.LOG_DEBUG { return nil, errors.New("log/syslog: invalid priority") } if tag == "" { tag = os.Args[0] } hostname, _ := os.Hostname() w := &builtinWriter{ priority: priority, tag: tag, hostname: hostname, network: network, raddr: raddr, } w.mu.Lock() defer w.mu.Unlock() err := w.connect() if err != nil { return nil, err } return w, err } // connect makes a connection to the syslog server. // It must be called with w.mu held. func (w *builtinWriter) connect() (err error) { if w.conn != nil { // ignore err from close, it makes sense to continue anyway w.conn.close() w.conn = nil } if w.network == "" { w.conn, err = unixSyslog() if w.hostname == "" { w.hostname = "localhost" } } else { var c net.Conn c, err = net.DialTimeout(w.network, w.raddr, remoteDeadline) if err == nil { w.conn = &netConn{conn: c} if w.hostname == "" { w.hostname = c.LocalAddr().String() } } } return } // Write sends a log message to the syslog daemon. func (w *builtinWriter) Write(b []byte) (int, error) { return w.writeAndRetry(w.priority, string(b)) } // Close closes a connection to the syslog daemon. func (w *builtinWriter) Close() error { w.mu.Lock() defer w.mu.Unlock() if w.conn != nil { err := w.conn.close() w.conn = nil return err } return nil } func (w *builtinWriter) writeAndRetry(p syslog.Priority, s string) (int, error) { pr := (w.priority & facilityMask) | (p & severityMask) w.mu.Lock() defer w.mu.Unlock() if w.conn != nil { if n, err := w.write(pr, s); err == nil { return n, err } } if err := w.connect(); err != nil { return 0, err } return w.write(pr, s) } // write generates and writes a syslog formatted string. The // format is as follows: TIMESTAMP HOSTNAME TAG[PID]: MSG func (w *builtinWriter) write(p syslog.Priority, msg string) (int, error) { // ensure it ends in a \n nl := "" if !strings.HasSuffix(msg, "\n") { nl = "\n" } err := w.conn.writeString(p, w.hostname, w.tag, msg, nl) if err != nil { return 0, err } // Note: return the length of the input, not the number of // bytes printed by Fprintf, because this must behave like // an io.Writer. return len(msg), nil } func (n *netConn) writeString(p syslog.Priority, hostname, tag, msg, nl string) error { if n.local { // Compared to the network form below, the changes are: // 1. Use time.Stamp instead of time.RFC3339. // 2. Drop the hostname field from the Fprintf. timestamp := time.Now().Format(time.Stamp) n.conn.SetWriteDeadline(time.Now().Add(localDeadline)) _, err := fmt.Fprintf(n.conn, "<%d>%s %s[%d]: %s%s", p, timestamp, tag, os.Getpid(), msg, nl) return err } timestamp := time.Now().Format(time.RFC3339) n.conn.SetWriteDeadline(time.Now().Add(remoteDeadline)) _, err := fmt.Fprintf(n.conn, "<%d>%s %s %s[%d]: %s%s", p, timestamp, hostname, tag, os.Getpid(), msg, nl) return err } func (n *netConn) close() error { return n.conn.Close() } // unixSyslog opens a connection to the syslog daemon running on the // local machine using a Unix domain socket. func unixSyslog() (conn serverConn, err error) { logTypes := []string{"unixgram", "unix"} logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"} for _, network := range logTypes { for _, path := range logPaths { conn, err := net.DialTimeout(network, path, localDeadline) if err != nil { continue } else { return &netConn{conn: conn, local: true}, nil } } } return nil, errors.New("Unix syslog delivery error") } go-syslog-1.0.0/go.mod000066400000000000000000000000461342036721000145370ustar00rootroot00000000000000module github.com/hashicorp/go-syslog go-syslog-1.0.0/syslog.go000066400000000000000000000010371342036721000153010ustar00rootroot00000000000000package gsyslog // Priority maps to the syslog priority levels type Priority int const ( LOG_EMERG Priority = iota LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG ) // Syslogger interface is used to write log messages to syslog type Syslogger interface { // WriteLevel is used to write a message at a given level WriteLevel(Priority, []byte) error // Write is used to write a message at the default level Write([]byte) (int, error) // Close is used to close the connection to the logger Close() error } go-syslog-1.0.0/unix.go000066400000000000000000000060121342036721000147420ustar00rootroot00000000000000// +build linux darwin dragonfly freebsd netbsd openbsd solaris package gsyslog import ( "fmt" "log/syslog" "strings" ) // builtinLogger wraps the Golang implementation of a // syslog.Writer to provide the Syslogger interface type builtinLogger struct { *builtinWriter } // NewLogger is used to construct a new Syslogger func NewLogger(p Priority, facility, tag string) (Syslogger, error) { fPriority, err := facilityPriority(facility) if err != nil { return nil, err } priority := syslog.Priority(p) | fPriority l, err := newBuiltin(priority, tag) if err != nil { return nil, err } return &builtinLogger{l}, nil } // DialLogger is used to construct a new Syslogger that establishes connection to remote syslog server func DialLogger(network, raddr string, p Priority, facility, tag string) (Syslogger, error) { fPriority, err := facilityPriority(facility) if err != nil { return nil, err } priority := syslog.Priority(p) | fPriority l, err := dialBuiltin(network, raddr, priority, tag) if err != nil { return nil, err } return &builtinLogger{l}, nil } // WriteLevel writes out a message at the given priority func (b *builtinLogger) WriteLevel(p Priority, buf []byte) error { var err error m := string(buf) switch p { case LOG_EMERG: _, err = b.writeAndRetry(syslog.LOG_EMERG, m) case LOG_ALERT: _, err = b.writeAndRetry(syslog.LOG_ALERT, m) case LOG_CRIT: _, err = b.writeAndRetry(syslog.LOG_CRIT, m) case LOG_ERR: _, err = b.writeAndRetry(syslog.LOG_ERR, m) case LOG_WARNING: _, err = b.writeAndRetry(syslog.LOG_WARNING, m) case LOG_NOTICE: _, err = b.writeAndRetry(syslog.LOG_NOTICE, m) case LOG_INFO: _, err = b.writeAndRetry(syslog.LOG_INFO, m) case LOG_DEBUG: _, err = b.writeAndRetry(syslog.LOG_DEBUG, m) default: err = fmt.Errorf("Unknown priority: %v", p) } return err } // facilityPriority converts a facility string into // an appropriate priority level or returns an error func facilityPriority(facility string) (syslog.Priority, error) { facility = strings.ToUpper(facility) switch facility { case "KERN": return syslog.LOG_KERN, nil case "USER": return syslog.LOG_USER, nil case "MAIL": return syslog.LOG_MAIL, nil case "DAEMON": return syslog.LOG_DAEMON, nil case "AUTH": return syslog.LOG_AUTH, nil case "SYSLOG": return syslog.LOG_SYSLOG, nil case "LPR": return syslog.LOG_LPR, nil case "NEWS": return syslog.LOG_NEWS, nil case "UUCP": return syslog.LOG_UUCP, nil case "CRON": return syslog.LOG_CRON, nil case "AUTHPRIV": return syslog.LOG_AUTHPRIV, nil case "FTP": return syslog.LOG_FTP, nil case "LOCAL0": return syslog.LOG_LOCAL0, nil case "LOCAL1": return syslog.LOG_LOCAL1, nil case "LOCAL2": return syslog.LOG_LOCAL2, nil case "LOCAL3": return syslog.LOG_LOCAL3, nil case "LOCAL4": return syslog.LOG_LOCAL4, nil case "LOCAL5": return syslog.LOG_LOCAL5, nil case "LOCAL6": return syslog.LOG_LOCAL6, nil case "LOCAL7": return syslog.LOG_LOCAL7, nil default: return 0, fmt.Errorf("invalid syslog facility: %s", facility) } } go-syslog-1.0.0/unsupported.go000066400000000000000000000007741342036721000163600ustar00rootroot00000000000000// +build windows plan9 nacl package gsyslog import ( "fmt" ) // NewLogger is used to construct a new Syslogger func NewLogger(p Priority, facility, tag string) (Syslogger, error) { return nil, fmt.Errorf("Platform does not support syslog") } // DialLogger is used to construct a new Syslogger that establishes connection to remote syslog server func DialLogger(network, raddr string, p Priority, facility, tag string) (Syslogger, error) { return nil, fmt.Errorf("Platform does not support syslog") }