github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/log/sql.go (about)

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