ctop/logging/main.go

111 lines
1.7 KiB
Go
Raw Normal View History

package logging
import (
2017-02-04 08:59:33 +00:00
"fmt"
"net"
"sync"
"time"
"github.com/op/go-logging"
)
const (
2017-02-04 08:59:33 +00:00
size = 1024
path = "/tmp/ctop.sock"
)
2017-02-11 03:58:26 +00:00
var (
2017-02-12 05:10:40 +00:00
Log *CTopLogger
2017-02-11 03:58:26 +00:00
wg sync.WaitGroup
2017-02-12 05:10:40 +00:00
exited bool
2017-02-11 03:58:26 +00:00
format = logging.MustStringFormatter(
`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)
)
type CTopLogger struct {
*logging.Logger
backend *logging.MemoryBackend
2017-02-04 08:59:33 +00:00
}
2017-02-12 05:10:40 +00:00
func Init(serverEnabled string) *CTopLogger {
if Log == nil {
Log = &CTopLogger{
logging.MustGetLogger("ctop"),
logging.NewMemoryBackend(size),
}
2017-02-04 08:59:33 +00:00
2017-02-12 05:10:40 +00:00
backendFmt := logging.NewBackendFormatter(Log.backend, format)
logging.SetBackend(backendFmt)
Log.Notice("logger initialized")
2017-02-04 08:59:33 +00:00
2017-02-12 05:10:40 +00:00
if serverEnabled == "1" {
Log.Serve()
}
2017-02-04 08:59:33 +00:00
}
2017-02-12 05:10:40 +00:00
return Log
2017-02-04 08:59:33 +00:00
}
func (log *CTopLogger) Exit() {
exited = true
wg.Wait()
}
func (log *CTopLogger) Serve() {
ln, err := net.Listen("unix", path)
if err != nil {
panic(err)
}
2017-02-04 08:59:33 +00:00
go func() {
for {
conn, err := ln.Accept()
if err != nil {
if err, ok := err.(net.Error); ok && err.Temporary() {
continue
}
return
2017-02-04 08:59:33 +00:00
}
go log.handler(conn)
}
}()
log.Notice("logging server started")
}
func (log *CTopLogger) handler(conn net.Conn) {
wg.Add(1)
defer wg.Done()
defer conn.Close()
for msg := range log.tail() {
2017-02-04 08:59:33 +00:00
msg = fmt.Sprintf("%s\n", msg)
conn.Write([]byte(msg))
}
conn.Write([]byte("bye\n"))
}
func (log *CTopLogger) tail() chan string {
stream := make(chan string)
node := log.backend.Head()
go func() {
for {
stream <- node.Record.Formatted(0)
for {
nnode := node.Next()
if nnode != nil {
node = nnode
break
}
if exited {
close(stream)
return
}
time.Sleep(1 * time.Second)
}
}
}()
return stream
}