github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/log/topic.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/trace"
     9  )
    10  
    11  // Topic returns trace.Topic with logging events from details
    12  func Topic(l Logger, d trace.Detailer, opts ...Option) (t trace.Topic) {
    13  	return internalTopic(wrapLogger(l, opts...), d)
    14  }
    15  
    16  //nolint:gocyclo,funlen
    17  func internalTopic(l Logger, d trace.Detailer) (t trace.Topic) {
    18  	t.OnReaderReconnect = func(
    19  		info trace.TopicReaderReconnectStartInfo,
    20  	) func(doneInfo trace.TopicReaderReconnectDoneInfo) {
    21  		if d.Details()&trace.TopicReaderStreamLifeCycleEvents == 0 {
    22  			return nil
    23  		}
    24  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "reconnect")
    25  		start := time.Now()
    26  		l.Log(ctx, "start")
    27  
    28  		return func(doneInfo trace.TopicReaderReconnectDoneInfo) {
    29  			l.Log(WithLevel(ctx, INFO), "reconnected",
    30  				kv.NamedError("reason", info.Reason),
    31  				kv.Latency(start),
    32  			)
    33  		}
    34  	}
    35  	t.OnReaderReconnectRequest = func(info trace.TopicReaderReconnectRequestInfo) {
    36  		if d.Details()&trace.TopicReaderStreamLifeCycleEvents == 0 {
    37  			return
    38  		}
    39  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "reconnect", "request")
    40  		l.Log(ctx, "start",
    41  			kv.NamedError("reason", info.Reason),
    42  			kv.Bool("was_sent", info.WasSent),
    43  		)
    44  	}
    45  	t.OnReaderPartitionReadStartResponse = func(
    46  		info trace.TopicReaderPartitionReadStartResponseStartInfo,
    47  	) func(stopInfo trace.TopicReaderPartitionReadStartResponseDoneInfo) {
    48  		if d.Details()&trace.TopicReaderPartitionEvents == 0 {
    49  			return nil
    50  		}
    51  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "partition", "read", "start", "response")
    52  		start := time.Now()
    53  		l.Log(ctx, "start",
    54  			kv.String("topic", info.Topic),
    55  			kv.String("reader_connection_id", info.ReaderConnectionID),
    56  			kv.Int64("partition_id", info.PartitionID),
    57  			kv.Int64("partition_session_id", info.PartitionSessionID),
    58  		)
    59  
    60  		return func(doneInfo trace.TopicReaderPartitionReadStartResponseDoneInfo) {
    61  			fields := []Field{
    62  				kv.String("topic", info.Topic),
    63  				kv.String("reader_connection_id", info.ReaderConnectionID),
    64  				kv.Int64("partition_id", info.PartitionID),
    65  				kv.Int64("partition_session_id", info.PartitionSessionID),
    66  				kv.Latency(start),
    67  			}
    68  			if doneInfo.CommitOffset != nil {
    69  				fields = append(fields,
    70  					kv.Int64("commit_offset", *doneInfo.CommitOffset),
    71  				)
    72  			}
    73  			if doneInfo.ReadOffset != nil {
    74  				fields = append(fields,
    75  					kv.Int64("read_offset", *doneInfo.ReadOffset),
    76  				)
    77  			}
    78  			if doneInfo.Error == nil {
    79  				l.Log(WithLevel(ctx, INFO), "read partition response completed", fields...)
    80  			} else {
    81  				l.Log(WithLevel(ctx, WARN), "read partition response completed",
    82  					append(fields,
    83  						kv.Error(doneInfo.Error),
    84  						kv.Version(),
    85  					)...,
    86  				)
    87  			}
    88  		}
    89  	}
    90  	t.OnReaderPartitionReadStopResponse = func(
    91  		info trace.TopicReaderPartitionReadStopResponseStartInfo,
    92  	) func(trace.TopicReaderPartitionReadStopResponseDoneInfo) {
    93  		if d.Details()&trace.TopicReaderPartitionEvents == 0 {
    94  			return nil
    95  		}
    96  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "partition", "read", "stop", "response")
    97  		start := time.Now()
    98  		l.Log(ctx, "start",
    99  			kv.String("reader_connection_id", info.ReaderConnectionID),
   100  			kv.String("topic", info.Topic),
   101  			kv.Int64("partition_id", info.PartitionID),
   102  			kv.Int64("partition_session_id", info.PartitionSessionID),
   103  			kv.Int64("committed_offset", info.CommittedOffset),
   104  			kv.Bool("graceful", info.Graceful))
   105  
   106  		return func(doneInfo trace.TopicReaderPartitionReadStopResponseDoneInfo) {
   107  			fields := []Field{
   108  				kv.String("reader_connection_id", info.ReaderConnectionID),
   109  				kv.String("topic", info.Topic),
   110  				kv.Int64("partition_id", info.PartitionID),
   111  				kv.Int64("partition_session_id", info.PartitionSessionID),
   112  				kv.Int64("committed_offset", info.CommittedOffset),
   113  				kv.Bool("graceful", info.Graceful),
   114  				kv.Latency(start),
   115  			}
   116  			if doneInfo.Error == nil {
   117  				l.Log(WithLevel(ctx, INFO), "reader partition stopped", fields...)
   118  			} else {
   119  				l.Log(WithLevel(ctx, WARN), "reader partition stopped",
   120  					append(fields,
   121  						kv.Error(doneInfo.Error),
   122  						kv.Version(),
   123  					)...,
   124  				)
   125  			}
   126  		}
   127  	}
   128  	t.OnReaderCommit = func(info trace.TopicReaderCommitStartInfo) func(doneInfo trace.TopicReaderCommitDoneInfo) {
   129  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   130  			return nil
   131  		}
   132  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "commit")
   133  		start := time.Now()
   134  		l.Log(ctx, "start",
   135  			kv.String("topic", info.Topic),
   136  			kv.Int64("partition_id", info.PartitionID),
   137  			kv.Int64("partition_session_id", info.PartitionSessionID),
   138  			kv.Int64("commit_start_offset", info.StartOffset),
   139  			kv.Int64("commit_end_offset", info.EndOffset),
   140  		)
   141  
   142  		return func(doneInfo trace.TopicReaderCommitDoneInfo) {
   143  			fields := []Field{
   144  				kv.String("topic", info.Topic),
   145  				kv.Int64("partition_id", info.PartitionID),
   146  				kv.Int64("partition_session_id", info.PartitionSessionID),
   147  				kv.Int64("commit_start_offset", info.StartOffset),
   148  				kv.Int64("commit_end_offset", info.EndOffset),
   149  				kv.Latency(start),
   150  			}
   151  			if doneInfo.Error == nil {
   152  				l.Log(ctx, "committed", fields...)
   153  			} else {
   154  				l.Log(WithLevel(ctx, WARN), "committed",
   155  					append(fields,
   156  						kv.Error(doneInfo.Error),
   157  						kv.Version(),
   158  					)...,
   159  				)
   160  			}
   161  		}
   162  	}
   163  	t.OnReaderSendCommitMessage = func(
   164  		info trace.TopicReaderSendCommitMessageStartInfo,
   165  	) func(trace.TopicReaderSendCommitMessageDoneInfo) {
   166  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   167  			return nil
   168  		}
   169  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "send", "commit", "message")
   170  		start := time.Now()
   171  
   172  		commitInfo := info.CommitsInfo.GetCommitsInfo()
   173  		for i := range commitInfo {
   174  			l.Log(ctx, "start",
   175  				kv.String("topic", commitInfo[i].Topic),
   176  				kv.Int64("partitions_id", commitInfo[i].PartitionID),
   177  				kv.Int64("partitions_session_id", commitInfo[i].PartitionSessionID),
   178  				kv.Int64("commit_start_offset", commitInfo[i].StartOffset),
   179  				kv.Int64("commit_end_offset", commitInfo[i].EndOffset),
   180  			)
   181  		}
   182  
   183  		return func(doneInfo trace.TopicReaderSendCommitMessageDoneInfo) {
   184  			for i := range commitInfo {
   185  				fields := []Field{
   186  					kv.String("topic", commitInfo[i].Topic),
   187  					kv.Int64("partitions_id", commitInfo[i].PartitionID),
   188  					kv.Int64("partitions_session_id", commitInfo[i].PartitionSessionID),
   189  					kv.Int64("commit_start_offset", commitInfo[i].StartOffset),
   190  					kv.Int64("commit_end_offset", commitInfo[i].EndOffset),
   191  					kv.Latency(start),
   192  				}
   193  				if doneInfo.Error == nil {
   194  					l.Log(ctx, "done", fields...)
   195  				} else {
   196  					l.Log(WithLevel(ctx, WARN), "commit message sent",
   197  						append(fields,
   198  							kv.Error(doneInfo.Error),
   199  							kv.Version(),
   200  						)...,
   201  					)
   202  				}
   203  			}
   204  		}
   205  	}
   206  	t.OnReaderCommittedNotify = func(info trace.TopicReaderCommittedNotifyInfo) {
   207  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   208  			return
   209  		}
   210  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "committed", "notify")
   211  		l.Log(ctx, "ack",
   212  			kv.String("reader_connection_id", info.ReaderConnectionID),
   213  			kv.String("topic", info.Topic),
   214  			kv.Int64("partition_id", info.PartitionID),
   215  			kv.Int64("partition_session_id", info.PartitionSessionID),
   216  			kv.Int64("committed_offset", info.CommittedOffset),
   217  		)
   218  	}
   219  	t.OnReaderClose = func(info trace.TopicReaderCloseStartInfo) func(doneInfo trace.TopicReaderCloseDoneInfo) {
   220  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   221  			return nil
   222  		}
   223  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "close")
   224  		start := time.Now()
   225  		l.Log(ctx, "done",
   226  			kv.String("reader_connection_id", info.ReaderConnectionID),
   227  			kv.NamedError("close_reason", info.CloseReason),
   228  		)
   229  
   230  		return func(doneInfo trace.TopicReaderCloseDoneInfo) {
   231  			fields := []Field{
   232  				kv.String("reader_connection_id", info.ReaderConnectionID),
   233  				kv.Latency(start),
   234  			}
   235  			if doneInfo.CloseError == nil {
   236  				l.Log(ctx, "closed", fields...)
   237  			} else {
   238  				l.Log(WithLevel(ctx, WARN), "closed",
   239  					append(fields,
   240  						kv.Error(doneInfo.CloseError),
   241  						kv.Version(),
   242  					)...,
   243  				)
   244  			}
   245  		}
   246  	}
   247  
   248  	t.OnReaderInit = func(info trace.TopicReaderInitStartInfo) func(doneInfo trace.TopicReaderInitDoneInfo) {
   249  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   250  			return nil
   251  		}
   252  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "init")
   253  		start := time.Now()
   254  		l.Log(ctx, "start",
   255  			kv.String("pre_init_reader_connection_id", info.PreInitReaderConnectionID),
   256  			kv.String("consumer", info.InitRequestInfo.GetConsumer()),
   257  			kv.Strings("topics", info.InitRequestInfo.GetTopics()),
   258  		)
   259  
   260  		return func(doneInfo trace.TopicReaderInitDoneInfo) {
   261  			fields := []Field{
   262  				kv.String("pre_init_reader_connection_id", info.PreInitReaderConnectionID),
   263  				kv.String("consumer", info.InitRequestInfo.GetConsumer()),
   264  				kv.Strings("topics", info.InitRequestInfo.GetTopics()),
   265  				kv.Latency(start),
   266  			}
   267  			if doneInfo.Error == nil {
   268  				l.Log(ctx, "topic reader stream initialized", fields...)
   269  			} else {
   270  				l.Log(WithLevel(ctx, WARN), "topic reader stream initialized",
   271  					append(fields,
   272  						kv.Error(doneInfo.Error),
   273  						kv.Version(),
   274  					)...,
   275  				)
   276  			}
   277  		}
   278  	}
   279  	t.OnReaderError = func(info trace.TopicReaderErrorInfo) {
   280  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   281  			return
   282  		}
   283  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "error")
   284  		l.Log(WithLevel(ctx, INFO), "stream error",
   285  			kv.Error(info.Error),
   286  			kv.String("reader_connection_id", info.ReaderConnectionID),
   287  			kv.Version(),
   288  		)
   289  	}
   290  	t.OnReaderUpdateToken = func(
   291  		info trace.OnReadUpdateTokenStartInfo,
   292  	) func(
   293  		updateTokenInfo trace.OnReadUpdateTokenMiddleTokenReceivedInfo,
   294  	) func(doneInfo trace.OnReadStreamUpdateTokenDoneInfo) {
   295  		if d.Details()&trace.TopicReaderStreamEvents == 0 {
   296  			return nil
   297  		}
   298  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "update", "token")
   299  		start := time.Now()
   300  		l.Log(ctx, "token updating...",
   301  			kv.String("reader_connection_id", info.ReaderConnectionID),
   302  		)
   303  
   304  		return func(
   305  			updateTokenInfo trace.OnReadUpdateTokenMiddleTokenReceivedInfo,
   306  		) func(doneInfo trace.OnReadStreamUpdateTokenDoneInfo) {
   307  			if updateTokenInfo.Error == nil {
   308  				l.Log(ctx, "got token",
   309  					kv.String("reader_connection_id", info.ReaderConnectionID),
   310  					kv.Int("token_len", updateTokenInfo.TokenLen),
   311  					kv.Latency(start),
   312  				)
   313  			} else {
   314  				l.Log(WithLevel(ctx, WARN), "got token",
   315  					kv.Error(updateTokenInfo.Error),
   316  					kv.String("reader_connection_id", info.ReaderConnectionID),
   317  					kv.Int("token_len", updateTokenInfo.TokenLen),
   318  					kv.Latency(start),
   319  					kv.Version(),
   320  				)
   321  			}
   322  
   323  			return func(doneInfo trace.OnReadStreamUpdateTokenDoneInfo) {
   324  				if doneInfo.Error == nil {
   325  					l.Log(ctx, "token updated on stream",
   326  						kv.String("reader_connection_id", info.ReaderConnectionID),
   327  						kv.Int("token_len", updateTokenInfo.TokenLen),
   328  						kv.Latency(start),
   329  					)
   330  				} else {
   331  					l.Log(WithLevel(ctx, WARN), "token updated on stream",
   332  						kv.Error(doneInfo.Error),
   333  						kv.String("reader_connection_id", info.ReaderConnectionID),
   334  						kv.Int("token_len", updateTokenInfo.TokenLen),
   335  						kv.Latency(start),
   336  						kv.Version(),
   337  					)
   338  				}
   339  			}
   340  		}
   341  	}
   342  	t.OnReaderSentDataRequest = func(info trace.TopicReaderSentDataRequestInfo) {
   343  		if d.Details()&trace.TopicReaderMessageEvents == 0 {
   344  			return
   345  		}
   346  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "sent", "data", "request")
   347  		l.Log(ctx, "sent data request",
   348  			kv.String("reader_connection_id", info.ReaderConnectionID),
   349  			kv.Int("request_bytes", info.RequestBytes),
   350  			kv.Int("local_capacity", info.LocalBufferSizeAfterSent),
   351  		)
   352  	}
   353  	t.OnReaderReceiveDataResponse = func(
   354  		info trace.TopicReaderReceiveDataResponseStartInfo,
   355  	) func(trace.TopicReaderReceiveDataResponseDoneInfo) {
   356  		if d.Details()&trace.TopicReaderMessageEvents == 0 {
   357  			return nil
   358  		}
   359  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "receive", "data", "response")
   360  		start := time.Now()
   361  		partitionsCount, batchesCount, messagesCount := info.DataResponse.GetPartitionBatchMessagesCounts()
   362  		l.Log(ctx, "data response received, process starting...",
   363  			kv.String("reader_connection_id", info.ReaderConnectionID),
   364  			kv.Int("received_bytes", info.DataResponse.GetBytesSize()),
   365  			kv.Int("local_capacity", info.LocalBufferSizeAfterReceive),
   366  			kv.Int("partitions_count", partitionsCount),
   367  			kv.Int("batches_count", batchesCount),
   368  			kv.Int("messages_count", messagesCount),
   369  		)
   370  
   371  		return func(doneInfo trace.TopicReaderReceiveDataResponseDoneInfo) {
   372  			if doneInfo.Error == nil {
   373  				l.Log(ctx, "data response received and processed",
   374  					kv.String("reader_connection_id", info.ReaderConnectionID),
   375  					kv.Int("received_bytes", info.DataResponse.GetBytesSize()),
   376  					kv.Int("local_capacity", info.LocalBufferSizeAfterReceive),
   377  					kv.Int("partitions_count", partitionsCount),
   378  					kv.Int("batches_count", batchesCount),
   379  					kv.Int("messages_count", messagesCount),
   380  					kv.Latency(start),
   381  				)
   382  			} else {
   383  				l.Log(WithLevel(ctx, WARN), "data response received and processed",
   384  					kv.Error(doneInfo.Error),
   385  					kv.String("reader_connection_id", info.ReaderConnectionID),
   386  					kv.Int("received_bytes", info.DataResponse.GetBytesSize()),
   387  					kv.Int("local_capacity", info.LocalBufferSizeAfterReceive),
   388  					kv.Int("partitions_count", partitionsCount),
   389  					kv.Int("batches_count", batchesCount),
   390  					kv.Int("messages_count", messagesCount),
   391  					kv.Latency(start),
   392  					kv.Version(),
   393  				)
   394  			}
   395  		}
   396  	}
   397  	t.OnReaderReadMessages = func(
   398  		info trace.TopicReaderReadMessagesStartInfo,
   399  	) func(doneInfo trace.TopicReaderReadMessagesDoneInfo) {
   400  		if d.Details()&trace.TopicReaderMessageEvents == 0 {
   401  			return nil
   402  		}
   403  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "read", "messages")
   404  		start := time.Now()
   405  		l.Log(ctx, "read messages called, waiting...",
   406  			kv.Int("min_count", info.MinCount),
   407  			kv.Int("max_count", info.MaxCount),
   408  			kv.Int("local_capacity_before", info.FreeBufferCapacity),
   409  		)
   410  
   411  		return func(doneInfo trace.TopicReaderReadMessagesDoneInfo) {
   412  			if doneInfo.Error == nil {
   413  				l.Log(ctx, "read messages returned",
   414  					kv.Int("min_count", info.MinCount),
   415  					kv.Int("max_count", info.MaxCount),
   416  					kv.Int("local_capacity_before", info.FreeBufferCapacity),
   417  					kv.Latency(start),
   418  				)
   419  			} else {
   420  				l.Log(WithLevel(ctx, WARN), "read messages returned",
   421  					kv.Error(doneInfo.Error),
   422  					kv.Int("min_count", info.MinCount),
   423  					kv.Int("max_count", info.MaxCount),
   424  					kv.Int("local_capacity_before", info.FreeBufferCapacity),
   425  					kv.Latency(start),
   426  					kv.Version(),
   427  				)
   428  			}
   429  		}
   430  	}
   431  	t.OnReaderUnknownGrpcMessage = func(info trace.OnReadUnknownGrpcMessageInfo) {
   432  		if d.Details()&trace.TopicReaderMessageEvents == 0 {
   433  			return
   434  		}
   435  		ctx := with(context.Background(), TRACE, "ydb", "topic", "reader", "unknown", "grpc", "message")
   436  		l.Log(WithLevel(ctx, INFO), "received unknown message",
   437  			kv.Error(info.Error),
   438  			kv.String("reader_connection_id", info.ReaderConnectionID),
   439  		)
   440  	}
   441  
   442  	t.OnReaderPopBatchTx = func(
   443  		startInfo trace.TopicReaderPopBatchTxStartInfo,
   444  	) func(trace.TopicReaderPopBatchTxDoneInfo) {
   445  		if d.Details()&trace.TopicReaderCustomerEvents == 0 {
   446  			return nil
   447  		}
   448  
   449  		start := time.Now()
   450  		ctx := with(*startInfo.Context, TRACE, "ydb", "topic", "reader", "customer", "popbatchtx")
   451  		l.Log(WithLevel(ctx, TRACE), "starting pop batch tx",
   452  			kv.Int64("reader_id", startInfo.ReaderID),
   453  			kv.String("transaction_session_id", startInfo.TransactionSessionID),
   454  			kv.String("transaction_id", startInfo.Tx.ID()),
   455  		)
   456  
   457  		return func(doneInfo trace.TopicReaderPopBatchTxDoneInfo) {
   458  			if doneInfo.Error == nil {
   459  				l.Log(
   460  					WithLevel(ctx, DEBUG), "pop batch done",
   461  					kv.Int64("reader_id", startInfo.ReaderID),
   462  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   463  					kv.String("transaction_id", startInfo.Tx.ID()),
   464  					kv.Int("messaged_count", doneInfo.MessagesCount),
   465  					kv.Int64("start_offset", doneInfo.StartOffset),
   466  					kv.Int64("end_offset", doneInfo.EndOffset),
   467  					kv.Latency(start),
   468  					kv.Version(),
   469  				)
   470  			} else {
   471  				l.Log(
   472  					WithLevel(ctx, WARN), "pop batch failed",
   473  					kv.Int64("reader_id", startInfo.ReaderID),
   474  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   475  					kv.String("transaction_id", startInfo.Tx.ID()),
   476  					kv.Error(doneInfo.Error),
   477  					kv.Latency(start),
   478  					kv.Version(),
   479  				)
   480  			}
   481  		}
   482  	}
   483  
   484  	t.OnReaderStreamPopBatchTx = func(
   485  		startInfo trace.TopicReaderStreamPopBatchTxStartInfo,
   486  	) func(
   487  		trace.TopicReaderStreamPopBatchTxDoneInfo,
   488  	) {
   489  		if d.Details()&trace.TopicReaderTransactionEvents == 0 {
   490  			return nil
   491  		}
   492  
   493  		start := time.Now()
   494  		ctx := with(*startInfo.Context, TRACE, "ydb", "topic", "reader", "transaction", "popbatchtx_on_stream")
   495  		l.Log(WithLevel(ctx, TRACE), "starting pop batch tx",
   496  			kv.Int64("reader_id", startInfo.ReaderID),
   497  			kv.String("reader_connection_id", startInfo.ReaderConnectionID),
   498  			kv.String("transaction_session_id", startInfo.TransactionSessionID),
   499  			kv.String("transaction_id", startInfo.Tx.ID()),
   500  			kv.Version(),
   501  		)
   502  
   503  		return func(doneInfo trace.TopicReaderStreamPopBatchTxDoneInfo) {
   504  			if doneInfo.Error == nil {
   505  				l.Log(
   506  					WithLevel(ctx, DEBUG), "pop batch on stream done",
   507  					kv.Int64("reader_id", startInfo.ReaderID),
   508  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   509  					kv.String("transaction_id", startInfo.Tx.ID()),
   510  					kv.Latency(start),
   511  					kv.Version(),
   512  				)
   513  			} else {
   514  				l.Log(
   515  					WithLevel(ctx, WARN), "pop batch on stream failed",
   516  					kv.Int64("reader_id", startInfo.ReaderID),
   517  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   518  					kv.String("transaction_id", startInfo.Tx.ID()),
   519  					kv.Error(doneInfo.Error),
   520  					kv.Latency(start),
   521  					kv.Version(),
   522  				)
   523  			}
   524  		}
   525  	}
   526  
   527  	t.OnReaderUpdateOffsetsInTransaction = func(
   528  		startInfo trace.TopicReaderOnUpdateOffsetsInTransactionStartInfo,
   529  	) func(
   530  		trace.TopicReaderOnUpdateOffsetsInTransactionDoneInfo,
   531  	) {
   532  		if d.Details()&trace.TopicReaderTransactionEvents == 0 {
   533  			return nil
   534  		}
   535  
   536  		start := time.Now()
   537  		ctx := with(*startInfo.Context, TRACE, "ydb", "topic", "reader", "transaction", "update_offsets")
   538  		l.Log(WithLevel(ctx, TRACE), "starting update offsets in transaction",
   539  			kv.Int64("reader_id", startInfo.ReaderID),
   540  			kv.String("reader_connection_id", startInfo.ReaderConnectionID),
   541  			kv.String("transaction_session_id", startInfo.TransactionSessionID),
   542  			kv.String("transaction_id", startInfo.Tx.ID()),
   543  			kv.Version(),
   544  		)
   545  
   546  		return func(doneInfo trace.TopicReaderOnUpdateOffsetsInTransactionDoneInfo) {
   547  			if doneInfo.Error == nil {
   548  				l.Log(
   549  					WithLevel(ctx, DEBUG), "pop batch on stream done",
   550  					kv.Int64("reader_id", startInfo.ReaderID),
   551  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   552  					kv.String("transaction_id", startInfo.Tx.ID()),
   553  					kv.Latency(start),
   554  					kv.Version(),
   555  				)
   556  			} else {
   557  				l.Log(
   558  					WithLevel(ctx, WARN), "pop batch on stream failed",
   559  					kv.Int64("reader_id", startInfo.ReaderID),
   560  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   561  					kv.String("transaction_id", startInfo.Tx.ID()),
   562  					kv.Error(doneInfo.Error),
   563  					kv.Latency(start),
   564  					kv.Version(),
   565  				)
   566  			}
   567  		}
   568  	}
   569  
   570  	t.OnReaderTransactionRollback = func(
   571  		startInfo trace.TopicReaderTransactionRollbackStartInfo,
   572  	) func(
   573  		trace.TopicReaderTransactionRollbackDoneInfo,
   574  	) {
   575  		if d.Details()&trace.TopicReaderTransactionEvents == 0 {
   576  			return nil
   577  		}
   578  
   579  		start := time.Now()
   580  		ctx := with(*startInfo.Context, TRACE, "ydb", "topic", "reader", "transaction", "update_offsets")
   581  		l.Log(WithLevel(ctx, TRACE), "starting update offsets in transaction",
   582  			kv.Int64("reader_id", startInfo.ReaderID),
   583  			kv.String("reader_connection_id", startInfo.ReaderConnectionID),
   584  			kv.String("transaction_session_id", startInfo.TransactionSessionID),
   585  			kv.String("transaction_id", startInfo.Tx.ID()),
   586  			kv.Version(),
   587  		)
   588  
   589  		return func(doneInfo trace.TopicReaderTransactionRollbackDoneInfo) {
   590  			if doneInfo.RollbackError == nil {
   591  				l.Log(
   592  					WithLevel(ctx, DEBUG), "pop batch on stream done",
   593  					kv.Int64("reader_id", startInfo.ReaderID),
   594  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   595  					kv.String("transaction_id", startInfo.Tx.ID()),
   596  					kv.Latency(start),
   597  					kv.Version(),
   598  				)
   599  			} else {
   600  				l.Log(
   601  					WithLevel(ctx, WARN), "pop batch on stream failed",
   602  					kv.Int64("reader_id", startInfo.ReaderID),
   603  					kv.String("transaction_session_id", startInfo.TransactionSessionID),
   604  					kv.String("transaction_id", startInfo.Tx.ID()),
   605  					kv.Error(doneInfo.RollbackError),
   606  					kv.Latency(start),
   607  					kv.Version(),
   608  				)
   609  			}
   610  		}
   611  	}
   612  
   613  	t.OnReaderTransactionCompleted = func(
   614  		startInfo trace.TopicReaderTransactionCompletedStartInfo,
   615  	) func(
   616  		trace.TopicReaderTransactionCompletedDoneInfo,
   617  	) {
   618  		if d.Details()&trace.TopicReaderTransactionEvents == 0 {
   619  			return nil
   620  		}
   621  
   622  		// expected as very short in memory operation without errors, no need log start separately
   623  		start := time.Now()
   624  
   625  		return func(doneInfo trace.TopicReaderTransactionCompletedDoneInfo) {
   626  			ctx := with(*startInfo.Context, TRACE, "ydb", "topic", "reader", "transaction", "update_offsets")
   627  			l.Log(WithLevel(ctx, TRACE), "starting update offsets in transaction",
   628  				kv.Int64("reader_id", startInfo.ReaderID),
   629  				kv.String("reader_connection_id", startInfo.ReaderConnectionID),
   630  				kv.String("transaction_session_id", startInfo.TransactionSessionID),
   631  				kv.String("transaction_id", startInfo.Tx.ID()),
   632  				kv.Latency(start),
   633  				kv.Version(),
   634  			)
   635  		}
   636  	}
   637  
   638  	///
   639  	/// Topic writer
   640  	///
   641  	t.OnWriterReconnect = func(
   642  		info trace.TopicWriterReconnectStartInfo,
   643  	) func(doneInfo trace.TopicWriterReconnectDoneInfo) {
   644  		if d.Details()&trace.TopicWriterStreamLifeCycleEvents == 0 {
   645  			return nil
   646  		}
   647  		ctx := with(context.Background(), TRACE, "ydb", "topic", "writer", "reconnect")
   648  		start := time.Now()
   649  		l.Log(ctx, "connect to topic writer stream starting...",
   650  			kv.String("topic", info.Topic),
   651  			kv.String("producer_id", info.ProducerID),
   652  			kv.String("writer_instance_id", info.WriterInstanceID),
   653  			kv.Int("attempt", info.Attempt),
   654  		)
   655  
   656  		return func(doneInfo trace.TopicWriterReconnectDoneInfo) {
   657  			if doneInfo.Error == nil {
   658  				l.Log(WithLevel(ctx, DEBUG), "connect to topic writer stream completed",
   659  					kv.String("topic", info.Topic),
   660  					kv.String("producer_id", info.ProducerID),
   661  					kv.String("writer_instance_id", info.WriterInstanceID),
   662  					kv.Int("attempt", info.Attempt),
   663  					kv.Latency(start),
   664  				)
   665  			} else {
   666  				l.Log(WithLevel(ctx, WARN), "connect to topic writer stream completed",
   667  					kv.Error(doneInfo.Error),
   668  					kv.String("topic", info.Topic),
   669  					kv.String("producer_id", info.ProducerID),
   670  					kv.String("writer_instance_id", info.WriterInstanceID),
   671  					kv.Int("attempt", info.Attempt),
   672  					kv.Latency(start),
   673  				)
   674  			}
   675  		}
   676  	}
   677  	t.OnWriterInitStream = func(
   678  		info trace.TopicWriterInitStreamStartInfo,
   679  	) func(doneInfo trace.TopicWriterInitStreamDoneInfo) {
   680  		if d.Details()&trace.TopicWriterStreamLifeCycleEvents == 0 {
   681  			return nil
   682  		}
   683  		ctx := with(context.Background(), TRACE, "ydb", "topic", "writer", "stream", "init")
   684  		start := time.Now()
   685  		l.Log(ctx, "start",
   686  			kv.String("topic", info.Topic),
   687  			kv.String("producer_id", info.ProducerID),
   688  			kv.String("writer_instance_id", info.WriterInstanceID),
   689  		)
   690  
   691  		return func(doneInfo trace.TopicWriterInitStreamDoneInfo) {
   692  			if doneInfo.Error == nil {
   693  				l.Log(WithLevel(ctx, DEBUG), "init stream completed",
   694  					kv.Error(doneInfo.Error),
   695  					kv.String("topic", info.Topic),
   696  					kv.String("producer_id", info.ProducerID),
   697  					kv.String("writer_instance_id", info.WriterInstanceID),
   698  					kv.Latency(start),
   699  					kv.String("session_id", doneInfo.SessionID),
   700  				)
   701  			} else {
   702  				l.Log(WithLevel(ctx, WARN), "init stream completed",
   703  					kv.Error(doneInfo.Error),
   704  					kv.String("topic", info.Topic),
   705  					kv.String("producer_id", info.ProducerID),
   706  					kv.String("writer_instance_id", info.WriterInstanceID),
   707  					kv.Latency(start),
   708  					kv.String("session_id", doneInfo.SessionID),
   709  				)
   710  			}
   711  		}
   712  	}
   713  	t.OnWriterBeforeCommitTransaction = func(
   714  		info trace.TopicOnWriterBeforeCommitTransactionStartInfo,
   715  	) func(trace.TopicOnWriterBeforeCommitTransactionDoneInfo) {
   716  		if d.Details()&trace.TopicWriterStreamLifeCycleEvents == 0 {
   717  			return nil
   718  		}
   719  
   720  		start := time.Now()
   721  
   722  		return func(doneInfo trace.TopicOnWriterBeforeCommitTransactionDoneInfo) {
   723  			ctx := with(*info.Ctx, TRACE, "ydb", "topic", "writer", "beforecommit")
   724  			l.Log(ctx, "wait of flush messages before commit transaction",
   725  				kv.String("kqp_session_id", info.KqpSessionID),
   726  				kv.String("topic_session_id_start", info.TopicSessionID),
   727  				kv.String("topic_session_id_finish", doneInfo.TopicSessionID),
   728  				kv.String("tx_id", info.TransactionID),
   729  				kv.Latency(start),
   730  			)
   731  		}
   732  	}
   733  	t.OnWriterAfterFinishTransaction = func(
   734  		info trace.TopicOnWriterAfterFinishTransactionStartInfo,
   735  	) func(trace.TopicOnWriterAfterFinishTransactionDoneInfo) {
   736  		start := time.Now()
   737  
   738  		return func(doneInfo trace.TopicOnWriterAfterFinishTransactionDoneInfo) {
   739  			ctx := with(context.Background(), TRACE, "ydb", "topic", "writer", "beforecommit")
   740  			l.Log(ctx, "close writer after transaction finished",
   741  				kv.String("kqp_session_id", info.SessionID),
   742  				kv.String("tx_id", info.TransactionID),
   743  				kv.Latency(start),
   744  			)
   745  		}
   746  	}
   747  	t.OnWriterClose = func(info trace.TopicWriterCloseStartInfo) func(doneInfo trace.TopicWriterCloseDoneInfo) {
   748  		if d.Details()&trace.TopicWriterStreamLifeCycleEvents == 0 {
   749  			return nil
   750  		}
   751  		ctx := with(context.Background(), TRACE, "ydb", "topic", "writer", "close")
   752  		start := time.Now()
   753  		l.Log(ctx, "start",
   754  			kv.String("writer_instance_id", info.WriterInstanceID),
   755  			kv.NamedError("reason", info.Reason),
   756  		)
   757  
   758  		return func(doneInfo trace.TopicWriterCloseDoneInfo) {
   759  			if doneInfo.Error == nil {
   760  				l.Log(WithLevel(ctx, DEBUG), "close topic writer completed",
   761  					kv.Error(doneInfo.Error),
   762  					kv.String("writer_instance_id", info.WriterInstanceID),
   763  					kv.NamedError("reason", info.Reason),
   764  					kv.Latency(start),
   765  				)
   766  			} else {
   767  				l.Log(WithLevel(ctx, WARN), "close topic writer completed",
   768  					kv.Error(doneInfo.Error),
   769  					kv.String("writer_instance_id", info.WriterInstanceID),
   770  					kv.NamedError("reason", info.Reason),
   771  					kv.Latency(start),
   772  				)
   773  			}
   774  		}
   775  	}
   776  	t.OnWriterCompressMessages = func(
   777  		info trace.TopicWriterCompressMessagesStartInfo,
   778  	) func(doneInfo trace.TopicWriterCompressMessagesDoneInfo) {
   779  		if d.Details()&trace.TopicWriterStreamEvents == 0 {
   780  			return nil
   781  		}
   782  		ctx := with(context.Background(), TRACE, "ydb", "topic", "writer", "compress", "messages")
   783  		start := time.Now()
   784  		l.Log(ctx, "start",
   785  			kv.String("writer_instance_id", info.WriterInstanceID),
   786  			kv.String("session_id", info.SessionID),
   787  			kv.Any("reason", info.Reason),
   788  			kv.Any("codec", info.Codec),
   789  			kv.Int("messages_count", info.MessagesCount),
   790  			kv.Int64("first_seqno", info.FirstSeqNo),
   791  		)
   792  
   793  		return func(doneInfo trace.TopicWriterCompressMessagesDoneInfo) {
   794  			if doneInfo.Error == nil {
   795  				l.Log(ctx, "compress message completed",
   796  					kv.Error(doneInfo.Error),
   797  					kv.String("writer_instance_id", info.WriterInstanceID),
   798  					kv.String("session_id", info.SessionID),
   799  					kv.Any("reason", info.Reason),
   800  					kv.Any("codec", info.Codec),
   801  					kv.Int("messages_count", info.MessagesCount),
   802  					kv.Int64("first_seqno", info.FirstSeqNo),
   803  					kv.Latency(start),
   804  				)
   805  			} else {
   806  				l.Log(WithLevel(ctx, ERROR), "compress message completed",
   807  					kv.Error(doneInfo.Error),
   808  					kv.String("writer_instance_id", info.WriterInstanceID),
   809  					kv.String("session_id", info.SessionID),
   810  					kv.Any("reason", info.Reason),
   811  					kv.Any("codec", info.Codec),
   812  					kv.Int("messages_count", info.MessagesCount),
   813  					kv.Int64("first_seqno", info.FirstSeqNo),
   814  					kv.Latency(start),
   815  				)
   816  			}
   817  		}
   818  	}
   819  	t.OnWriterSendMessages = func(
   820  		info trace.TopicWriterSendMessagesStartInfo,
   821  	) func(doneInfo trace.TopicWriterSendMessagesDoneInfo) {
   822  		if d.Details()&trace.TopicWriterStreamEvents == 0 {
   823  			return nil
   824  		}
   825  		ctx := with(context.Background(), TRACE, "ydb", "topic", "writer", "send", "messages")
   826  		start := time.Now()
   827  		l.Log(ctx, "start",
   828  			kv.String("writer_instance_id", info.WriterInstanceID),
   829  			kv.String("session_id", info.SessionID),
   830  			kv.Any("codec", info.Codec),
   831  			kv.Int("messages_count", info.MessagesCount),
   832  			kv.Int64("first_seqno", info.FirstSeqNo),
   833  		)
   834  
   835  		return func(doneInfo trace.TopicWriterSendMessagesDoneInfo) {
   836  			if doneInfo.Error == nil {
   837  				l.Log(ctx, "writing messages to grpc buffer completed",
   838  					kv.String("writer_instance_id", info.WriterInstanceID),
   839  					kv.String("session_id", info.SessionID),
   840  					kv.Any("codec", info.Codec),
   841  					kv.Int("messages_count", info.MessagesCount),
   842  					kv.Int64("first_seqno", info.FirstSeqNo),
   843  					kv.Latency(start),
   844  				)
   845  			} else {
   846  				l.Log(WithLevel(ctx, WARN), "writing messages to grpc buffer completed",
   847  					kv.Error(doneInfo.Error),
   848  					kv.String("writer_instance_id", info.WriterInstanceID),
   849  					kv.String("session_id", info.SessionID),
   850  					kv.Any("codec", info.Codec),
   851  					kv.Int("messages_count", info.MessagesCount),
   852  					kv.Int64("first_seqno", info.FirstSeqNo),
   853  					kv.Latency(start),
   854  				)
   855  			}
   856  		}
   857  	}
   858  	t.OnWriterReceiveResult = func(info trace.TopicWriterResultMessagesInfo) {
   859  		if d.Details()&trace.TopicWriterStreamEvents == 0 {
   860  			return
   861  		}
   862  		acks := info.Acks.GetAcks()
   863  		ctx := with(context.Background(), DEBUG, "ydb", "topic", "writer", "receive", "result")
   864  		l.Log(ctx, "topic writer receive result from server",
   865  			kv.String("writer_instance_id", info.WriterInstanceID),
   866  			kv.String("session_id", info.SessionID),
   867  			kv.Int("acks_count", acks.AcksCount),
   868  			kv.Int64("seq_no_min", acks.SeqNoMin),
   869  			kv.Int64("seq_no_max", acks.SeqNoMax),
   870  			kv.Int64("written_offset_min", acks.WrittenOffsetMin),
   871  			kv.Int64("written_offset_max", acks.WrittenOffsetMax),
   872  			kv.Int("written_offset_count", acks.WrittenCount),
   873  			kv.Int("written_in_tx_count", acks.WrittenInTxCount),
   874  			kv.Int("skip_count", acks.SkipCount),
   875  			kv.Version(),
   876  		)
   877  	}
   878  	t.OnWriterReadUnknownGrpcMessage = func(info trace.TopicOnWriterReadUnknownGrpcMessageInfo) {
   879  		if d.Details()&trace.TopicWriterStreamEvents == 0 {
   880  			return
   881  		}
   882  		ctx := with(context.Background(), DEBUG, "ydb", "topic", "writer", "read", "unknown", "grpc", "message")
   883  		l.Log(ctx, "topic writer receive unknown message from server",
   884  			kv.Error(info.Error),
   885  			kv.String("writer_instance_id", info.WriterInstanceID),
   886  			kv.String("session_id", info.SessionID),
   887  		)
   888  	}
   889  
   890  	return t
   891  }