-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsyslogd.go
More file actions
110 lines (98 loc) · 2.41 KB
/
syslogd.go
File metadata and controls
110 lines (98 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package syslogd
import (
"fmt"
"io"
"log"
"os"
"path"
"regexp"
"github.com/deis/deis/logger/syslog"
)
const logRoot = "/data/logs"
type handler struct {
// To simplify implementation of our handler we embed helper
// syslog.BaseHandler struct.
*syslog.BaseHandler
}
// Simple fiter for named/bind messages which can be used with BaseHandler
func filter(m syslog.SyslogMessage) bool {
return true
}
func newHandler() *handler {
h := handler{syslog.NewBaseHandler(5, filter, false)}
go h.mainLoop() // BaseHandler needs some gorutine that reads from its queue
return &h
}
// check if a file path exists
func fileExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func getLogFile(message string) (io.Writer, error) {
r := regexp.MustCompile(`^.* ([-a-z0-9]+)\[[a-z0-9-_\.]+\].*`)
match := r.FindStringSubmatch(message)
if match == nil {
return nil, fmt.Errorf("Could not find app name in message: %s", message)
}
appName := match[1]
filePath := path.Join(logRoot, appName+".log")
// check if file exists
exists, err := fileExists(filePath)
if err != nil {
return nil, err
}
// return a new file or the existing file for appending
var file io.Writer
if exists {
file, err = os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0644)
} else {
file, err = os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0644)
}
return file, err
}
func writeToDisk(m syslog.SyslogMessage) error {
file, err := getLogFile(m.String())
if err != nil {
return err
}
bytes := []byte(m.String() + "\n")
file.Write(bytes)
return nil
}
// mainLoop reads from BaseHandler queue using h.Get and logs messages to stdout
func (h *handler) mainLoop() {
for {
m := h.Get()
if m == nil {
break
}
err := writeToDisk(m)
if err != nil {
log.Println(err)
}
}
h.End()
}
// Listen starts a new syslog server which runs until it receives a signal.
func Listen(signalChan chan os.Signal, cleanupDone chan bool) {
fmt.Println("Starting syslog...")
// Create a server with one handler and run one listen gorutine
s := syslog.NewServer()
s.AddHandler(newHandler())
s.Listen("0.0.0.0:514")
fmt.Println("Syslog server started...")
fmt.Println("deis-logger running")
// Wait for terminating signal
for _ = range signalChan {
// Shutdown the server
fmt.Println("Shutting down...")
s.Shutdown()
cleanupDone <- true
}
}