go.mercari.io/datastore@v1.8.2/dsmiddleware/dslog/dslog.go (about) 1 package dslog 2 3 import ( 4 "context" 5 "strings" 6 "sync" 7 8 "go.mercari.io/datastore" 9 ) 10 11 var _ datastore.Middleware = &logger{} 12 13 // NewLogger returns with specified logger function. 14 func NewLogger(prefix string, logf func(ctx context.Context, format string, args ...interface{})) datastore.Middleware { 15 return &logger{Prefix: prefix, Logf: logf, counter: 1} 16 } 17 18 type contextTx struct{} 19 20 type logger struct { 21 Prefix string 22 Logf func(ctx context.Context, format string, args ...interface{}) 23 24 m sync.Mutex 25 counter int 26 } 27 28 type txPutEntity struct { 29 Index int 30 Key datastore.Key 31 PendingKey datastore.PendingKey 32 } 33 34 func (l *logger) KeysToString(keys []datastore.Key) string { 35 keyStrings := make([]string, 0, len(keys)) 36 for _, key := range keys { 37 keyStrings = append(keyStrings, key.String()) 38 } 39 40 return strings.Join(keyStrings, ", ") 41 } 42 43 func (l *logger) AllocateIDs(info *datastore.MiddlewareInfo, keys []datastore.Key) ([]datastore.Key, error) { 44 l.m.Lock() 45 cnt := l.counter 46 l.counter++ 47 l.m.Unlock() 48 49 l.Logf(info.Context, l.Prefix+"AllocateIDs #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 50 51 keys, err := info.Next.AllocateIDs(info, keys) 52 53 if err == nil { 54 l.Logf(info.Context, l.Prefix+"AllocateIDs #%d, keys=[%s]", cnt, l.KeysToString(keys)) 55 } else { 56 l.Logf(info.Context, l.Prefix+"AllocateIDs #%d, err=%s", cnt, err.Error()) 57 } 58 59 return keys, err 60 } 61 62 func (l *logger) PutMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) ([]datastore.Key, error) { 63 l.m.Lock() 64 cnt := l.counter 65 l.counter++ 66 l.m.Unlock() 67 68 l.Logf(info.Context, l.Prefix+"PutMultiWithoutTx #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 69 70 keys, err := info.Next.PutMultiWithoutTx(info, keys, psList) 71 72 if err == nil { 73 l.Logf(info.Context, l.Prefix+"PutMultiWithoutTx #%d, keys=[%s]", cnt, l.KeysToString(keys)) 74 } else { 75 l.Logf(info.Context, l.Prefix+"PutMultiWithoutTx #%d, err=%s", cnt, err.Error()) 76 } 77 78 return keys, err 79 } 80 81 func (l *logger) PutMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) ([]datastore.PendingKey, error) { 82 l.m.Lock() 83 cnt := l.counter 84 l.counter++ 85 l.m.Unlock() 86 87 l.Logf(info.Context, l.Prefix+"PutMultiWithTx #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 88 89 pKeys, err := info.Next.PutMultiWithTx(info, keys, psList) 90 if err != nil { 91 l.Logf(info.Context, l.Prefix+"PutMultiWithTx #%d, err=%s", cnt, err.Error()) 92 } 93 if len(keys) != len(pKeys) { 94 l.Logf(info.Context, l.Prefix+"PutMultiWithTx #%d, keys length mismatch len(keys)=%d, len(pKeys)=%d", cnt, len(keys), len(pKeys)) 95 return pKeys, err 96 } 97 98 lgTxPutMap, ok := info.Context.Value(contextTx{}).(map[*logger]map[datastore.Transaction][]*txPutEntity) 99 if !ok { 100 lgTxPutMap = make(map[*logger]map[datastore.Transaction][]*txPutEntity) 101 info.Context = context.WithValue(info.Context, contextTx{}, lgTxPutMap) 102 } 103 txPutMap, ok := lgTxPutMap[l] 104 if !ok { 105 txPutMap = make(map[datastore.Transaction][]*txPutEntity) 106 lgTxPutMap[l] = txPutMap 107 } 108 putLogs := txPutMap[info.Transaction] 109 for idx, key := range keys { 110 if key.Incomplete() { 111 putLogs = append(putLogs, &txPutEntity{PendingKey: pKeys[idx]}) 112 } else { 113 putLogs = append(putLogs, &txPutEntity{Key: key}) 114 } 115 } 116 lgTxPutMap[l][info.Transaction] = putLogs 117 118 return pKeys, err 119 } 120 121 func (l *logger) GetMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) error { 122 l.m.Lock() 123 cnt := l.counter 124 l.counter++ 125 l.m.Unlock() 126 127 l.Logf(info.Context, l.Prefix+"GetMultiWithoutTx #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 128 129 err := info.Next.GetMultiWithoutTx(info, keys, psList) 130 131 if err != nil { 132 l.Logf(info.Context, l.Prefix+"GetMultiWithoutTx #%d, err=%s", cnt, err.Error()) 133 } 134 135 return err 136 } 137 138 func (l *logger) GetMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) error { 139 l.m.Lock() 140 cnt := l.counter 141 l.counter++ 142 l.m.Unlock() 143 144 l.Logf(info.Context, l.Prefix+"GetMultiWithTx #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 145 146 err := info.Next.GetMultiWithTx(info, keys, psList) 147 148 if err != nil { 149 l.Logf(info.Context, l.Prefix+"GetMultiWithTx #%d, err=%s", cnt, err.Error()) 150 } 151 152 return err 153 } 154 155 func (l *logger) DeleteMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key) error { 156 l.m.Lock() 157 cnt := l.counter 158 l.counter++ 159 l.m.Unlock() 160 161 l.Logf(info.Context, l.Prefix+"DeleteMultiWithoutTx #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 162 163 err := info.Next.DeleteMultiWithoutTx(info, keys) 164 165 if err != nil { 166 l.Logf(info.Context, l.Prefix+"DeleteMultiWithoutTx #%d, err=%s", cnt, err.Error()) 167 } 168 169 return err 170 } 171 172 func (l *logger) DeleteMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key) error { 173 l.m.Lock() 174 cnt := l.counter 175 l.counter++ 176 l.m.Unlock() 177 178 l.Logf(info.Context, l.Prefix+"DeleteMultiWithTx #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 179 180 err := info.Next.DeleteMultiWithTx(info, keys) 181 182 if err != nil { 183 l.Logf(info.Context, l.Prefix+"DeleteMultiWithTx #%d, err=%s", cnt, err.Error()) 184 } 185 186 return err 187 } 188 189 func (l *logger) PostCommit(info *datastore.MiddlewareInfo, tx datastore.Transaction, commit datastore.Commit) error { 190 l.m.Lock() 191 cnt := l.counter 192 l.counter++ 193 l.m.Unlock() 194 195 lgTxPutMap, ok := info.Context.Value(contextTx{}).(map[*logger]map[datastore.Transaction][]*txPutEntity) 196 if ok { 197 txPutMap, ok := lgTxPutMap[l] 198 if ok { 199 putLogs := txPutMap[info.Transaction] 200 delete(txPutMap, info.Transaction) 201 keys := make([]datastore.Key, 0, len(putLogs)) 202 for _, putLog := range putLogs { 203 if putLog.Key != nil { 204 keys = append(keys, putLog.Key) 205 continue 206 } 207 208 key := commit.Key(putLog.PendingKey) 209 keys = append(keys, key) 210 } 211 212 l.Logf(info.Context, l.Prefix+"PostCommit #%d Put keys=[%s]", cnt, l.KeysToString(keys)) 213 214 delete(txPutMap, info.Transaction) 215 216 } else { 217 l.Logf(info.Context, l.Prefix+"PostCommit #%d put log not contains in ctx", cnt) 218 } 219 220 if len(txPutMap) == 0 { 221 delete(lgTxPutMap, l) 222 } 223 224 } else { 225 l.Logf(info.Context, l.Prefix+"PostCommit #%d put log not contains in ctx", cnt) 226 } 227 228 return info.Next.PostCommit(info, tx, commit) 229 } 230 231 func (l *logger) PostRollback(info *datastore.MiddlewareInfo, tx datastore.Transaction) error { 232 l.m.Lock() 233 cnt := l.counter 234 l.counter++ 235 l.m.Unlock() 236 237 l.Logf(info.Context, l.Prefix+"PostRollback #%d", cnt) 238 239 return info.Next.PostRollback(info, tx) 240 } 241 242 func (l *logger) Run(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump) datastore.Iterator { 243 l.m.Lock() 244 cnt := l.counter 245 l.counter++ 246 l.m.Unlock() 247 248 l.Logf(info.Context, l.Prefix+"Run #%d, q=%s", cnt, qDump.String()) 249 250 return info.Next.Run(info, q, qDump) 251 } 252 253 func (l *logger) GetAll(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump, psList *[]datastore.PropertyList) ([]datastore.Key, error) { 254 l.m.Lock() 255 cnt := l.counter 256 l.counter++ 257 l.m.Unlock() 258 259 l.Logf(info.Context, l.Prefix+"GetAll #%d, q=%s", cnt, qDump.String()) 260 261 keys, err := info.Next.GetAll(info, q, qDump, psList) 262 263 if err == nil { 264 l.Logf(info.Context, l.Prefix+"GetAll #%d, len(keys)=%d, keys=[%s]", cnt, len(keys), l.KeysToString(keys)) 265 } else { 266 l.Logf(info.Context, l.Prefix+"GetAll #%d, err=%s", cnt, err.Error()) 267 } 268 269 return keys, err 270 } 271 272 func (l *logger) Next(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump, iter datastore.Iterator, ps *datastore.PropertyList) (datastore.Key, error) { 273 l.m.Lock() 274 cnt := l.counter 275 l.counter++ 276 l.m.Unlock() 277 278 l.Logf(info.Context, l.Prefix+"Next #%d, q=%s", cnt, qDump.String()) 279 280 key, err := info.Next.Next(info, q, qDump, iter, ps) 281 282 if err == nil { 283 l.Logf(info.Context, l.Prefix+"Next #%d, key=%s", cnt, key.String()) 284 } else { 285 l.Logf(info.Context, l.Prefix+"Next #%d, err=%s", cnt, err.Error()) 286 } 287 288 return key, err 289 } 290 291 func (l *logger) Count(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump) (int, error) { 292 l.m.Lock() 293 cnt := l.counter 294 l.counter++ 295 l.m.Unlock() 296 297 l.Logf(info.Context, l.Prefix+"Count #%d, q=%s", cnt, qDump.String()) 298 299 ret, err := info.Next.Count(info, q, qDump) 300 301 if err == nil { 302 l.Logf(info.Context, l.Prefix+"Count #%d, ret=%d", cnt, ret) 303 } else { 304 l.Logf(info.Context, l.Prefix+"Count #%d, err=%s", cnt, err.Error()) 305 } 306 307 return ret, err 308 }