github.com/portworx/kvdb@v0.0.0-20241107215734-a185a966f535/wrappers/kv_log.go (about) 1 package wrappers 2 3 import ( 4 "fmt" 5 "os" 6 "time" 7 8 "github.com/portworx/kvdb" 9 "github.com/sirupsen/logrus" 10 ) 11 12 const ( 13 opType = "operation" 14 errString = "error" 15 output = "output" 16 defaultLogPath = "kvdb_audit.log" 17 ) 18 19 type kvBaseWrapper struct { 20 // name is the name of this wrapper 21 name kvdb.WrapperName 22 // wrappedKvdb is the Kvdb wrapped by this wrapper 23 wrappedKvdb kvdb.Kvdb 24 } 25 26 func (b *kvBaseWrapper) WrapperName() kvdb.WrapperName { 27 return b.name 28 } 29 30 func (b *kvBaseWrapper) WrappedKvdb() kvdb.Kvdb { 31 return b.wrappedKvdb 32 } 33 34 func (b *kvBaseWrapper) Removed() { 35 } 36 37 func (b *kvBaseWrapper) SetWrappedKvdb(kvdb kvdb.Kvdb) error { 38 b.wrappedKvdb = kvdb 39 return nil 40 } 41 42 type logKvWrapper struct { 43 kvBaseWrapper 44 logger *logrus.Logger 45 fd *os.File 46 } 47 48 func (b *logKvWrapper) Removed() { 49 b.logger.SetOutput(os.Stdout) 50 if b.fd != nil { 51 b.fd.Close() 52 b.fd = nil 53 } 54 } 55 56 // New constructs a new kvdb.Kvdb. 57 func NewLogWrapper( 58 kv kvdb.Kvdb, 59 options map[string]string, 60 ) (kvdb.Kvdb, error) { 61 logrus.Infof("creating kvdb logging wrapper, options: %v", options) 62 wrapper := &logKvWrapper{ 63 kvBaseWrapper{ 64 name: kvdb.Wrapper_Log, 65 wrappedKvdb: kv, 66 }, 67 nil, 68 nil, 69 } 70 71 path, ok := options[kvdb.LogPathOption] 72 if !ok { 73 path = defaultLogPath 74 } 75 file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) 76 if err != nil { 77 return nil, fmt.Errorf("failed to open/create log at %s: %v", path, err) 78 } 79 wrapper.fd = file 80 wrapper.logger = logrus.New() 81 wrapper.logger.SetFormatter(&logrus.TextFormatter{}) 82 wrapper.logger.SetOutput(file) 83 wrapper.logger.SetLevel(logrus.InfoLevel) 84 return wrapper, nil 85 } 86 87 func (k *logKvWrapper) String() string { 88 return k.wrappedKvdb.String() 89 } 90 91 func (k *logKvWrapper) Capabilities() int { 92 return k.wrappedKvdb.Capabilities() 93 } 94 95 func (k *logKvWrapper) Get(key string) (*kvdb.KVPair, error) { 96 pair, err := k.wrappedKvdb.Get(key) 97 k.logger.WithFields(logrus.Fields{ 98 opType: "Get", 99 output: pair, 100 errString: err, 101 }).Info() 102 return pair, err 103 } 104 105 func (k *logKvWrapper) Snapshot(prefixes []string, consistent bool) (kvdb.Kvdb, uint64, error) { 106 kv, version, err := k.wrappedKvdb.Snapshot(prefixes, consistent) 107 k.logger.WithFields(logrus.Fields{ 108 opType: "Snapshot", 109 errString: err, 110 }).Info() 111 return kv, version, err 112 } 113 114 func (k *logKvWrapper) Put( 115 key string, 116 value interface{}, 117 ttl uint64, 118 ) (*kvdb.KVPair, error) { 119 pair, err := k.wrappedKvdb.Put(key, value, ttl) 120 k.logger.WithFields(logrus.Fields{ 121 opType: "Put", 122 output: pair, 123 errString: err, 124 }).Info() 125 return pair, err 126 } 127 128 func (k *logKvWrapper) GetVal(key string, v interface{}) (*kvdb.KVPair, error) { 129 pair, err := k.wrappedKvdb.GetVal(key, v) 130 k.logger.WithFields(logrus.Fields{ 131 opType: "GetValue", 132 output: pair, 133 errString: err, 134 }).Info() 135 return pair, err 136 } 137 138 func (k *logKvWrapper) Create( 139 key string, 140 value interface{}, 141 ttl uint64, 142 ) (*kvdb.KVPair, error) { 143 pair, err := k.wrappedKvdb.Create(key, value, ttl) 144 k.logger.WithFields(logrus.Fields{ 145 opType: "Create", 146 output: pair, 147 errString: err, 148 }).Info() 149 return pair, err 150 } 151 152 func (k *logKvWrapper) Update( 153 key string, 154 value interface{}, 155 ttl uint64, 156 ) (*kvdb.KVPair, error) { 157 pair, err := k.wrappedKvdb.Update(key, value, ttl) 158 k.logger.WithFields(logrus.Fields{ 159 opType: "Update", 160 output: pair, 161 errString: err, 162 }).Info() 163 return pair, err 164 } 165 166 func (k *logKvWrapper) Enumerate(prefix string) (kvdb.KVPairs, error) { 167 pairs, err := k.wrappedKvdb.Enumerate(prefix) 168 k.logger.WithFields(logrus.Fields{ 169 opType: "Enumerate", 170 "length": len(pairs), 171 errString: err, 172 }).Info() 173 return pairs, err 174 } 175 176 func (k *logKvWrapper) Delete(key string) (*kvdb.KVPair, error) { 177 pair, err := k.wrappedKvdb.Delete(key) 178 k.logger.WithFields(logrus.Fields{ 179 opType: "Delete", 180 output: pair, 181 errString: err, 182 }).Info() 183 return pair, err 184 } 185 186 func (k *logKvWrapper) DeleteTree(prefix string) error { 187 err := k.wrappedKvdb.DeleteTree(prefix) 188 k.logger.WithFields(logrus.Fields{ 189 opType: "DeleteTree", 190 errString: err, 191 }).Info() 192 return err 193 } 194 195 func (k *logKvWrapper) Keys(prefix, sep string) ([]string, error) { 196 keys, err := k.wrappedKvdb.Keys(prefix, sep) 197 k.logger.WithFields(logrus.Fields{ 198 opType: "Keys", 199 "length": len(keys), 200 errString: err, 201 }).Info() 202 return keys, err 203 } 204 205 func (k *logKvWrapper) CompareAndSet( 206 kvp *kvdb.KVPair, 207 flags kvdb.KVFlags, 208 prevValue []byte, 209 ) (*kvdb.KVPair, error) { 210 pair, err := k.wrappedKvdb.CompareAndSet(kvp, flags, prevValue) 211 k.logger.WithFields(logrus.Fields{ 212 opType: "CompareAndSet", 213 output: pair, 214 errString: err, 215 }).Info() 216 return pair, err 217 } 218 219 func (k *logKvWrapper) CompareAndDelete( 220 kvp *kvdb.KVPair, 221 flags kvdb.KVFlags, 222 ) (*kvdb.KVPair, error) { 223 pair, err := k.wrappedKvdb.CompareAndDelete(kvp, flags) 224 k.logger.WithFields(logrus.Fields{ 225 opType: "CompareAndDelete", 226 output: pair, 227 errString: err, 228 }).Info() 229 return pair, err 230 } 231 232 func (k *logKvWrapper) WatchKey( 233 key string, 234 waitIndex uint64, 235 opaque interface{}, 236 cb kvdb.WatchCB, 237 ) error { 238 err := k.wrappedKvdb.WatchKey(key, waitIndex, opaque, cb) 239 k.logger.WithFields(logrus.Fields{ 240 opType: "WatchKey", 241 errString: err, 242 }).Info() 243 return err 244 } 245 246 func (k *logKvWrapper) WatchTree( 247 prefix string, 248 waitIndex uint64, 249 opaque interface{}, 250 cb kvdb.WatchCB, 251 ) error { 252 err := k.wrappedKvdb.WatchTree(prefix, waitIndex, opaque, cb) 253 k.logger.WithFields(logrus.Fields{ 254 opType: "WatchTree", 255 errString: err, 256 }).Info() 257 return err 258 } 259 260 func (k *logKvWrapper) Compact( 261 index uint64, 262 ) error { 263 err := k.wrappedKvdb.Compact(index) 264 k.logger.WithFields(logrus.Fields{ 265 opType: "Compact", 266 errString: err, 267 }).Info() 268 return err 269 } 270 271 func (k *logKvWrapper) Lock(key string) (*kvdb.KVPair, error) { 272 pair, err := k.wrappedKvdb.Lock(key) 273 k.logger.WithFields(logrus.Fields{ 274 opType: "Lock", 275 output: pair, 276 errString: err, 277 }).Info() 278 return pair, err 279 } 280 281 func (k *logKvWrapper) LockWithID( 282 key string, 283 lockerID string, 284 ) (*kvdb.KVPair, error) { 285 pair, err := k.wrappedKvdb.LockWithID(key, lockerID) 286 k.logger.WithFields(logrus.Fields{ 287 opType: "LockWithID", 288 output: pair, 289 errString: err, 290 }).Info() 291 return pair, err 292 } 293 294 func (k *logKvWrapper) IsKeyLocked(key string) (bool, string, error) { 295 return k.wrappedKvdb.IsKeyLocked(key) 296 } 297 298 func (k *logKvWrapper) LockWithTimeout( 299 key string, 300 lockerID string, 301 lockTryDuration time.Duration, 302 lockHoldDuration time.Duration, 303 ) (*kvdb.KVPair, error) { 304 pair, err := k.wrappedKvdb.LockWithTimeout(key, lockerID, lockTryDuration, lockHoldDuration) 305 k.logger.WithFields(logrus.Fields{ 306 opType: "LockWithTimeout", 307 output: pair, 308 errString: err, 309 }).Info() 310 return pair, err 311 } 312 313 func (k *logKvWrapper) Unlock(kvp *kvdb.KVPair) error { 314 err := k.wrappedKvdb.Unlock(kvp) 315 k.logger.WithFields(logrus.Fields{ 316 opType: "Unlock", 317 errString: err, 318 }).Info() 319 return err 320 } 321 322 func (k *logKvWrapper) EnumerateWithSelect( 323 prefix string, 324 enumerateSelect kvdb.EnumerateSelect, 325 copySelect kvdb.CopySelect, 326 ) ([]interface{}, error) { 327 vals, err := k.wrappedKvdb.EnumerateWithSelect(prefix, enumerateSelect, copySelect) 328 k.logger.WithFields(logrus.Fields{ 329 opType: "EnumerateWithSelect", 330 "length": len(vals), 331 errString: err, 332 }).Info() 333 return vals, err 334 } 335 336 func (k *logKvWrapper) EnumerateKVPWithSelect( 337 prefix string, 338 enumerateSelect kvdb.EnumerateKVPSelect, 339 copySelect kvdb.CopyKVPSelect, 340 ) (kvdb.KVPairs, error) { 341 vals, err := k.wrappedKvdb.EnumerateKVPWithSelect(prefix, enumerateSelect, copySelect) 342 k.logger.WithFields(logrus.Fields{ 343 opType: "EnumerateKVPWithSelect", 344 "length": len(vals), 345 errString: err, 346 }).Info() 347 return vals, err 348 } 349 350 func (k *logKvWrapper) GetWithCopy( 351 key string, 352 copySelect kvdb.CopySelect, 353 ) (interface{}, error) { 354 pair, err := k.wrappedKvdb.GetWithCopy(key, copySelect) 355 k.logger.WithFields(logrus.Fields{ 356 opType: "GetWithCopy", 357 output: pair, 358 errString: err, 359 }).Info() 360 return pair, err 361 } 362 363 func (k *logKvWrapper) TxNew() (kvdb.Tx, error) { 364 tx, err := k.wrappedKvdb.TxNew() 365 k.logger.WithFields(logrus.Fields{ 366 opType: "Snapshot", 367 errString: err, 368 }).Info() 369 return tx, err 370 } 371 372 func (k *logKvWrapper) SnapPut(snapKvp *kvdb.KVPair) (*kvdb.KVPair, error) { 373 pair, err := k.wrappedKvdb.SnapPut(snapKvp) 374 k.logger.WithFields(logrus.Fields{ 375 opType: "SnapPut", 376 output: pair, 377 errString: err, 378 }).Info() 379 return pair, err 380 } 381 382 func (k *logKvWrapper) AddUser(username string, password string) error { 383 err := k.wrappedKvdb.AddUser(username, password) 384 k.logger.WithFields(logrus.Fields{ 385 opType: "AddUser", 386 errString: err, 387 }).Info() 388 return err 389 } 390 391 func (k *logKvWrapper) RemoveUser(username string) error { 392 err := k.wrappedKvdb.RemoveUser(username) 393 k.logger.WithFields(logrus.Fields{ 394 opType: "RemoveUser", 395 errString: err, 396 }).Info() 397 return err 398 } 399 400 func (k *logKvWrapper) GrantUserAccess( 401 username string, 402 permType kvdb.PermissionType, 403 subtree string, 404 ) error { 405 err := k.wrappedKvdb.GrantUserAccess(username, permType, subtree) 406 k.logger.WithFields(logrus.Fields{ 407 opType: "GrantUserAccess", 408 errString: err, 409 }).Info() 410 return err 411 } 412 413 func (k *logKvWrapper) RevokeUsersAccess( 414 username string, 415 permType kvdb.PermissionType, 416 subtree string, 417 ) error { 418 err := k.wrappedKvdb.RevokeUsersAccess(username, permType, subtree) 419 k.logger.WithFields(logrus.Fields{ 420 opType: "RevokeUsersAccess", 421 errString: err, 422 }).Info() 423 return err 424 } 425 426 func (k *logKvWrapper) SetFatalCb(f kvdb.FatalErrorCB) { 427 k.wrappedKvdb.SetFatalCb(f) 428 } 429 430 func (k *logKvWrapper) SetLockHoldDuration(timeout time.Duration) { 431 k.wrappedKvdb.SetLockHoldDuration(timeout) 432 } 433 434 func (k *logKvWrapper) GetLockTryDuration() time.Duration { 435 return k.wrappedKvdb.GetLockTryDuration() 436 } 437 438 func (k *logKvWrapper) GetLockHoldDuration() time.Duration { 439 return k.wrappedKvdb.GetLockHoldDuration() 440 } 441 442 func (k *logKvWrapper) Serialize() ([]byte, error) { 443 return k.wrappedKvdb.Serialize() 444 } 445 446 func (k *logKvWrapper) Deserialize(b []byte) (kvdb.KVPairs, error) { 447 return k.wrappedKvdb.Deserialize(b) 448 } 449 450 func (k *logKvWrapper) AddMember(nodeIP, nodePeerPort, nodeName string) (map[string][]string, error) { 451 members, err := k.wrappedKvdb.AddMember(nodeIP, nodePeerPort, nodeName) 452 k.logger.WithFields(logrus.Fields{ 453 opType: "AddMember", 454 output: members, 455 errString: err, 456 }).Info() 457 return members, err 458 } 459 460 func (k *logKvWrapper) AddLearner(nodeIP, nodePeerPort, nodeName string) (map[string][]string, error) { 461 members, err := k.wrappedKvdb.AddLearner(nodeIP, nodePeerPort, nodeName) 462 k.logger.WithFields(logrus.Fields{ 463 opType: "AddLearner", 464 output: members, 465 errString: err, 466 }).Info() 467 return members, err 468 } 469 470 func (k *logKvWrapper) RemoveMember(nodeName, nodeIP string) error { 471 err := k.wrappedKvdb.RemoveMember(nodeName, nodeIP) 472 k.logger.WithFields(logrus.Fields{ 473 opType: "RemoveMember", 474 errString: err, 475 }).Info() 476 return err 477 } 478 479 func (k *logKvWrapper) RemoveMemberByID(removeMemberID uint64) error { 480 err := k.wrappedKvdb.RemoveMemberByID(removeMemberID) 481 k.logger.WithFields(logrus.Fields{ 482 opType: "RemoveMemberByID", 483 errString: err, 484 }).Info() 485 return err 486 } 487 488 func (k *logKvWrapper) UpdateMember(nodeIP, nodePeerPort, nodeName string) (map[string][]string, error) { 489 members, err := k.wrappedKvdb.UpdateMember(nodeIP, nodePeerPort, nodeName) 490 k.logger.WithFields(logrus.Fields{ 491 opType: "UpdateMember", 492 output: members, 493 errString: err, 494 }).Info() 495 return members, err 496 } 497 498 func (k *logKvWrapper) ListMembers() (map[uint64]*kvdb.MemberInfo, error) { 499 members, err := k.wrappedKvdb.ListMembers() 500 k.logger.WithFields(logrus.Fields{ 501 opType: "ListMembers", 502 output: members, 503 errString: err, 504 }).Info() 505 return members, err 506 } 507 508 func (k *logKvWrapper) SetEndpoints(endpoints []string) error { 509 err := k.wrappedKvdb.SetEndpoints(endpoints) 510 k.logger.WithFields(logrus.Fields{ 511 opType: "SetEndpoints", 512 errString: err, 513 }).Info() 514 return err 515 } 516 517 func (k *logKvWrapper) GetEndpoints() []string { 518 endpoints := k.wrappedKvdb.GetEndpoints() 519 k.logger.WithFields(logrus.Fields{ 520 opType: "GetEndpoints", 521 output: endpoints, 522 }).Info() 523 return endpoints 524 } 525 526 func (k *logKvWrapper) Defragment(endpoint string, timeout int) error { 527 return k.wrappedKvdb.Defragment(endpoint, timeout) 528 }