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