mirror of
https://github.com/mumble-voip/grumble.git
synced 2025-12-19 21:59:59 -08:00
92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
// Copyright (c) 2011 The Grumble Authors
|
|
// The use of this source code is goverened by a BSD-style
|
|
// license that can be found in the LICENSE-file.
|
|
|
|
// Package logtarget implements a multiplexing logging target
|
|
package logtarget
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
type LogTarget interface {
|
|
io.Writer
|
|
|
|
OpenFile(string) error
|
|
Rotate() error
|
|
}
|
|
|
|
// LogTarget implements the io.Writer interface, allowing
|
|
// 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 FileLogTarget struct {
|
|
mu sync.Mutex
|
|
logfn string
|
|
file *os.File
|
|
memLog *bytes.Buffer
|
|
}
|
|
|
|
var Target LogTarget
|
|
|
|
func init() {
|
|
Target = &FileLogTarget{}
|
|
}
|
|
|
|
// Write writes a log message to all registered io.Writers
|
|
func (target *FileLogTarget) Write(in []byte) (int, error) {
|
|
target.mu.Lock()
|
|
defer target.mu.Unlock()
|
|
|
|
if target.file == nil {
|
|
panic("no log file opened")
|
|
}
|
|
|
|
n, err := os.Stderr.Write(in)
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
|
|
n, err = target.file.Write(in)
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
|
|
return len(in), nil
|
|
}
|
|
|
|
// OpenFile opens the main log file for writing.
|
|
// This method will open the file in append-only mode.
|
|
func (target *FileLogTarget) 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
|
|
}
|
|
|
|
// Rotate rotates the current log file.
|
|
// 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 *FileLogTarget) 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
|
|
}
|