github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/log/table.go (about) 1 package log 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/ydb-platform/ydb-go-sdk/v3/internal/kv" 8 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 9 "github.com/ydb-platform/ydb-go-sdk/v3/retry" 10 "github.com/ydb-platform/ydb-go-sdk/v3/trace" 11 ) 12 13 // Table makes trace.Table with logging events from details 14 func Table(l Logger, d trace.Detailer, opts ...Option) (t trace.Table) { 15 return internalTable(wrapLogger(l, opts...), d) 16 } 17 18 //nolint:gocyclo,funlen 19 func internalTable(l *wrapper, d trace.Detailer) (t trace.Table) { 20 return trace.Table{ 21 OnInit: func(info trace.TableInitStartInfo) func(trace.TableInitDoneInfo) { 22 if d.Details()&trace.TableEvents == 0 { 23 return nil 24 } 25 ctx := with(*info.Context, TRACE, "ydb", "table", "init") 26 l.Log(ctx, "start") 27 start := time.Now() 28 29 return func(info trace.TableInitDoneInfo) { 30 l.Log(WithLevel(ctx, INFO), "done", 31 kv.Latency(start), 32 kv.Int("size_max", info.Limit), 33 ) 34 } 35 }, 36 OnClose: func(info trace.TableCloseStartInfo) func(trace.TableCloseDoneInfo) { 37 if d.Details()&trace.TableEvents == 0 { 38 return nil 39 } 40 ctx := with(*info.Context, TRACE, "ydb", "table", "close") 41 l.Log(ctx, "start") 42 start := time.Now() 43 44 return func(info trace.TableCloseDoneInfo) { 45 if info.Error == nil { 46 l.Log(WithLevel(ctx, INFO), "done", 47 kv.Latency(start), 48 ) 49 } else { 50 l.Log(WithLevel(ctx, ERROR), "failed", 51 kv.Latency(start), 52 kv.Error(info.Error), 53 kv.Version(), 54 ) 55 } 56 } 57 }, 58 OnDo: func( 59 info trace.TableDoStartInfo, 60 ) func( 61 trace.TableDoDoneInfo, 62 ) { 63 if d.Details()&trace.TablePoolAPIEvents == 0 { 64 return nil 65 } 66 ctx := with(*info.Context, TRACE, "ydb", "table", "do") 67 idempotent := info.Idempotent 68 label := info.Label 69 l.Log(ctx, "start", 70 kv.Bool("idempotent", idempotent), 71 kv.String("label", label), 72 ) 73 start := time.Now() 74 75 return func(info trace.TableDoDoneInfo) { 76 if info.Error == nil { 77 l.Log(ctx, "done", 78 kv.Latency(start), 79 kv.Bool("idempotent", idempotent), 80 kv.String("label", label), 81 kv.Int("attempts", info.Attempts), 82 ) 83 } else { 84 lvl := ERROR 85 if !xerrors.IsYdb(info.Error) { 86 lvl = DEBUG 87 } 88 m := retry.Check(info.Error) 89 l.Log(WithLevel(ctx, lvl), "done", 90 kv.Latency(start), 91 kv.Bool("idempotent", idempotent), 92 kv.String("label", label), 93 kv.Int("attempts", info.Attempts), 94 kv.Error(info.Error), 95 kv.Bool("retryable", m.MustRetry(idempotent)), 96 kv.Int64("code", m.StatusCode()), 97 kv.Bool("deleteSession", m.IsRetryObjectValid()), 98 kv.Version(), 99 ) 100 } 101 } 102 }, 103 OnDoTx: func( 104 info trace.TableDoTxStartInfo, 105 ) func( 106 trace.TableDoTxDoneInfo, 107 ) { 108 if d.Details()&trace.TablePoolAPIEvents == 0 { 109 return nil 110 } 111 ctx := with(*info.Context, TRACE, "ydb", "table", "do", "tx") 112 idempotent := info.Idempotent 113 label := info.Label 114 l.Log(ctx, "start", 115 kv.Bool("idempotent", idempotent), 116 kv.String("label", label), 117 ) 118 start := time.Now() 119 120 return func(info trace.TableDoTxDoneInfo) { 121 if info.Error == nil { 122 l.Log(ctx, "done", 123 kv.Latency(start), 124 kv.Bool("idempotent", idempotent), 125 kv.String("label", label), 126 kv.Int("attempts", info.Attempts), 127 ) 128 } else { 129 lvl := WARN 130 if !xerrors.IsYdb(info.Error) { 131 lvl = DEBUG 132 } 133 m := retry.Check(info.Error) 134 l.Log(WithLevel(ctx, lvl), "done", 135 kv.Latency(start), 136 kv.Bool("idempotent", idempotent), 137 kv.String("label", label), 138 kv.Int("attempts", info.Attempts), 139 kv.Error(info.Error), 140 kv.Bool("retryable", m.MustRetry(idempotent)), 141 kv.Int64("code", m.StatusCode()), 142 kv.Bool("deleteSession", m.IsRetryObjectValid()), 143 kv.Version(), 144 ) 145 } 146 } 147 }, 148 OnCreateSession: func( 149 info trace.TableCreateSessionStartInfo, 150 ) func( 151 trace.TableCreateSessionDoneInfo, 152 ) { 153 if d.Details()&trace.TablePoolAPIEvents == 0 { 154 return nil 155 } 156 ctx := with(*info.Context, TRACE, "ydb", "table", "create", "session") 157 l.Log(ctx, "start") 158 start := time.Now() 159 160 return func(info trace.TableCreateSessionDoneInfo) { 161 if info.Error == nil { 162 l.Log(ctx, "done", 163 kv.Latency(start), 164 kv.Int("attempts", info.Attempts), 165 kv.String("session_id", info.Session.ID()), 166 kv.String("session_status", info.Session.Status()), 167 ) 168 } else { 169 l.Log(WithLevel(ctx, ERROR), "failed", 170 kv.Latency(start), 171 kv.Int("attempts", info.Attempts), 172 kv.Error(info.Error), 173 kv.Version(), 174 ) 175 } 176 } 177 }, 178 OnSessionNew: func(info trace.TableSessionNewStartInfo) func(trace.TableSessionNewDoneInfo) { 179 if d.Details()&trace.TableSessionEvents == 0 { 180 return nil 181 } 182 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "new") 183 l.Log(ctx, "start") 184 start := time.Now() 185 186 return func(info trace.TableSessionNewDoneInfo) { 187 if info.Error == nil { 188 if info.Session != nil { 189 l.Log(ctx, "done", 190 kv.Latency(start), 191 kv.String("id", info.Session.ID()), 192 ) 193 } else { 194 l.Log(WithLevel(ctx, WARN), "failed", 195 kv.Latency(start), 196 kv.Version(), 197 ) 198 } 199 } else { 200 l.Log(WithLevel(ctx, WARN), "failed", 201 kv.Latency(start), 202 kv.Error(info.Error), 203 kv.Version(), 204 ) 205 } 206 } 207 }, 208 OnSessionDelete: func(info trace.TableSessionDeleteStartInfo) func(trace.TableSessionDeleteDoneInfo) { 209 if d.Details()&trace.TableSessionEvents == 0 { 210 return nil 211 } 212 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "delete") 213 session := info.Session 214 l.Log(ctx, "start", 215 kv.String("id", info.Session.ID()), 216 kv.String("status", info.Session.Status()), 217 ) 218 start := time.Now() 219 220 return func(info trace.TableSessionDeleteDoneInfo) { 221 if info.Error == nil { 222 l.Log(ctx, "done", 223 kv.Latency(start), 224 kv.String("id", session.ID()), 225 kv.String("status", session.Status()), 226 ) 227 } else { 228 l.Log(WithLevel(ctx, WARN), "failed", 229 kv.Latency(start), 230 kv.String("id", session.ID()), 231 kv.String("status", session.Status()), 232 kv.Error(info.Error), 233 kv.Version(), 234 ) 235 } 236 } 237 }, 238 OnSessionKeepAlive: func(info trace.TableKeepAliveStartInfo) func(trace.TableKeepAliveDoneInfo) { 239 if d.Details()&trace.TableSessionEvents == 0 { 240 return nil 241 } 242 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "keep", "alive") 243 session := info.Session 244 l.Log(ctx, "start", 245 kv.String("id", session.ID()), 246 kv.String("status", session.Status()), 247 ) 248 start := time.Now() 249 250 return func(info trace.TableKeepAliveDoneInfo) { 251 if info.Error == nil { 252 l.Log(ctx, "done", 253 kv.Latency(start), 254 kv.String("id", session.ID()), 255 kv.String("status", session.Status()), 256 ) 257 } else { 258 l.Log(WithLevel(ctx, WARN), "failed", 259 kv.Latency(start), 260 kv.String("id", session.ID()), 261 kv.String("status", session.Status()), 262 kv.Error(info.Error), 263 kv.Version(), 264 ) 265 } 266 } 267 }, 268 OnSessionQueryPrepare: func( 269 info trace.TablePrepareDataQueryStartInfo, 270 ) func( 271 trace.TablePrepareDataQueryDoneInfo, 272 ) { 273 if d.Details()&trace.TableSessionQueryInvokeEvents == 0 { 274 return nil 275 } 276 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "query", "prepare") 277 session := info.Session 278 query := info.Query 279 l.Log(ctx, "start", 280 appendFieldByCondition(l.logQuery, 281 kv.String("query", info.Query), 282 kv.String("id", session.ID()), 283 kv.String("status", session.Status()), 284 )..., 285 ) 286 start := time.Now() 287 288 return func(info trace.TablePrepareDataQueryDoneInfo) { 289 if info.Error == nil { 290 l.Log(ctx, "done", 291 appendFieldByCondition(l.logQuery, 292 kv.Stringer("result", info.Result), 293 appendFieldByCondition(l.logQuery, 294 kv.String("query", query), 295 kv.String("id", session.ID()), 296 kv.String("status", session.Status()), 297 kv.Latency(start), 298 )..., 299 )..., 300 ) 301 } else { 302 l.Log(WithLevel(ctx, ERROR), "failed", 303 appendFieldByCondition(l.logQuery, 304 kv.String("query", query), 305 kv.Error(info.Error), 306 kv.String("id", session.ID()), 307 kv.String("status", session.Status()), 308 kv.Latency(start), 309 kv.Version(), 310 )..., 311 ) 312 } 313 } 314 }, 315 OnSessionQueryExecute: func( 316 info trace.TableExecuteDataQueryStartInfo, 317 ) func( 318 trace.TableExecuteDataQueryDoneInfo, 319 ) { 320 if d.Details()&trace.TableSessionQueryInvokeEvents == 0 { 321 return nil 322 } 323 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "query", "execute") 324 session := info.Session 325 query := info.Query 326 l.Log(ctx, "start", 327 appendFieldByCondition(l.logQuery, 328 kv.Stringer("query", info.Query), 329 kv.String("id", session.ID()), 330 kv.String("status", session.Status()), 331 )..., 332 ) 333 start := time.Now() 334 335 return func(info trace.TableExecuteDataQueryDoneInfo) { 336 if info.Error == nil { 337 tx := info.Tx 338 l.Log(ctx, "done", 339 appendFieldByCondition(l.logQuery, 340 kv.Stringer("query", query), 341 kv.String("id", session.ID()), 342 kv.String("tx", tx.ID()), 343 kv.String("status", session.Status()), 344 kv.Bool("prepared", info.Prepared), 345 kv.NamedError("result_err", info.Result.Err()), 346 kv.Latency(start), 347 )..., 348 ) 349 } else { 350 l.Log(WithLevel(ctx, ERROR), "failed", 351 appendFieldByCondition(l.logQuery, 352 kv.Stringer("query", query), 353 kv.Error(info.Error), 354 kv.String("id", session.ID()), 355 kv.String("status", session.Status()), 356 kv.Bool("prepared", info.Prepared), 357 kv.Latency(start), 358 kv.Version(), 359 )..., 360 ) 361 } 362 } 363 }, 364 OnSessionQueryStreamExecute: func( 365 info trace.TableSessionQueryStreamExecuteStartInfo, 366 ) func( 367 trace.TableSessionQueryStreamExecuteDoneInfo, 368 ) { 369 if d.Details()&trace.TableSessionQueryStreamEvents == 0 { 370 return nil 371 } 372 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "query", "stream", "execute") 373 session := info.Session 374 query := info.Query 375 l.Log(ctx, "start", 376 appendFieldByCondition(l.logQuery, 377 kv.Stringer("query", info.Query), 378 kv.String("id", session.ID()), 379 kv.String("status", session.Status()), 380 )..., 381 ) 382 start := time.Now() 383 384 return func(info trace.TableSessionQueryStreamExecuteDoneInfo) { 385 if info.Error == nil { 386 l.Log(ctx, "done", 387 appendFieldByCondition(l.logQuery, 388 kv.Stringer("query", query), 389 kv.Error(info.Error), 390 kv.String("id", session.ID()), 391 kv.String("status", session.Status()), 392 kv.Latency(start), 393 )..., 394 ) 395 } else { 396 l.Log(WithLevel(ctx, ERROR), "failed", 397 appendFieldByCondition(l.logQuery, 398 kv.Stringer("query", query), 399 kv.Error(info.Error), 400 kv.String("id", session.ID()), 401 kv.String("status", session.Status()), 402 kv.Latency(start), 403 kv.Version(), 404 )..., 405 ) 406 } 407 } 408 }, 409 OnSessionQueryStreamRead: func( 410 info trace.TableSessionQueryStreamReadStartInfo, 411 ) func( 412 trace.TableSessionQueryStreamReadDoneInfo, 413 ) { 414 if d.Details()&trace.TableSessionQueryStreamEvents == 0 { 415 return nil 416 } 417 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "query", "stream", "read") 418 session := info.Session 419 l.Log(ctx, "start", 420 kv.String("id", session.ID()), 421 kv.String("status", session.Status()), 422 ) 423 start := time.Now() 424 425 return func(info trace.TableSessionQueryStreamReadDoneInfo) { 426 if info.Error == nil { 427 l.Log(ctx, "done", 428 kv.Latency(start), 429 kv.String("id", session.ID()), 430 kv.String("status", session.Status()), 431 ) 432 } else { 433 l.Log(WithLevel(ctx, ERROR), "failed", 434 kv.Latency(start), 435 kv.String("id", session.ID()), 436 kv.String("status", session.Status()), 437 kv.Error(info.Error), 438 kv.Version(), 439 ) 440 } 441 } 442 }, 443 OnTxBegin: func( 444 info trace.TableTxBeginStartInfo, 445 ) func( 446 trace.TableTxBeginDoneInfo, 447 ) { 448 if d.Details()&trace.TableSessionTransactionEvents == 0 { 449 return nil 450 } 451 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "tx", "begin") 452 session := info.Session 453 l.Log(ctx, "start", 454 kv.String("id", session.ID()), 455 kv.String("status", session.Status()), 456 ) 457 start := time.Now() 458 459 return func(info trace.TableTxBeginDoneInfo) { 460 if info.Error == nil { 461 l.Log(ctx, "done", 462 kv.Latency(start), 463 kv.String("id", session.ID()), 464 kv.String("status", session.Status()), 465 kv.String("tx", info.Tx.ID()), 466 ) 467 } else { 468 l.Log(WithLevel(ctx, WARN), "failed", 469 kv.Latency(start), 470 kv.String("id", session.ID()), 471 kv.String("status", session.Status()), 472 kv.Error(info.Error), 473 kv.Version(), 474 ) 475 } 476 } 477 }, 478 OnTxCommit: func(info trace.TableTxCommitStartInfo) func(trace.TableTxCommitDoneInfo) { 479 if d.Details()&trace.TableSessionTransactionEvents == 0 { 480 return nil 481 } 482 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "tx", "commit") 483 session := info.Session 484 tx := info.Tx 485 l.Log(ctx, "start", 486 kv.String("id", session.ID()), 487 kv.String("status", session.Status()), 488 kv.String("tx", info.Tx.ID()), 489 ) 490 start := time.Now() 491 492 return func(info trace.TableTxCommitDoneInfo) { 493 if info.Error == nil { 494 l.Log(ctx, "done", 495 kv.Latency(start), 496 kv.String("id", session.ID()), 497 kv.String("status", session.Status()), 498 kv.String("tx", tx.ID()), 499 ) 500 } else { 501 l.Log(WithLevel(ctx, ERROR), "failed", 502 kv.Latency(start), 503 kv.String("id", session.ID()), 504 kv.String("status", session.Status()), 505 kv.String("tx", tx.ID()), 506 kv.Error(info.Error), 507 kv.Version(), 508 ) 509 } 510 } 511 }, 512 OnTxRollback: func( 513 info trace.TableTxRollbackStartInfo, 514 ) func( 515 trace.TableTxRollbackDoneInfo, 516 ) { 517 if d.Details()&trace.TableSessionTransactionEvents == 0 { 518 return nil 519 } 520 ctx := with(*info.Context, TRACE, "ydb", "table", "session", "tx", "rollback") 521 session := info.Session 522 tx := info.Tx 523 l.Log(ctx, "start", 524 kv.String("id", session.ID()), 525 kv.String("status", session.Status()), 526 kv.String("tx", tx.ID()), 527 ) 528 start := time.Now() 529 530 return func(info trace.TableTxRollbackDoneInfo) { 531 if info.Error == nil { 532 l.Log(ctx, "done", 533 kv.Latency(start), 534 kv.String("id", session.ID()), 535 kv.String("status", session.Status()), 536 kv.String("tx", tx.ID()), 537 ) 538 } else { 539 l.Log(WithLevel(ctx, ERROR), "failed", 540 kv.Latency(start), 541 kv.String("id", session.ID()), 542 kv.String("status", session.Status()), 543 kv.String("tx", tx.ID()), 544 kv.Error(info.Error), 545 kv.Version(), 546 ) 547 } 548 } 549 }, 550 OnPoolPut: func(info trace.TablePoolPutStartInfo) func(trace.TablePoolPutDoneInfo) { 551 if d.Details()&trace.TablePoolAPIEvents == 0 { 552 return nil 553 } 554 ctx := with(*info.Context, TRACE, "ydb", "table", "pool", "put") 555 session := info.Session 556 l.Log(ctx, "start", 557 kv.String("id", session.ID()), 558 kv.String("status", session.Status()), 559 ) 560 start := time.Now() 561 562 return func(info trace.TablePoolPutDoneInfo) { 563 if info.Error == nil { 564 l.Log(ctx, "done", 565 kv.Latency(start), 566 kv.String("id", session.ID()), 567 kv.String("status", session.Status()), 568 ) 569 } else { 570 l.Log(WithLevel(ctx, ERROR), "failed", 571 kv.Latency(start), 572 kv.String("id", session.ID()), 573 kv.String("status", session.Status()), 574 kv.Error(info.Error), 575 kv.Version(), 576 ) 577 } 578 } 579 }, 580 OnPoolGet: func(info trace.TablePoolGetStartInfo) func(trace.TablePoolGetDoneInfo) { 581 if d.Details()&trace.TablePoolAPIEvents == 0 { 582 return nil 583 } 584 ctx := with(*info.Context, TRACE, "ydb", "table", "pool", "get") 585 l.Log(ctx, "start") 586 start := time.Now() 587 588 return func(info trace.TablePoolGetDoneInfo) { 589 if info.Error == nil { 590 session := info.Session 591 l.Log(ctx, "done", 592 kv.Latency(start), 593 kv.String("id", session.ID()), 594 kv.String("status", session.Status()), 595 kv.Int("attempts", info.Attempts), 596 ) 597 } else { 598 l.Log(WithLevel(ctx, WARN), "failed", 599 kv.Latency(start), 600 kv.Int("attempts", info.Attempts), 601 kv.Error(info.Error), 602 kv.Version(), 603 ) 604 } 605 } 606 }, 607 OnPoolStateChange: func(info trace.TablePoolStateChangeInfo) { 608 if d.Details()&trace.TablePoolLifeCycleEvents == 0 { 609 return 610 } 611 ctx := with(context.Background(), TRACE, "ydb", "table", "pool", "state", "change") 612 l.Log(WithLevel(ctx, DEBUG), "", 613 kv.Int("limit", info.Limit), 614 kv.Int("index", info.Index), 615 kv.Int("idle", info.Idle), 616 kv.Int("wait", info.Wait), 617 kv.Int("create_in_progress", info.CreateInProgress), 618 ) 619 }, 620 OnSessionBulkUpsert: nil, 621 OnSessionQueryExplain: nil, 622 OnTxExecute: nil, 623 OnTxExecuteStatement: nil, 624 OnPoolWith: nil, 625 } 626 }