package lockingwriter import ( "os" "time" "github.com/gofrs/flock" ) // for now this package defines a writer for use with log.New(). It it intended to be used from the external ssh applications. This logger uses a file lock to allow all the various ssh applications to log to the same file. // the correct way to do this is to send log events to a daemon // but i'm trying to cut a corner type LockingWriter struct { path string } const ( fp = "/town/var/log/external.log" lp = "/town/var/log/log.lock" ) func New() *LockingWriter { f, err := os.OpenFile(fp, os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0660) if err != nil && !os.IsExist(err) { panic(err) } f.Close() return &LockingWriter{ path: fp, } } func (l *LockingWriter) Write(p []byte) (n int, err error) { fl := flock.New(lp) var locked bool for !locked { locked, err = fl.TryLock() if err != nil { return } time.Sleep(time.Second) } var f *os.File f, err = os.OpenFile(l.path, os.O_APPEND|os.O_WRONLY, 0660) if err != nil { return } defer f.Close() defer fl.Unlock() n, err = f.Write(p) if err != nil { panic(err) } return //return f.Write(p) }