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