Skip to content

Commit

Permalink
Merge pull request #54 from olabiniV2/stderr_logging
Browse files Browse the repository at this point in the history
Refactor logtarget
  • Loading branch information
actown authored Apr 12, 2020
2 parents f4d41de + 8b2c790 commit a31e589
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 38 deletions.
4 changes: 2 additions & 2 deletions cmd/grumble/grumble.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ func main() {
dataDir.Close()

// Set up logging
err = logtarget.Target.OpenFile(Args.LogPath)
logtarget.Default, err = logtarget.OpenFile(Args.LogPath, os.Stderr)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to open log file (%v): %v", Args.LogPath, err)
return
}
log.SetPrefix("[G] ")
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
log.SetOutput(&logtarget.Target)
log.SetOutput(logtarget.Default)
log.Printf("Grumble")
log.Printf("Using data directory: %s", Args.DataDir)

Expand Down
2 changes: 1 addition & 1 deletion cmd/grumble/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func NewServer(id int64) (s *Server, err error) {
s.Channels[0] = NewChannel(0, "Root")
s.nextChanId = 1

s.Logger = log.New(&logtarget.Target, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds)
s.Logger = log.New(logtarget.Default, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds)

return
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/grumble/signal_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func SignalHandler() {
signal.Notify(sigchan, syscall.SIGUSR2, syscall.SIGTERM, syscall.SIGINT)
for sig := range sigchan {
if sig == syscall.SIGUSR2 {
err := logtarget.Target.Rotate()
err := logtarget.Default.Rotate()
if err != nil {
fmt.Fprintf(os.Stderr, "unable to rotate log file: %v", err)
}
Expand Down
85 changes: 51 additions & 34 deletions pkg/logtarget/logtarget.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package logtarget

import (
"bytes"
"io"
"os"
"sync"
)
Expand All @@ -15,56 +15,72 @@ import (
// LogTarget to be registered with the regular Go log package.
// LogTarget multiplexes its incoming writes to multiple optional
// output writers, and one main output writer (the log file).
type LogTarget struct {
mu sync.Mutex
logfn string
file *os.File
memLog *bytes.Buffer
}

var Target LogTarget
type LogTarget interface {
io.Writer

// Write writes a log message to all registered io.Writers
func (target *LogTarget) Write(in []byte) (int, error) {
target.mu.Lock()
defer target.mu.Unlock()

if target.file == nil {
panic("no log file opened")
}
Rotate() error
}

n, err := os.Stderr.Write(in)
if err != nil {
return n, err
}
// logTarget is the default implementation of a log
// target. It can write to more than one writer at the same time
// but only rotate one file
type logTarget struct {
mu sync.Mutex
logfn string
file *os.File
w io.Writer
ws []io.Writer
}

n, err = target.file.Write(in)
if err != nil {
return n, err
}
// Default is the default log target for the application
// It has to be initialized before used
var Default LogTarget

return len(in), nil
// OpenWriters returns a log target that will
// log to all the given writers at the same time
func OpenWriters(ws ...io.Writer) LogTarget {
target := &logTarget{}
target.w = io.MultiWriter(ws...)
return target
}

// OpenFile opens the main log file for writing.
// OpenFile creates a LogTarget pointing to a log file
// and returns it.
// 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)
// It also takes a variable number of writers that are
// other log targets
func OpenFile(fileName string, ws ...io.Writer) (t LogTarget, err error) {
target := &logTarget{}
target.logfn = fileName
target.file, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650)
if err != nil {
return err
return nil, err
}
return nil
target.ws = ws
target.w = io.MultiWriter(append(ws, target.file)...)
return target, nil
}

// Rotate rotates the current log file.
// Write writes a log message to all registered io.Writers
func (target *logTarget) Write(out []byte) (int, error) {
target.mu.Lock()
defer target.mu.Unlock()

return target.Write(out)
}

// Rotate rotates the current log file, if one is opened.
// This method holds a lock while rotating the log file,
// and all log writes will be held back until the rotation
// is complete.
func (target *LogTarget) Rotate() error {
func (target *logTarget) Rotate() error {
target.mu.Lock()
defer target.mu.Unlock()

if target.file == nil {
return nil
}

// Close the existing log file
err := target.file.Close()
if err != nil {
Expand All @@ -75,6 +91,7 @@ func (target *LogTarget) Rotate() error {
if err != nil {
return err
}
target.w = io.MultiWriter(append(target.ws, target.file)...)

return nil
}

0 comments on commit a31e589

Please sign in to comment.