[VOL-5486] Fix deprecated versions
Change-Id: I3e03ea246020547ae75fa92ce8cf5cbba7e8f3bb
Signed-off-by: Abhay Kumar <abhay.kumar@radisys.com>
diff --git a/vendor/go.etcd.io/etcd/pkg/v3/traceutil/trace.go b/vendor/go.etcd.io/etcd/pkg/v3/traceutil/trace.go
new file mode 100644
index 0000000..abf5cf1
--- /dev/null
+++ b/vendor/go.etcd.io/etcd/pkg/v3/traceutil/trace.go
@@ -0,0 +1,243 @@
+// Copyright 2019 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package traceutil implements tracing utilities using "context".
+package traceutil
+
+import (
+ "context"
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+
+ "go.uber.org/zap"
+)
+
+// TraceKey is used as a key of context for Trace.
+type TraceKey struct{}
+
+// StartTimeKey is used as a key of context for start time of operation.
+type StartTimeKey struct{}
+
+// Field is a kv pair to record additional details of the trace.
+type Field struct {
+ Key string
+ Value any
+}
+
+func (f *Field) format() string {
+ return fmt.Sprintf("%s:%v; ", f.Key, f.Value)
+}
+
+func writeFields(fields []Field) string {
+ if len(fields) == 0 {
+ return ""
+ }
+ var buf strings.Builder
+ buf.WriteString("{")
+ for _, f := range fields {
+ buf.WriteString(f.format())
+ }
+ buf.WriteString("}")
+ return buf.String()
+}
+
+type Trace struct {
+ operation string
+ lg *zap.Logger
+ fields []Field
+ startTime time.Time
+ steps []step
+ stepDisabled bool
+ isEmpty bool
+}
+
+type step struct {
+ time time.Time
+ msg string
+ fields []Field
+ isSubTraceStart bool
+ isSubTraceEnd bool
+}
+
+func New(op string, lg *zap.Logger, fields ...Field) *Trace {
+ return &Trace{operation: op, lg: lg, startTime: time.Now(), fields: fields}
+}
+
+// TODO returns a non-nil, empty Trace
+func TODO() *Trace {
+ return &Trace{isEmpty: true}
+}
+
+func Get(ctx context.Context) *Trace {
+ if trace, ok := ctx.Value(TraceKey{}).(*Trace); ok && trace != nil {
+ return trace
+ }
+ return TODO()
+}
+
+func (t *Trace) GetStartTime() time.Time {
+ return t.startTime
+}
+
+func (t *Trace) SetStartTime(time time.Time) {
+ t.startTime = time
+}
+
+func (t *Trace) InsertStep(at int, time time.Time, msg string, fields ...Field) {
+ newStep := step{time: time, msg: msg, fields: fields}
+ if at < len(t.steps) {
+ t.steps = append(t.steps[:at+1], t.steps[at:]...)
+ t.steps[at] = newStep
+ } else {
+ t.steps = append(t.steps, newStep)
+ }
+}
+
+// StartSubTrace adds step to trace as a start sign of sublevel trace
+// All steps in the subtrace will log out the input fields of this function
+func (t *Trace) StartSubTrace(fields ...Field) {
+ t.steps = append(t.steps, step{fields: fields, isSubTraceStart: true})
+}
+
+// StopSubTrace adds step to trace as a end sign of sublevel trace
+// All steps in the subtrace will log out the input fields of this function
+func (t *Trace) StopSubTrace(fields ...Field) {
+ t.steps = append(t.steps, step{fields: fields, isSubTraceEnd: true})
+}
+
+// Step adds step to trace
+func (t *Trace) Step(msg string, fields ...Field) {
+ if !t.stepDisabled {
+ t.steps = append(t.steps, step{time: time.Now(), msg: msg, fields: fields})
+ }
+}
+
+// StepWithFunction will measure the input function as a single step
+func (t *Trace) StepWithFunction(f func(), msg string, fields ...Field) {
+ t.disableStep()
+ f()
+ t.enableStep()
+ t.Step(msg, fields...)
+}
+
+func (t *Trace) AddField(fields ...Field) {
+ for _, f := range fields {
+ if !t.updateFieldIfExist(f) {
+ t.fields = append(t.fields, f)
+ }
+ }
+}
+
+func (t *Trace) IsEmpty() bool {
+ return t.isEmpty
+}
+
+// Log dumps all steps in the Trace
+func (t *Trace) Log() {
+ t.LogWithStepThreshold(0)
+}
+
+// LogIfLong dumps logs if the duration is longer than threshold
+func (t *Trace) LogIfLong(threshold time.Duration) {
+ if time.Since(t.startTime) > threshold {
+ stepThreshold := threshold / time.Duration(len(t.steps)+1)
+ t.LogWithStepThreshold(stepThreshold)
+ }
+}
+
+// LogAllStepsIfLong dumps all logs if the duration is longer than threshold
+func (t *Trace) LogAllStepsIfLong(threshold time.Duration) {
+ if time.Since(t.startTime) > threshold {
+ t.LogWithStepThreshold(0)
+ }
+}
+
+// LogWithStepThreshold only dumps step whose duration is longer than step threshold
+func (t *Trace) LogWithStepThreshold(threshold time.Duration) {
+ msg, fs := t.logInfo(threshold)
+ if t.lg != nil {
+ t.lg.Info(msg, fs...)
+ }
+}
+
+func (t *Trace) logInfo(threshold time.Duration) (string, []zap.Field) {
+ endTime := time.Now()
+ totalDuration := endTime.Sub(t.startTime)
+ traceNum := rand.Int31()
+ msg := fmt.Sprintf("trace[%d] %s", traceNum, t.operation)
+
+ var steps []string
+ lastStepTime := t.startTime
+ for i := 0; i < len(t.steps); i++ {
+ tstep := t.steps[i]
+ // add subtrace common fields which defined at the beginning to each sub-steps
+ if tstep.isSubTraceStart {
+ for j := i + 1; j < len(t.steps) && !t.steps[j].isSubTraceEnd; j++ {
+ t.steps[j].fields = append(tstep.fields, t.steps[j].fields...)
+ }
+ continue
+ }
+ // add subtrace common fields which defined at the end to each sub-steps
+ if tstep.isSubTraceEnd {
+ for j := i - 1; j >= 0 && !t.steps[j].isSubTraceStart; j-- {
+ t.steps[j].fields = append(tstep.fields, t.steps[j].fields...)
+ }
+ continue
+ }
+ }
+ for i := 0; i < len(t.steps); i++ {
+ tstep := t.steps[i]
+ if tstep.isSubTraceStart || tstep.isSubTraceEnd {
+ continue
+ }
+ stepDuration := tstep.time.Sub(lastStepTime)
+ if stepDuration > threshold {
+ steps = append(steps, fmt.Sprintf("trace[%d] '%v' %s (duration: %v)",
+ traceNum, tstep.msg, writeFields(tstep.fields), stepDuration))
+ }
+ lastStepTime = tstep.time
+ }
+
+ fs := []zap.Field{
+ zap.String("detail", writeFields(t.fields)),
+ zap.Duration("duration", totalDuration),
+ zap.Time("start", t.startTime),
+ zap.Time("end", endTime),
+ zap.Strings("steps", steps),
+ zap.Int("step_count", len(steps)),
+ }
+ return msg, fs
+}
+
+func (t *Trace) updateFieldIfExist(f Field) bool {
+ for i, v := range t.fields {
+ if v.Key == f.Key {
+ t.fields[i].Value = f.Value
+ return true
+ }
+ }
+ return false
+}
+
+// disableStep sets the flag to prevent the trace from adding steps
+func (t *Trace) disableStep() {
+ t.stepDisabled = true
+}
+
+// enableStep re-enable the trace to add steps
+func (t *Trace) enableStep() {
+ t.stepDisabled = false
+}