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

     1  package log
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
     7  	"github.com/ydb-platform/ydb-go-sdk/v3/retry"
     8  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
     9  )
    10  
    11  // Retry returns trace.Retry with logging events from details
    12  func Retry(l Logger, d trace.Detailer, opts ...Option) (t trace.Retry) {
    13  	return internalRetry(wrapLogger(l, opts...), d)
    14  }
    15  
    16  func internalRetry(l Logger, d trace.Detailer) (t trace.Retry) {
    17  	t.OnRetry = func(
    18  		info trace.RetryLoopStartInfo,
    19  	) func(
    20  		trace.RetryLoopIntermediateInfo,
    21  	) func(
    22  		trace.RetryLoopDoneInfo,
    23  	) {
    24  		if d.Details()&trace.RetryEvents == 0 {
    25  			return nil
    26  		}
    27  		ctx := with(*info.Context, TRACE, "ydb", "retry")
    28  		label := info.Label
    29  		idempotent := info.Idempotent
    30  		l.Log(ctx, "start",
    31  			String("label", label),
    32  			Bool("idempotent", idempotent),
    33  		)
    34  		start := time.Now()
    35  
    36  		return func(info trace.RetryLoopIntermediateInfo) func(trace.RetryLoopDoneInfo) {
    37  			if info.Error == nil {
    38  				l.Log(ctx, "attempt done",
    39  					String("label", label),
    40  					latencyField(start),
    41  				)
    42  			} else {
    43  				lvl := ERROR
    44  				if !xerrors.IsYdb(info.Error) {
    45  					lvl = DEBUG
    46  				}
    47  				m := retry.Check(info.Error)
    48  				l.Log(WithLevel(ctx, lvl), "attempt failed",
    49  					Error(info.Error),
    50  					String("label", label),
    51  					latencyField(start),
    52  					Bool("retryable", m.MustRetry(idempotent)),
    53  					Int64("code", m.StatusCode()),
    54  					Bool("deleteSession", m.MustDeleteSession()),
    55  					versionField(),
    56  				)
    57  			}
    58  
    59  			return func(info trace.RetryLoopDoneInfo) {
    60  				if info.Error == nil {
    61  					l.Log(ctx, "done",
    62  						String("label", label),
    63  						latencyField(start),
    64  						Int("attempts", info.Attempts),
    65  					)
    66  				} else {
    67  					lvl := ERROR
    68  					if !xerrors.IsYdb(info.Error) {
    69  						lvl = DEBUG
    70  					}
    71  					m := retry.Check(info.Error)
    72  					l.Log(WithLevel(ctx, lvl), "failed",
    73  						Error(info.Error),
    74  						String("label", label),
    75  						latencyField(start),
    76  						Int("attempts", info.Attempts),
    77  						Bool("retryable", m.MustRetry(idempotent)),
    78  						Int64("code", m.StatusCode()),
    79  						Bool("deleteSession", m.MustDeleteSession()),
    80  						versionField(),
    81  					)
    82  				}
    83  			}
    84  		}
    85  	}
    86  
    87  	return t
    88  }