github.com/greenboxal/deis@v1.12.1/logspout/routes.go (about) 1 package main 2 3 import ( 4 "crypto/sha1" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "log" 9 "os" 10 "strconv" 11 "strings" 12 "sync" 13 "time" 14 ) 15 16 type RouteStore interface { 17 Get(id string) (*Route, error) 18 GetAll() ([]*Route, error) 19 Add(route *Route) error 20 Remove(id string) bool 21 } 22 23 type RouteManager struct { 24 sync.Mutex 25 persistor RouteStore 26 attacher *AttachManager 27 routes map[string]*Route 28 } 29 30 func NewRouteManager(attacher *AttachManager) *RouteManager { 31 return &RouteManager{attacher: attacher, routes: make(map[string]*Route)} 32 } 33 34 func (rm *RouteManager) Load(persistor RouteStore) error { 35 routes, err := persistor.GetAll() 36 if err != nil { 37 return err 38 } 39 for _, route := range routes { 40 rm.Add(route) 41 } 42 rm.persistor = persistor 43 return nil 44 } 45 46 func (rm *RouteManager) Get(id string) (*Route, error) { 47 rm.Lock() 48 defer rm.Unlock() 49 route, ok := rm.routes[id] 50 if !ok { 51 return nil, os.ErrNotExist 52 } 53 return route, nil 54 } 55 56 func (rm *RouteManager) GetAll() ([]*Route, error) { 57 rm.Lock() 58 defer rm.Unlock() 59 routes := make([]*Route, 0) 60 for _, route := range rm.routes { 61 routes = append(routes, route) 62 } 63 return routes, nil 64 } 65 66 func (rm *RouteManager) Add(route *Route) error { 67 rm.Lock() 68 defer rm.Unlock() 69 if route.ID == "" { 70 h := sha1.New() 71 io.WriteString(h, strconv.Itoa(int(time.Now().UnixNano()))) 72 route.ID = fmt.Sprintf("%x", h.Sum(nil))[:12] 73 } 74 route.closer = make(chan bool) 75 rm.routes[route.ID] = route 76 types := []string{} 77 if route.Source != nil { 78 types = append(types, route.Source.Types...) 79 } 80 go func() { 81 logstream := make(chan *Log) 82 defer close(logstream) 83 go syslogStreamer(route.Target, types, logstream) 84 rm.attacher.Listen(route.Source, logstream, route.closer) 85 }() 86 if rm.persistor != nil { 87 if err := rm.persistor.Add(route); err != nil { 88 log.Println("persistor:", err) 89 } 90 } 91 return nil 92 } 93 94 func (rm *RouteManager) Remove(id string) bool { 95 rm.Lock() 96 defer rm.Unlock() 97 route, ok := rm.routes[id] 98 if ok && route.closer != nil { 99 route.closer <- true 100 } 101 delete(rm.routes, id) 102 if rm.persistor != nil { 103 rm.persistor.Remove(id) 104 } 105 return ok 106 } 107 108 type RouteFileStore string 109 110 func (fs RouteFileStore) Filename(id string) string { 111 return string(fs) + "/" + id + ".json" 112 } 113 114 func (fs RouteFileStore) Get(id string) (*Route, error) { 115 file, err := os.Open(fs.Filename(id)) 116 if err != nil { 117 return nil, err 118 } 119 route := new(Route) 120 if err = unmarshal(file, route); err != nil { 121 return nil, err 122 } 123 return route, nil 124 } 125 126 func (fs RouteFileStore) GetAll() ([]*Route, error) { 127 files, err := ioutil.ReadDir(string(fs)) 128 if err != nil { 129 return nil, err 130 } 131 var routes []*Route 132 for _, file := range files { 133 fileparts := strings.Split(file.Name(), ".") 134 if len(fileparts) > 1 && fileparts[1] == "json" { 135 route, err := fs.Get(fileparts[0]) 136 if err == nil { 137 routes = append(routes, route) 138 } 139 } 140 } 141 return routes, nil 142 } 143 144 func (fs RouteFileStore) Add(route *Route) error { 145 return ioutil.WriteFile(fs.Filename(route.ID), marshal(route), 0644) 146 } 147 148 func (fs RouteFileStore) Remove(id string) bool { 149 if _, err := os.Stat(fs.Filename(id)); err == nil { 150 if err := os.Remove(fs.Filename(id)); err != nil { 151 return true 152 } 153 } 154 return false 155 }