--log file with timestamps

This commit is contained in:
Andrey Petrov 2015-01-18 22:05:49 -08:00
parent 6c83bcb06a
commit 797d8c92be
4 changed files with 48 additions and 7 deletions

View File

@ -1,13 +1,20 @@
package chat package chat
import "sync" import (
"fmt"
"io"
"sync"
)
const timestampFmt = "2006-01-02 15:04:05"
// History contains the history entries // History contains the history entries
type History struct { type History struct {
sync.RWMutex
entries []Message entries []Message
head int head int
size int size int
lock sync.Mutex out io.Writer
} }
// NewHistory constructs a new history of the given size // NewHistory constructs a new history of the given size
@ -19,8 +26,8 @@ func NewHistory(size int) *History {
// Add adds the given entry to the entries in the history // Add adds the given entry to the entries in the history
func (h *History) Add(entry Message) { func (h *History) Add(entry Message) {
h.lock.Lock() h.Lock()
defer h.lock.Unlock() defer h.Unlock()
max := cap(h.entries) max := cap(h.entries)
h.head = (h.head + 1) % max h.head = (h.head + 1) % max
@ -28,6 +35,10 @@ func (h *History) Add(entry Message) {
if h.size < max { if h.size < max {
h.size++ h.size++
} }
if h.out != nil {
fmt.Fprintf(h.out, "[%s] %s\n", entry.Timestamp().UTC().Format(timestampFmt), entry.String())
}
} }
// Len returns the number of entries in the history // Len returns the number of entries in the history
@ -37,8 +48,8 @@ func (h *History) Len() int {
// Get the entry with the given number // Get the entry with the given number
func (h *History) Get(num int) []Message { func (h *History) Get(num int) []Message {
h.lock.Lock() h.RLock()
defer h.lock.Unlock() defer h.RUnlock()
max := cap(h.entries) max := cap(h.entries)
if num > h.size { if num > h.size {
@ -56,3 +67,10 @@ func (h *History) Get(num int) []Message {
return r return r
} }
// SetOutput sets the output for logging added messages
func (h *History) SetOutput(w io.Writer) {
h.Lock()
h.out = w
h.Unlock()
}

View File

@ -11,6 +11,7 @@ type Message interface {
Render(*Theme) string Render(*Theme) string
String() string String() string
Command() string Command() string
Timestamp() time.Time
} }
type MessageTo interface { type MessageTo interface {
@ -61,6 +62,10 @@ func (m *Msg) Command() string {
return "" return ""
} }
func (m *Msg) Timestamp() time.Time {
return m.timestamp
}
// PublicMsg is any message from a user sent to the room. // PublicMsg is any message from a user sent to the room.
type PublicMsg struct { type PublicMsg struct {
Msg Msg

View File

@ -3,6 +3,7 @@ package chat
import ( import (
"errors" "errors"
"fmt" "fmt"
"io"
"sync" "sync"
) )
@ -59,6 +60,11 @@ func (r *Room) Close() {
}) })
} }
// SetLogging sets logging output for the room's history
func (r *Room) SetLogging(out io.Writer) {
r.history.SetOutput(out)
}
// HandleMsg reacts to a message, will block until done. // HandleMsg reacts to a message, will block until done.
func (r *Room) HandleMsg(m Message) { func (r *Room) HandleMsg(m Message) {
switch m := m.(type) { switch m := m.(type) {

14
cmd.go
View File

@ -28,6 +28,7 @@ type Options struct {
Admin string `long:"admin" description:"File of public keys who are admins."` Admin string `long:"admin" description:"File of public keys who are admins."`
Whitelist string `long:"whitelist" description:"Optional file of public keys who are allowed to connect."` Whitelist string `long:"whitelist" description:"Optional file of public keys who are allowed to connect."`
Motd string `long:"motd" description:"Optional Message of the Day file."` Motd string `long:"motd" description:"Optional Message of the Day file."`
Log string `long:"log" description:"Write chat log to this file."`
Pprof int `long:"pprof" description:"Enable pprof http server for profiling."` Pprof int `long:"pprof" description:"Enable pprof http server for profiling."`
} }
@ -116,7 +117,7 @@ func main() {
return err return err
} }
auth.Op(key) auth.Op(key)
logger.Debugf("Added admin: %s", line) logger.Debugf("Added admin: %s", sshd.Fingerprint(key))
return nil return nil
}) })
if err != nil { if err != nil {
@ -151,6 +152,17 @@ func main() {
host.SetMotd(motdString) host.SetMotd(motdString)
} }
if options.Log == "-" {
host.SetLogging(os.Stdout)
} else if options.Log != "" {
fp, err := os.OpenFile(options.Log, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
logger.Errorf("Failed to open log file for writing: %v", err)
return
}
host.SetLogging(fp)
}
go host.Serve() go host.Serve()
// Construct interrupt handler // Construct interrupt handler