1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- package applog
- import (
- "log"
- "os"
- "time"
- )
- var Enabled bool
- type logToFile struct {
- fn string
- file *os.File
- closing chan chan error // channel to close the file. Pass a 'chan error' which returns the error
- }
- var ltf *logToFile
- func newlogToFile(fn string) *logToFile {
- return &logToFile{
- fn: fn,
- file: nil,
- closing: make(chan chan error),
- }
- }
- func Printf(format string, a ...interface{}) {
- if Enabled {
- log.Printf(format, a...)
- }
- }
- func Println(a ...interface{}) {
- if Enabled {
- log.Println(a...)
- }
- }
- func logToFileMonitor() {
- for {
- select {
- case errc := <-ltf.closing: // a close has been requested
- if ltf.file != nil {
- log.SetOutput(os.Stderr)
- ltf.file.Close()
- ltf.file = nil
- }
- errc <- nil // pass a 'nil' error back, as everything worked fine
- return
- case <-time.After(time.Duration(5 * time.Second)):
- if fi, err := os.Stat(ltf.fn); err != nil || fi.Size() == 0 {
- // it has rotated - first check we can open the new file
- if f, err := os.OpenFile(ltf.fn, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
- // Send the error to the current log file - not ideal
- log.Printf("Could not open new log file: %v", err)
- } else {
- log.SetOutput(f)
- log.Printf("Rotating log file")
- ltf.file.Close()
- ltf.file = f
- }
- }
- }
- }
- }
- func FileOpen(fn string) {
- ltf = newlogToFile(fn)
- var err error
- ltf.file, err = os.OpenFile(fn, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
- if err != nil {
- log.Fatalf("Error writing log file: %v", err)
- }
- // we deliberately do not close logFile here, because we keep it open pretty much for ever
- log.SetOutput(ltf.file)
- log.Printf("Opening log file")
- go logToFileMonitor()
- }
- func FileClose() {
- if ltf != nil {
- log.Printf("Closing log file")
- errc := make(chan error) // pass a 'chan error' through the closing channel
- ltf.closing <- errc
- _ = <-errc // wait until the monitor has closed the log file and exited
- close(ltf.closing) // close our 'chan error' channel
- ltf = nil
- }
- }
|