github.com/astaxie/beego@v1.12.3/logs/alils/alils.go (about) 1 package alils 2 3 import ( 4 "encoding/json" 5 "strings" 6 "sync" 7 "time" 8 9 "github.com/astaxie/beego/logs" 10 "github.com/gogo/protobuf/proto" 11 ) 12 13 const ( 14 // CacheSize set the flush size 15 CacheSize int = 64 16 // Delimiter define the topic delimiter 17 Delimiter string = "##" 18 ) 19 20 // Config is the Config for Ali Log 21 type Config struct { 22 Project string `json:"project"` 23 Endpoint string `json:"endpoint"` 24 KeyID string `json:"key_id"` 25 KeySecret string `json:"key_secret"` 26 LogStore string `json:"log_store"` 27 Topics []string `json:"topics"` 28 Source string `json:"source"` 29 Level int `json:"level"` 30 FlushWhen int `json:"flush_when"` 31 } 32 33 // aliLSWriter implements LoggerInterface. 34 // it writes messages in keep-live tcp connection. 35 type aliLSWriter struct { 36 store *LogStore 37 group []*LogGroup 38 withMap bool 39 groupMap map[string]*LogGroup 40 lock *sync.Mutex 41 Config 42 } 43 44 // NewAliLS create a new Logger 45 func NewAliLS() logs.Logger { 46 alils := new(aliLSWriter) 47 alils.Level = logs.LevelTrace 48 return alils 49 } 50 51 // Init parse config and init struct 52 func (c *aliLSWriter) Init(jsonConfig string) (err error) { 53 54 json.Unmarshal([]byte(jsonConfig), c) 55 56 if c.FlushWhen > CacheSize { 57 c.FlushWhen = CacheSize 58 } 59 60 prj := &LogProject{ 61 Name: c.Project, 62 Endpoint: c.Endpoint, 63 AccessKeyID: c.KeyID, 64 AccessKeySecret: c.KeySecret, 65 } 66 67 c.store, err = prj.GetLogStore(c.LogStore) 68 if err != nil { 69 return err 70 } 71 72 // Create default Log Group 73 c.group = append(c.group, &LogGroup{ 74 Topic: proto.String(""), 75 Source: proto.String(c.Source), 76 Logs: make([]*Log, 0, c.FlushWhen), 77 }) 78 79 // Create other Log Group 80 c.groupMap = make(map[string]*LogGroup) 81 for _, topic := range c.Topics { 82 83 lg := &LogGroup{ 84 Topic: proto.String(topic), 85 Source: proto.String(c.Source), 86 Logs: make([]*Log, 0, c.FlushWhen), 87 } 88 89 c.group = append(c.group, lg) 90 c.groupMap[topic] = lg 91 } 92 93 if len(c.group) == 1 { 94 c.withMap = false 95 } else { 96 c.withMap = true 97 } 98 99 c.lock = &sync.Mutex{} 100 101 return nil 102 } 103 104 // WriteMsg write message in connection. 105 // if connection is down, try to re-connect. 106 func (c *aliLSWriter) WriteMsg(when time.Time, msg string, level int) (err error) { 107 108 if level > c.Level { 109 return nil 110 } 111 112 var topic string 113 var content string 114 var lg *LogGroup 115 if c.withMap { 116 117 // Topic,LogGroup 118 strs := strings.SplitN(msg, Delimiter, 2) 119 if len(strs) == 2 { 120 pos := strings.LastIndex(strs[0], " ") 121 topic = strs[0][pos+1 : len(strs[0])] 122 content = strs[0][0:pos] + strs[1] 123 lg = c.groupMap[topic] 124 } 125 126 // send to empty Topic 127 if lg == nil { 128 content = msg 129 lg = c.group[0] 130 } 131 } else { 132 content = msg 133 lg = c.group[0] 134 } 135 136 c1 := &LogContent{ 137 Key: proto.String("msg"), 138 Value: proto.String(content), 139 } 140 141 l := &Log{ 142 Time: proto.Uint32(uint32(when.Unix())), 143 Contents: []*LogContent{ 144 c1, 145 }, 146 } 147 148 c.lock.Lock() 149 lg.Logs = append(lg.Logs, l) 150 c.lock.Unlock() 151 152 if len(lg.Logs) >= c.FlushWhen { 153 c.flush(lg) 154 } 155 156 return nil 157 } 158 159 // Flush implementing method. empty. 160 func (c *aliLSWriter) Flush() { 161 162 // flush all group 163 for _, lg := range c.group { 164 c.flush(lg) 165 } 166 } 167 168 // Destroy destroy connection writer and close tcp listener. 169 func (c *aliLSWriter) Destroy() { 170 } 171 172 func (c *aliLSWriter) flush(lg *LogGroup) { 173 174 c.lock.Lock() 175 defer c.lock.Unlock() 176 err := c.store.PutLogs(lg) 177 if err != nil { 178 return 179 } 180 181 lg.Logs = make([]*Log, 0, c.FlushWhen) 182 } 183 184 func init() { 185 logs.Register(logs.AdapterAliLS, NewAliLS) 186 }