From b13dbeadf1d103d86635adf9b4b3d70f693f6844 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Thu, 10 Nov 2011 00:38:59 +0100 Subject: [PATCH] Improved logging. --- Makefile | 1 + args.go | 6 ++++++ grumble.go | 10 +++++++++- log.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ server.go | 5 ++--- signal_unix.go | 13 +++++++++++-- 6 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 log.go diff --git a/Makefile b/Makefile index f60b162..2ff04f7 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,7 @@ GOFILES = \ gencert.go \ register.go \ ssh.go \ + log.go \ args.go \ ifeq ($(SQLITE),1) diff --git a/args.go b/args.go index ddd9534..946be8b 100644 --- a/args.go +++ b/args.go @@ -11,6 +11,7 @@ import ( type args struct { ShowHelp bool DataDir string + LogPath string SshAddr string RegenKeys bool SQLiteDB string @@ -25,6 +26,10 @@ func defaultDataDir() string { return filepath.Join(os.Getenv("HOME"), dirname) } +func defaultLogPath() string { + return filepath.Join(defaultDataDir(), "grumble.log") +} + func Usage() { fmt.Fprintf(os.Stderr, "usage: grumble [options]\n") fmt.Fprintf(os.Stderr, "remote control: grumble [options] ctl [ctlopts]\n") @@ -36,6 +41,7 @@ var Args args func init() { flag.BoolVar(&Args.ShowHelp, "help", false, "Show this help") flag.StringVar(&Args.DataDir, "datadir", defaultDataDir(), "Directory to use for server storage") + flag.StringVar(&Args.LogPath, "log", defaultLogPath(), "Log file path") flag.StringVar(&Args.SshAddr, "ssh", "localhost:46545", "Address to use for SSH admin prompt") flag.BoolVar(&Args.RegenKeys, "regenkeys", false, "Force Grumble to regenerate its global RSA keypair and certificate") diff --git a/grumble.go b/grumble.go index 5040e9f..f9ad908 100644 --- a/grumble.go +++ b/grumble.go @@ -25,8 +25,16 @@ func main() { return } + err = LogTarget.OpenFile(Args.LogPath) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to open log file: %v", err) + return + } + log.SetPrefix("[G] ") log.SetFlags(log.LstdFlags | log.Lmicroseconds) + log.SetOutput(&LogTarget) + log.Printf("Grumble") log.Printf("Using data directory: %s", Args.DataDir) @@ -164,4 +172,4 @@ func main() { go SignalHandler() select {} } -} +} \ No newline at end of file diff --git a/log.go b/log.go new file mode 100644 index 0000000..e83066d --- /dev/null +++ b/log.go @@ -0,0 +1,53 @@ +package main + +import ( + "bytes" + "os" + "sync" +) + +type logTarget struct { + mu sync.Mutex + logfn string + file *os.File + memLog *bytes.Buffer +} + +var LogTarget logTarget + +func (target *logTarget) Write(in []byte) (int, error) { + target.mu.Lock() + defer target.mu.Unlock() + + return target.file.Write(in) +} + +// Open a log file for writing. +// This method will open the file in append-only mode. +func (target *logTarget) OpenFile(fn string) (err error) { + target.logfn = fn + target.file, err = os.OpenFile(target.logfn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) + if err != nil { + return err + } + return nil +} + +// Perform a log rotation +func (target *logTarget) Rotate() error { + target.mu.Lock() + defer target.mu.Unlock() + + // Close the existing log file + err := target.file.Close() + if err != nil { + return err + } + + target.file, err = os.OpenFile(target.logfn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) + if err != nil { + return err + } + + return nil +} diff --git a/server.go b/server.go index 56dd843..463dfad 100644 --- a/server.go +++ b/server.go @@ -26,7 +26,6 @@ import ( "hash" "log" "net" - "os" "path/filepath" "strings" "sync" @@ -122,7 +121,7 @@ type clientLogForwarder struct { } func (lf clientLogForwarder) Write(incoming []byte) (int, error) { - buf := bytes.NewBuffer(nil) + buf := new(bytes.Buffer) buf.WriteString(fmt.Sprintf("<%v:%v(%v)> ", lf.client.Session, lf.client.ShownName(), lf.client.UserId())) buf.Write(incoming) lf.logger.Output(3, buf.String()) @@ -166,7 +165,7 @@ func NewServer(id int64, addr string, port int) (s *Server, err error) { s.Channels[0] = NewChannel(0, "Root") s.nextChanId = 1 - s.Logger = log.New(os.Stdout, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) + s.Logger = log.New(&LogTarget, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) return } diff --git a/signal_unix.go b/signal_unix.go index 5d0dff2..ecab22b 100644 --- a/signal_unix.go +++ b/signal_unix.go @@ -5,6 +5,7 @@ package main import ( + "fmt" "os" "os/signal" ) @@ -12,9 +13,17 @@ import ( func SignalHandler() { for { sig := <-signal.Incoming - if sig != os.SIGINT && sig != os.SIGTERM { + + if sig == os.SIGUSR2 { + err := LogTarget.Rotate() + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to rotate log file: %v", err) + } continue } - os.Exit(0) + + if sig == os.SIGINT || sig == os.SIGTERM { + os.Exit(0) + } } }