github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/log/sql.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/retry"
     9  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    10  )
    11  
    12  // DatabaseSQL makes trace.DatabaseSQL with logging events from details
    13  func DatabaseSQL(l Logger, d trace.Detailer, opts ...Option) (t trace.DatabaseSQL) {
    14  	return internalDatabaseSQL(wrapLogger(l, opts...), d)
    15  }
    16  
    17  //nolint:funlen
    18  func internalDatabaseSQL(l *wrapper, d trace.Detailer) (t trace.DatabaseSQL) {
    19  	t.OnConnectorConnect = func(
    20  		info trace.DatabaseSQLConnectorConnectStartInfo,
    21  	) func(
    22  		trace.DatabaseSQLConnectorConnectDoneInfo,
    23  	) {
    24  		if d.Details()&trace.DatabaseSQLConnectorEvents == 0 {
    25  			return nil
    26  		}
    27  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "connector", "connect")
    28  		l.Log(ctx, "start")
    29  		start := time.Now()
    30  
    31  		return func(info trace.DatabaseSQLConnectorConnectDoneInfo) {
    32  			if info.Error == nil {
    33  				l.Log(WithLevel(ctx, DEBUG), "connected",
    34  					kv.Latency(start),
    35  					kv.String("session_id", info.Session.ID()),
    36  					kv.String("session_status", info.Session.Status()),
    37  				)
    38  			} else {
    39  				l.Log(WithLevel(ctx, ERROR), "failed",
    40  					kv.Error(info.Error),
    41  					kv.Latency(start),
    42  					kv.Version(),
    43  				)
    44  			}
    45  		}
    46  	}
    47  
    48  	t.OnConnPing = func(info trace.DatabaseSQLConnPingStartInfo) func(trace.DatabaseSQLConnPingDoneInfo) {
    49  		if d.Details()&trace.DatabaseSQLConnEvents == 0 {
    50  			return nil
    51  		}
    52  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "conn", "ping")
    53  		l.Log(ctx, "start")
    54  		start := time.Now()
    55  
    56  		return func(info trace.DatabaseSQLConnPingDoneInfo) {
    57  			if info.Error == nil {
    58  				l.Log(ctx, "done",
    59  					kv.Latency(start),
    60  				)
    61  			} else {
    62  				l.Log(WithLevel(ctx, ERROR), "failed",
    63  					kv.Error(info.Error),
    64  					kv.Latency(start),
    65  					kv.Version(),
    66  				)
    67  			}
    68  		}
    69  	}
    70  	t.OnConnClose = func(info trace.DatabaseSQLConnCloseStartInfo) func(trace.DatabaseSQLConnCloseDoneInfo) {
    71  		if d.Details()&trace.DatabaseSQLConnEvents == 0 {
    72  			return nil
    73  		}
    74  		ctx := with(context.Background(), TRACE, "ydb", "database", "sql", "conn", "close")
    75  		l.Log(ctx, "start")
    76  		start := time.Now()
    77  
    78  		return func(info trace.DatabaseSQLConnCloseDoneInfo) {
    79  			if info.Error == nil {
    80  				l.Log(ctx, "done",
    81  					kv.Latency(start),
    82  				)
    83  			} else {
    84  				l.Log(WithLevel(ctx, WARN), "failed",
    85  					kv.Error(info.Error),
    86  					kv.Latency(start),
    87  					kv.Version(),
    88  				)
    89  			}
    90  		}
    91  	}
    92  	t.OnConnBegin = func(info trace.DatabaseSQLConnBeginStartInfo) func(trace.DatabaseSQLConnBeginDoneInfo) {
    93  		if d.Details()&trace.DatabaseSQLConnEvents == 0 {
    94  			return nil
    95  		}
    96  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "conn", "begin", "tx")
    97  		l.Log(ctx, "start")
    98  		start := time.Now()
    99  
   100  		return func(info trace.DatabaseSQLConnBeginDoneInfo) {
   101  			if info.Error == nil {
   102  				l.Log(ctx, "done",
   103  					kv.Latency(start),
   104  				)
   105  			} else {
   106  				l.Log(WithLevel(ctx, ERROR), "failed",
   107  					kv.Error(info.Error),
   108  					kv.Latency(start),
   109  					kv.Version(),
   110  				)
   111  			}
   112  		}
   113  	}
   114  	t.OnConnPrepare = func(info trace.DatabaseSQLConnPrepareStartInfo) func(trace.DatabaseSQLConnPrepareDoneInfo) {
   115  		if d.Details()&trace.DatabaseSQLConnEvents == 0 {
   116  			return nil
   117  		}
   118  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "conn", "prepare", "stmt")
   119  		l.Log(ctx, "start",
   120  			appendFieldByCondition(l.logQuery,
   121  				kv.String("query", info.Query),
   122  			)...,
   123  		)
   124  		query := info.Query
   125  		start := time.Now()
   126  
   127  		return func(info trace.DatabaseSQLConnPrepareDoneInfo) {
   128  			if info.Error == nil {
   129  				l.Log(ctx, "done",
   130  					kv.Latency(start),
   131  				)
   132  			} else {
   133  				l.Log(WithLevel(ctx, ERROR), "failed",
   134  					appendFieldByCondition(l.logQuery,
   135  						kv.String("query", query),
   136  						kv.Error(info.Error),
   137  						kv.Latency(start),
   138  						kv.Version(),
   139  					)...,
   140  				)
   141  			}
   142  		}
   143  	}
   144  	t.OnConnExec = func(info trace.DatabaseSQLConnExecStartInfo) func(trace.DatabaseSQLConnExecDoneInfo) {
   145  		if d.Details()&trace.DatabaseSQLConnEvents == 0 {
   146  			return nil
   147  		}
   148  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "conn", "exec")
   149  		l.Log(ctx, "start",
   150  			appendFieldByCondition(l.logQuery,
   151  				kv.String("query", info.Query),
   152  			)...,
   153  		)
   154  		query := info.Query
   155  		idempotent := info.Idempotent
   156  		start := time.Now()
   157  
   158  		return func(info trace.DatabaseSQLConnExecDoneInfo) {
   159  			if info.Error == nil {
   160  				l.Log(ctx, "done",
   161  					kv.Latency(start),
   162  				)
   163  			} else {
   164  				m := retry.Check(info.Error)
   165  				l.Log(WithLevel(ctx, ERROR), "failed",
   166  					appendFieldByCondition(l.logQuery,
   167  						kv.String("query", query),
   168  						kv.Bool("retryable", m.MustRetry(idempotent)),
   169  						kv.Int64("code", m.StatusCode()),
   170  						kv.Bool("deleteSession", m.IsRetryObjectValid()),
   171  						kv.Error(info.Error),
   172  						kv.Latency(start),
   173  						kv.Version(),
   174  					)...,
   175  				)
   176  			}
   177  		}
   178  	}
   179  	t.OnConnQuery = func(info trace.DatabaseSQLConnQueryStartInfo) func(trace.DatabaseSQLConnQueryDoneInfo) {
   180  		if d.Details()&trace.DatabaseSQLConnEvents == 0 {
   181  			return nil
   182  		}
   183  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "conn", "query")
   184  		l.Log(ctx, "start",
   185  			appendFieldByCondition(l.logQuery,
   186  				kv.String("query", info.Query),
   187  			)...,
   188  		)
   189  		query := info.Query
   190  		idempotent := info.Idempotent
   191  		start := time.Now()
   192  
   193  		return func(info trace.DatabaseSQLConnQueryDoneInfo) {
   194  			if info.Error == nil {
   195  				l.Log(ctx, "done",
   196  					kv.Latency(start),
   197  				)
   198  			} else {
   199  				m := retry.Check(info.Error)
   200  				l.Log(WithLevel(ctx, ERROR), "failed",
   201  					appendFieldByCondition(l.logQuery,
   202  						kv.String("query", query),
   203  						kv.Bool("retryable", m.MustRetry(idempotent)),
   204  						kv.Int64("code", m.StatusCode()),
   205  						kv.Bool("deleteSession", m.IsRetryObjectValid()),
   206  						kv.Error(info.Error),
   207  						kv.Latency(start),
   208  						kv.Version(),
   209  					)...,
   210  				)
   211  			}
   212  		}
   213  	}
   214  	t.OnTxCommit = func(info trace.DatabaseSQLTxCommitStartInfo) func(trace.DatabaseSQLTxCommitDoneInfo) {
   215  		if d.Details()&trace.DatabaseSQLTxEvents == 0 {
   216  			return nil
   217  		}
   218  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "tx", "commit")
   219  		l.Log(ctx, "start")
   220  		start := time.Now()
   221  
   222  		return func(info trace.DatabaseSQLTxCommitDoneInfo) {
   223  			if info.Error == nil {
   224  				l.Log(ctx, "committed",
   225  					kv.Latency(start),
   226  				)
   227  			} else {
   228  				l.Log(WithLevel(ctx, ERROR), "failed",
   229  					kv.Error(info.Error),
   230  					kv.Latency(start),
   231  					kv.Version(),
   232  				)
   233  			}
   234  		}
   235  	}
   236  	t.OnTxRollback = func(info trace.DatabaseSQLTxRollbackStartInfo) func(trace.DatabaseSQLTxRollbackDoneInfo) {
   237  		if d.Details()&trace.DatabaseSQLTxEvents == 0 {
   238  			return nil
   239  		}
   240  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "tx", "rollback")
   241  		l.Log(ctx, "start")
   242  		start := time.Now()
   243  
   244  		return func(info trace.DatabaseSQLTxRollbackDoneInfo) {
   245  			if info.Error == nil {
   246  				l.Log(ctx, "done",
   247  					kv.Latency(start),
   248  				)
   249  			} else {
   250  				l.Log(WithLevel(ctx, WARN), "failed",
   251  					kv.Error(info.Error),
   252  					kv.Latency(start),
   253  					kv.Version(),
   254  				)
   255  			}
   256  		}
   257  	}
   258  	t.OnStmtClose = func(info trace.DatabaseSQLStmtCloseStartInfo) func(trace.DatabaseSQLStmtCloseDoneInfo) {
   259  		if d.Details()&trace.DatabaseSQLStmtEvents == 0 {
   260  			return nil
   261  		}
   262  		ctx := with(context.Background(), TRACE, "ydb", "database", "sql", "stmt", "close")
   263  		l.Log(ctx, "start")
   264  		start := time.Now()
   265  
   266  		return func(info trace.DatabaseSQLStmtCloseDoneInfo) {
   267  			if info.Error == nil {
   268  				l.Log(ctx, "closed",
   269  					kv.Latency(start),
   270  				)
   271  			} else {
   272  				l.Log(WithLevel(ctx, ERROR), "close failed",
   273  					kv.Error(info.Error),
   274  					kv.Latency(start),
   275  					kv.Version(),
   276  				)
   277  			}
   278  		}
   279  	}
   280  	t.OnStmtExec = func(info trace.DatabaseSQLStmtExecStartInfo) func(trace.DatabaseSQLStmtExecDoneInfo) {
   281  		if d.Details()&trace.DatabaseSQLStmtEvents == 0 {
   282  			return nil
   283  		}
   284  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "stmt", "exec")
   285  		l.Log(ctx, "start",
   286  			appendFieldByCondition(l.logQuery,
   287  				kv.String("query", info.Query),
   288  			)...,
   289  		)
   290  		query := info.Query
   291  		start := time.Now()
   292  
   293  		return func(info trace.DatabaseSQLStmtExecDoneInfo) {
   294  			if info.Error == nil {
   295  				l.Log(ctx, "done",
   296  					kv.Error(info.Error),
   297  					kv.Latency(start),
   298  				)
   299  			} else {
   300  				l.Log(WithLevel(ctx, ERROR), "failed",
   301  					appendFieldByCondition(l.logQuery,
   302  						kv.String("query", query),
   303  						kv.Error(info.Error),
   304  						kv.Latency(start),
   305  						kv.Version(),
   306  					)...,
   307  				)
   308  			}
   309  		}
   310  	}
   311  	t.OnStmtQuery = func(info trace.DatabaseSQLStmtQueryStartInfo) func(trace.DatabaseSQLStmtQueryDoneInfo) {
   312  		if d.Details()&trace.DatabaseSQLStmtEvents == 0 {
   313  			return nil
   314  		}
   315  		ctx := with(*info.Context, TRACE, "ydb", "database", "sql", "stmt", "query")
   316  		l.Log(ctx, "start",
   317  			appendFieldByCondition(l.logQuery,
   318  				kv.String("query", info.Query),
   319  			)...,
   320  		)
   321  		query := info.Query
   322  		start := time.Now()
   323  
   324  		return func(info trace.DatabaseSQLStmtQueryDoneInfo) {
   325  			if info.Error == nil {
   326  				l.Log(ctx, "done",
   327  					kv.Latency(start),
   328  				)
   329  			} else {
   330  				l.Log(WithLevel(ctx, ERROR), "failed",
   331  					appendFieldByCondition(l.logQuery,
   332  						kv.String("query", query),
   333  						kv.Error(info.Error),
   334  						kv.Latency(start),
   335  						kv.Version(),
   336  					)...,
   337  				)
   338  			}
   339  		}
   340  	}
   341  
   342  	return t
   343  }