mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor update for E2E framework
Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
72
vendor/k8s.io/utils/buffer/ring_growing.go
generated
vendored
Normal file
72
vendor/k8s.io/utils/buffer/ring_growing.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes 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 buffer
|
||||
|
||||
// RingGrowing is a growing ring buffer.
|
||||
// Not thread safe.
|
||||
type RingGrowing struct {
|
||||
data []interface{}
|
||||
n int // Size of Data
|
||||
beg int // First available element
|
||||
readable int // Number of data items available
|
||||
}
|
||||
|
||||
// NewRingGrowing constructs a new RingGrowing instance with provided parameters.
|
||||
func NewRingGrowing(initialSize int) *RingGrowing {
|
||||
return &RingGrowing{
|
||||
data: make([]interface{}, initialSize),
|
||||
n: initialSize,
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOne reads (consumes) first item from the buffer if it is available, otherwise returns false.
|
||||
func (r *RingGrowing) ReadOne() (data interface{}, ok bool) {
|
||||
if r.readable == 0 {
|
||||
return nil, false
|
||||
}
|
||||
r.readable--
|
||||
element := r.data[r.beg]
|
||||
r.data[r.beg] = nil // Remove reference to the object to help GC
|
||||
if r.beg == r.n-1 {
|
||||
// Was the last element
|
||||
r.beg = 0
|
||||
} else {
|
||||
r.beg++
|
||||
}
|
||||
return element, true
|
||||
}
|
||||
|
||||
// WriteOne adds an item to the end of the buffer, growing it if it is full.
|
||||
func (r *RingGrowing) WriteOne(data interface{}) {
|
||||
if r.readable == r.n {
|
||||
// Time to grow
|
||||
newN := r.n * 2
|
||||
newData := make([]interface{}, newN)
|
||||
to := r.beg + r.readable
|
||||
if to <= r.n {
|
||||
copy(newData, r.data[r.beg:to])
|
||||
} else {
|
||||
copied := copy(newData, r.data[r.beg:])
|
||||
copy(newData[copied:], r.data[:(to%r.n)])
|
||||
}
|
||||
r.beg = 0
|
||||
r.data = newData
|
||||
r.n = newN
|
||||
}
|
||||
r.data[(r.readable+r.beg)%r.n] = data
|
||||
r.readable++
|
||||
}
|
19
vendor/k8s.io/utils/io/consistentread.go → vendor/k8s.io/utils/io/read.go
generated
vendored
19
vendor/k8s.io/utils/io/consistentread.go → vendor/k8s.io/utils/io/read.go
generated
vendored
@ -18,10 +18,15 @@ package io
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// ErrLimitReached means that the read limit is reached.
|
||||
var ErrLimitReached = errors.New("the read limit is reached")
|
||||
|
||||
// ConsistentRead repeatedly reads a file until it gets the same content twice.
|
||||
// This is useful when reading files in /proc that are larger than page size
|
||||
// and kernel may modify them between individual read() syscalls.
|
||||
@ -53,3 +58,17 @@ func consistentReadSync(filename string, attempts int, sync func(int)) ([]byte,
|
||||
}
|
||||
return nil, fmt.Errorf("could not get consistent content of %s after %d attempts", filename, attempts)
|
||||
}
|
||||
|
||||
// ReadAtMost reads up to `limit` bytes from `r`, and reports an error
|
||||
// when `limit` bytes are read.
|
||||
func ReadAtMost(r io.Reader, limit int64) ([]byte, error) {
|
||||
limitedReader := &io.LimitedReader{R: r, N: limit}
|
||||
data, err := ioutil.ReadAll(limitedReader)
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
if limitedReader.N <= 0 {
|
||||
return data, ErrLimitReached
|
||||
}
|
||||
return data, nil
|
||||
}
|
121
vendor/k8s.io/utils/net/ipnet.go
generated
vendored
Normal file
121
vendor/k8s.io/utils/net/ipnet.go
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 net
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IPNetSet maps string to net.IPNet.
|
||||
type IPNetSet map[string]*net.IPNet
|
||||
|
||||
// ParseIPNets parses string slice to IPNetSet.
|
||||
func ParseIPNets(specs ...string) (IPNetSet, error) {
|
||||
ipnetset := make(IPNetSet)
|
||||
for _, spec := range specs {
|
||||
spec = strings.TrimSpace(spec)
|
||||
_, ipnet, err := net.ParseCIDR(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k := ipnet.String() // In case of normalization
|
||||
ipnetset[k] = ipnet
|
||||
}
|
||||
return ipnetset, nil
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s IPNetSet) Insert(items ...*net.IPNet) {
|
||||
for _, item := range items {
|
||||
s[item.String()] = item
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s IPNetSet) Delete(items ...*net.IPNet) {
|
||||
for _, item := range items {
|
||||
delete(s, item.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s IPNetSet) Has(item *net.IPNet) bool {
|
||||
_, contained := s[item.String()]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s IPNetSet) HasAll(items ...*net.IPNet) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s IPNetSet) Difference(s2 IPNetSet) IPNetSet {
|
||||
result := make(IPNetSet)
|
||||
for k, i := range s {
|
||||
_, found := s2[k]
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
result[k] = i
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// StringSlice returns a []string with the String representation of each element in the set.
|
||||
// Order is undefined.
|
||||
func (s IPNetSet) StringSlice() []string {
|
||||
a := make([]string, 0, len(s))
|
||||
for k := range s {
|
||||
a = append(a, k)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s IPNetSet) IsSuperset(s2 IPNetSet) bool {
|
||||
for k := range s2 {
|
||||
_, found := s[k]
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s IPNetSet) Equal(s2 IPNetSet) bool {
|
||||
return len(s) == len(s2) && s.IsSuperset(s2)
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s IPNetSet) Len() int {
|
||||
return len(s)
|
||||
}
|
37
vendor/k8s.io/utils/net/net.go
generated
vendored
Normal file
37
vendor/k8s.io/utils/net/net.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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 net
|
||||
|
||||
import "net"
|
||||
|
||||
// IsIPv6 returns if netIP is IPv6.
|
||||
func IsIPv6(netIP net.IP) bool {
|
||||
return netIP != nil && netIP.To4() == nil
|
||||
}
|
||||
|
||||
// IsIPv6String returns if ip is IPv6.
|
||||
func IsIPv6String(ip string) bool {
|
||||
netIP := net.ParseIP(ip)
|
||||
return IsIPv6(netIP)
|
||||
}
|
||||
|
||||
// IsIPv6CIDRString returns if cidr is IPv6.
|
||||
// This assumes cidr is a valid CIDR.
|
||||
func IsIPv6CIDRString(cidr string) bool {
|
||||
ip, _, _ := net.ParseCIDR(cidr)
|
||||
return IsIPv6(ip)
|
||||
}
|
86
vendor/k8s.io/utils/pointer/pointer.go
generated
vendored
Normal file
86
vendor/k8s.io/utils/pointer/pointer.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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 pointer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// AllPtrFieldsNil tests whether all pointer fields in a struct are nil. This is useful when,
|
||||
// for example, an API struct is handled by plugins which need to distinguish
|
||||
// "no plugin accepted this spec" from "this spec is empty".
|
||||
//
|
||||
// This function is only valid for structs and pointers to structs. Any other
|
||||
// type will cause a panic. Passing a typed nil pointer will return true.
|
||||
func AllPtrFieldsNil(obj interface{}) bool {
|
||||
v := reflect.ValueOf(obj)
|
||||
if !v.IsValid() {
|
||||
panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj))
|
||||
}
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return true
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Int32Ptr returns a pointer to an int32
|
||||
func Int32Ptr(i int32) *int32 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Int64Ptr returns a pointer to an int64
|
||||
func Int64Ptr(i int64) *int64 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Int32PtrDerefOr dereference the int32 ptr and returns it if not nil,
|
||||
// else returns def.
|
||||
func Int32PtrDerefOr(ptr *int32, def int32) int32 {
|
||||
if ptr != nil {
|
||||
return *ptr
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// BoolPtr returns a pointer to a bool
|
||||
func BoolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// StringPtr returns a pointer to the passed string.
|
||||
func StringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
// Float32Ptr returns a pointer to the passed float32.
|
||||
func Float32Ptr(i float32) *float32 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Float64Ptr returns a pointer to the passed float64.
|
||||
func Float64Ptr(i float64) *float64 {
|
||||
return &i
|
||||
}
|
36
vendor/k8s.io/utils/strings/escape.go
generated
vendored
Normal file
36
vendor/k8s.io/utils/strings/escape.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes 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 strings
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EscapeQualifiedName converts a plugin name, which might contain a / into a
|
||||
// string that is safe to use on-disk. This assumes that the input has already
|
||||
// been validates as a qualified name. we use "~" rather than ":" here in case
|
||||
// we ever use a filesystem that doesn't allow ":".
|
||||
func EscapeQualifiedName(in string) string {
|
||||
return strings.Replace(in, "/", "~", -1)
|
||||
}
|
||||
|
||||
// UnescapeQualifiedName converts an escaped plugin name (as per EscapeQualifiedName)
|
||||
// back to its normal form. This assumes that the input has already been
|
||||
// validates as a qualified name.
|
||||
func UnescapeQualifiedName(in string) string {
|
||||
return strings.Replace(in, "~", "/", -1)
|
||||
}
|
64
vendor/k8s.io/utils/strings/line_delimiter.go
generated
vendored
Normal file
64
vendor/k8s.io/utils/strings/line_delimiter.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes 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 strings
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LineDelimiter is a filter that will split input on lines
|
||||
// and bracket each line with the delimiter string.
|
||||
type LineDelimiter struct {
|
||||
output io.Writer
|
||||
delimiter []byte
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
// NewLineDelimiter allocates a new io.Writer that will split input on lines
|
||||
// and bracket each line with the delimiter string. This can be useful in
|
||||
// output tests where it is difficult to see and test trailing whitespace.
|
||||
func NewLineDelimiter(output io.Writer, delimiter string) *LineDelimiter {
|
||||
return &LineDelimiter{output: output, delimiter: []byte(delimiter)}
|
||||
}
|
||||
|
||||
// Write writes buf to the LineDelimiter ld. The only errors returned are ones
|
||||
// encountered while writing to the underlying output stream.
|
||||
func (ld *LineDelimiter) Write(buf []byte) (n int, err error) {
|
||||
return ld.buf.Write(buf)
|
||||
}
|
||||
|
||||
// Flush all lines up until now. This will assume insert a linebreak at the current point of the stream.
|
||||
func (ld *LineDelimiter) Flush() (err error) {
|
||||
lines := strings.Split(ld.buf.String(), "\n")
|
||||
for _, line := range lines {
|
||||
if _, err = ld.output.Write(ld.delimiter); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = ld.output.Write([]byte(line)); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = ld.output.Write(ld.delimiter); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = ld.output.Write([]byte("\n")); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
46
vendor/k8s.io/utils/strings/strings.go
generated
vendored
Normal file
46
vendor/k8s.io/utils/strings/strings.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes 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 strings
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SplitQualifiedName Splits a fully qualified name and returns its namespace and name.
|
||||
// Assumes that the input 'str' has been validated.
|
||||
func SplitQualifiedName(str string) (string, string) {
|
||||
parts := strings.Split(str, "/")
|
||||
if len(parts) < 2 {
|
||||
return "", str
|
||||
}
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
|
||||
// JoinQualifiedName joins 'namespace' and 'name' and returns a fully qualified name
|
||||
// Assumes that the input is valid.
|
||||
func JoinQualifiedName(namespace, name string) string {
|
||||
return path.Join(namespace, name)
|
||||
}
|
||||
|
||||
// ShortenString returns the first N slice of a string.
|
||||
func ShortenString(str string, n int) string {
|
||||
if len(str) <= n {
|
||||
return str
|
||||
}
|
||||
return str[:n]
|
||||
}
|
97
vendor/k8s.io/utils/trace/trace.go
generated
vendored
Normal file
97
vendor/k8s.io/utils/trace/trace.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes 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 trace
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
type traceStep struct {
|
||||
stepTime time.Time
|
||||
msg string
|
||||
}
|
||||
|
||||
// Trace keeps track of a set of "steps" and allows us to log a specific
|
||||
// step if it took longer than its share of the total allowed time
|
||||
type Trace struct {
|
||||
name string
|
||||
startTime time.Time
|
||||
steps []traceStep
|
||||
}
|
||||
|
||||
// New creates a Trace with the specified name
|
||||
func New(name string) *Trace {
|
||||
return &Trace{name, time.Now(), nil}
|
||||
}
|
||||
|
||||
// Step adds a new step with a specific message. Call this at the end of an
|
||||
// execution step to record how long it took.
|
||||
func (t *Trace) Step(msg string) {
|
||||
if t.steps == nil {
|
||||
// traces almost always have less than 6 steps, do this to avoid more than a single allocation
|
||||
t.steps = make([]traceStep, 0, 6)
|
||||
}
|
||||
t.steps = append(t.steps, traceStep{time.Now(), msg})
|
||||
}
|
||||
|
||||
// Log is used to dump all the steps in the Trace
|
||||
func (t *Trace) Log() {
|
||||
// an explicit logging request should dump all the steps out at the higher level
|
||||
t.logWithStepThreshold(0)
|
||||
}
|
||||
|
||||
func (t *Trace) logWithStepThreshold(stepThreshold time.Duration) {
|
||||
var buffer bytes.Buffer
|
||||
tracenum := rand.Int31()
|
||||
endTime := time.Now()
|
||||
|
||||
totalTime := endTime.Sub(t.startTime)
|
||||
buffer.WriteString(fmt.Sprintf("Trace[%d]: %q (started: %v) (total time: %v):\n", tracenum, t.name, t.startTime, totalTime))
|
||||
lastStepTime := t.startTime
|
||||
for _, step := range t.steps {
|
||||
stepDuration := step.stepTime.Sub(lastStepTime)
|
||||
if stepThreshold == 0 || stepDuration > stepThreshold || klog.V(4) {
|
||||
buffer.WriteString(fmt.Sprintf("Trace[%d]: [%v] [%v] %v\n", tracenum, step.stepTime.Sub(t.startTime), stepDuration, step.msg))
|
||||
}
|
||||
lastStepTime = step.stepTime
|
||||
}
|
||||
stepDuration := endTime.Sub(lastStepTime)
|
||||
if stepThreshold == 0 || stepDuration > stepThreshold || klog.V(4) {
|
||||
buffer.WriteString(fmt.Sprintf("Trace[%d]: [%v] [%v] END\n", tracenum, endTime.Sub(t.startTime), stepDuration))
|
||||
}
|
||||
|
||||
klog.Info(buffer.String())
|
||||
}
|
||||
|
||||
// LogIfLong is used to dump steps that took longer than its share
|
||||
func (t *Trace) LogIfLong(threshold time.Duration) {
|
||||
if time.Since(t.startTime) >= threshold {
|
||||
// if any step took more than it's share of the total allowed time, it deserves a higher log level
|
||||
stepThreshold := threshold / time.Duration(len(t.steps)+1)
|
||||
t.logWithStepThreshold(stepThreshold)
|
||||
}
|
||||
}
|
||||
|
||||
// TotalTime can be used to figure out how long it took since the Trace was created
|
||||
func (t *Trace) TotalTime() time.Duration {
|
||||
return time.Since(t.startTime)
|
||||
}
|
Reference in New Issue
Block a user