remote syslog support

This commit is contained in:
Máximo Cuadros Ortiz
2014-10-11 00:54:28 +02:00
parent 6586ac4653
commit d99c6aeead
9 changed files with 139 additions and 62 deletions

View File

@@ -16,6 +16,8 @@ Server options:
Logging options:
-l, --log FILE File to redirect log output
-T, --logtime Timestamp log entries (default: true)
-s, --syslog Enable syslog as log method.
-r, --remote_syslog Syslog server addr (udp://localhost:514).
-D, --debug Enable debugging output
-V, --trace Trace the raw protocol

View File

@@ -42,7 +42,10 @@ func main() {
flag.StringVar(&opts.PidFile, "pid", "", "File to store process pid.")
flag.StringVar(&opts.LogFile, "l", "", "File to store logging output.")
flag.StringVar(&opts.LogFile, "log", "", "File to store logging output.")
flag.BoolVar(&opts.Syslog, "syslog", false, "Enable syslog as log method.")
flag.BoolVar(&opts.Syslog, "s", false, "Enable syslog as log method.")
flag.BoolVar(&opts.Syslog, "syslog", false, "Enable syslog as log method..")
flag.StringVar(&opts.RemoteSyslog, "r", "", "Syslog server addr (udp://localhost:514).")
flag.StringVar(&opts.RemoteSyslog, "remote_syslog", "", "Syslog server addr (udp://localhost:514).")
flag.BoolVar(&showVersion, "version", false, "Print version information.")
flag.BoolVar(&showVersion, "v", false, "Print version information.")
flag.IntVar(&opts.ProfPort, "profile", 0, "Profiling HTTP port")
@@ -99,14 +102,17 @@ func main() {
}
func buildLogger(opts *server.Options) server.Logger {
if opts.Syslog {
return logger.NewSysLogger(opts.Debug, opts.Trace)
}
if opts.LogFile != "" {
return logger.NewFileLogger(opts.LogFile, opts.Logtime, opts.Debug, opts.Trace)
}
return logger.NewStdLogger(opts.Logtime, opts.Debug, opts.Trace, true)
if opts.RemoteSyslog != "" {
return logger.NewRemoteSysLogger(opts.RemoteSyslog, opts.Debug, opts.Trace)
}
if opts.Syslog {
return logger.NewSysLogger(opts.Debug, opts.Trace)
}
return logger.NewStdLogger(opts.Logtime, opts.Debug, opts.Trace, true)
}

View File

@@ -17,12 +17,12 @@ func TestStdLogger(t *testing.T) {
t.Fatalf("Expected %q, received %q\n", 0, flags)
}
if logger.debug != false {
t.Fatalf("Expected %b, received %b\n", false, logger.debug)
if logger.debug {
t.Fatalf("Expected %t, received %t\n", false, logger.debug)
}
if logger.trace != false {
t.Fatalf("Expected %b, received %b\n", false, logger.trace)
if logger.trace {
t.Fatalf("Expected %t, received %t\n", false, logger.trace)
}
}
@@ -34,12 +34,12 @@ func TestStdLoggerWithDebugTraceAndTime(t *testing.T) {
t.Fatalf("Expected %d, received %d\n", log.LstdFlags, flags)
}
if logger.debug != true {
t.Fatalf("Expected %b, received %b\n", true, logger.debug)
if !logger.debug {
t.Fatalf("Expected %t, received %t\n", true, logger.debug)
}
if logger.trace != true {
t.Fatalf("Expected %b, received %b\n", true, logger.trace)
if !logger.trace {
t.Fatalf("Expected %t, received %t\n", true, logger.trace)
}
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"log/syslog"
"net/url"
)
type SysLogger struct {
@@ -16,7 +17,7 @@ type SysLogger struct {
func NewSysLogger(debug, trace bool) *SysLogger {
w, err := syslog.New(syslog.LOG_DAEMON|syslog.LOG_NOTICE, "gnatsd")
if err != nil {
log.Fatal("error connecting to syslog: %v", err)
log.Fatalf("error connecting to syslog: %q", err.Error())
}
return &SysLogger{
@@ -26,10 +27,11 @@ func NewSysLogger(debug, trace bool) *SysLogger {
}
}
func NewRemoteSysLogger(network, raddr string, debug, trace bool) *SysLogger {
w, err := syslog.Dial(network, raddr, syslog.LOG_DEBUG, "gnatsd")
func NewRemoteSysLogger(fqn string, debug, trace bool) *SysLogger {
network, addr := getNetworkAndAddr(fqn)
w, err := syslog.Dial(network, addr, syslog.LOG_DEBUG, "gnatsd")
if err != nil {
log.Fatal("error connecting to syslog: %v", err)
log.Fatalf("error connecting to syslog: %q", err.Error())
}
return &SysLogger{
@@ -39,6 +41,24 @@ func NewRemoteSysLogger(network, raddr string, debug, trace bool) *SysLogger {
}
}
func getNetworkAndAddr(fqn string) (network, addr string) {
u, err := url.Parse(fqn)
if err != nil {
log.Fatal(err)
}
network = u.Scheme
if network == "udp" || network == "tcp" {
addr = u.Host
} else if network == "unix" {
addr = u.Path
} else {
log.Fatalf("error invalid network type: %q", u.Scheme)
}
return
}
func (l *SysLogger) Log(format string, v ...interface{}) {
l.writer.Notice(fmt.Sprintf(format, v...))
}

View File

@@ -1,6 +1,7 @@
package logger
import (
"fmt"
"log"
"net"
"strings"
@@ -8,50 +9,50 @@ import (
"time"
)
var serverAddr string
var serverFQN string
func TestSysLogger(t *testing.T) {
logger := NewSysLogger(false, false)
if logger.debug != false {
t.Fatalf("Expected %b, received %b\n", false, logger.debug)
if logger.debug {
t.Fatalf("Expected %t, received %t\n", false, logger.debug)
}
if logger.trace != false {
t.Fatalf("Expected %b, received %b\n", false, logger.trace)
if logger.trace {
t.Fatalf("Expected %t, received %t\n", false, logger.trace)
}
}
func TestSysLoggerWithDebugAndTrace(t *testing.T) {
logger := NewSysLogger(true, true)
if logger.debug != true {
t.Fatalf("Expected %b, received %b\n", true, logger.debug)
if !logger.debug {
t.Fatalf("Expected %t, received %t\n", true, logger.debug)
}
if logger.trace != true {
t.Fatalf("Expected %b, received %b\n", true, logger.trace)
if !logger.trace {
t.Fatalf("Expected %t, received %t\n", true, logger.trace)
}
}
func TestRemoteSysLogger(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger := NewRemoteSysLogger(serverFQN, true, true)
if logger.debug != true {
t.Fatalf("Expected %b, received %b\n", true, logger.debug)
if !logger.debug {
t.Fatalf("Expected %t, received %t\n", true, logger.debug)
}
if logger.trace != true {
t.Fatalf("Expected %b, received %b\n", true, logger.trace)
if !logger.trace {
t.Fatalf("Expected %t, received %t\n", true, logger.trace)
}
}
func TestRemoteSysLoggerLog(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger := NewRemoteSysLogger(serverFQN, true, true)
logger.Log("foo %s", "bar")
expectSyslogOutput(t, <-done, "foo bar\n")
@@ -60,7 +61,7 @@ func TestRemoteSysLoggerLog(t *testing.T) {
func TestRemoteSysLoggerDebug(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger := NewRemoteSysLogger(serverFQN, true, true)
logger.Debug("foo %s", "qux")
expectSyslogOutput(t, <-done, "foo qux\n")
@@ -69,7 +70,7 @@ func TestRemoteSysLoggerDebug(t *testing.T) {
func TestRemoteSysLoggerDebugDisabled(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, false, false)
logger := NewRemoteSysLogger(serverFQN, false, false)
logger.Debug("foo %s", "qux")
rcvd := <-done
@@ -81,7 +82,7 @@ func TestRemoteSysLoggerDebugDisabled(t *testing.T) {
func TestRemoteSysLoggerTrace(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger := NewRemoteSysLogger(serverFQN, true, true)
logger.Trace("foo %s", "qux")
expectSyslogOutput(t, <-done, "foo qux\n")
@@ -90,7 +91,7 @@ func TestRemoteSysLoggerTrace(t *testing.T) {
func TestRemoteSysLoggerTraceDisabled(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, false)
logger := NewRemoteSysLogger(serverFQN, true, false)
logger.Trace("foo %s", "qux")
rcvd := <-done
@@ -99,6 +100,41 @@ func TestRemoteSysLoggerTraceDisabled(t *testing.T) {
}
}
func TestGetNetworkAndAddrUDP(t *testing.T) {
n, a := getNetworkAndAddr("udp://foo.com:1000")
if n != "udp" {
t.Fatalf("Unexpected network %s\n", n)
}
if a != "foo.com:1000" {
t.Fatalf("Unexpected addr %s\n", a)
}
}
func TestGetNetworkAndAddrTCP(t *testing.T) {
n, a := getNetworkAndAddr("tcp://foo.com:1000")
if n != "tcp" {
t.Fatalf("Unexpected network %s\n", n)
}
if a != "foo.com:1000" {
t.Fatalf("Unexpected addr %s\n", a)
}
}
func TestGetNetworkAndAddrUnix(t *testing.T) {
n, a := getNetworkAndAddr("unix:///foo.sock")
if n != "unix" {
t.Fatalf("Unexpected network %s\n", n)
}
if a != "/foo.sock" {
t.Fatalf("Unexpected addr %s\n", a)
}
}
func expectSyslogOutput(t *testing.T, line string, expected string) {
data := strings.Split(line, "]: ")
if len(data) != 2 {
@@ -129,7 +165,7 @@ func startServer(done chan<- string) {
log.Fatalf("net.ListenPacket failed udp :0 %v", e)
}
serverAddr = c.LocalAddr().String()
serverFQN = fmt.Sprintf("udp://%s", c.LocalAddr().String())
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
go runSyslog(c, done)
}

View File

@@ -17,6 +17,8 @@ debug: false
trace: true
logtime: false
log_file: "/tmp/gnatsd.log"
syslog: true
remote_syslog: "udp://foo.com:33"
#pid file
pid_file: "/tmp/gnatsd.pid"

View File

@@ -44,6 +44,7 @@ type Options struct {
PidFile string `json:"-"`
LogFile string `json:"-"`
Syslog bool `json:"-"`
RemoteSyslog string `json:"-"`
}
type authorization struct {
@@ -98,6 +99,10 @@ func ProcessConfigFile(configFile string) (*Options, error) {
}
case "logfile", "log_file":
opts.LogFile = v.(string)
case "syslog":
opts.Syslog = v.(bool)
case "remote_syslog":
opts.RemoteSyslog = v.(string)
case "pidfile", "pid_file":
opts.PidFile = v.(string)
case "prof_port":

View File

@@ -44,18 +44,20 @@ func TestOptions_RandomPort(t *testing.T) {
func TestConfigFile(t *testing.T) {
golden := &Options{
Host: "apcera.me",
Port: 4242,
Username: "derek",
Password: "bella",
AuthTimeout: 1.0,
Debug: false,
Trace: true,
Logtime: false,
HTTPPort: 8222,
LogFile: "/tmp/gnatsd.log",
PidFile: "/tmp/gnatsd.pid",
ProfPort: 6543,
Host: "apcera.me",
Port: 4242,
Username: "derek",
Password: "bella",
AuthTimeout: 1.0,
Debug: false,
Trace: true,
Logtime: false,
HTTPPort: 8222,
LogFile: "/tmp/gnatsd.log",
PidFile: "/tmp/gnatsd.pid",
ProfPort: 6543,
Syslog: true,
RemoteSyslog: "udp://foo.com:33",
}
opts, err := ProcessConfigFile("./configs/test.conf")
@@ -71,18 +73,20 @@ func TestConfigFile(t *testing.T) {
func TestMergeOverrides(t *testing.T) {
golden := &Options{
Host: "apcera.me",
Port: 2222,
Username: "derek",
Password: "spooky",
AuthTimeout: 1.0,
Debug: true,
Trace: true,
Logtime: false,
HTTPPort: DEFAULT_HTTP_PORT,
LogFile: "/tmp/gnatsd.log",
PidFile: "/tmp/gnatsd.pid",
ProfPort: 6789,
Host: "apcera.me",
Port: 2222,
Username: "derek",
Password: "spooky",
AuthTimeout: 1.0,
Debug: true,
Trace: true,
Logtime: false,
HTTPPort: DEFAULT_HTTP_PORT,
LogFile: "/tmp/gnatsd.log",
PidFile: "/tmp/gnatsd.pid",
ProfPort: 6789,
Syslog: true,
RemoteSyslog: "udp://foo.com:33",
}
fopts, err := ProcessConfigFile("./configs/test.conf")
if err != nil {

View File

@@ -18,6 +18,8 @@ Server options:
Logging options:
-l, --log FILE File to redirect log output
-T, --logtime Timestamp log entries (default: true)
-s, --syslog Enable syslog as log method.
-r, --remote_syslog Syslog server addr (udp://localhost:514).
-D, --debug Enable debugging output
-V, --trace Trace the raw protocol