github.com/GoogleCloudPlatform/testgrid@v0.0.174/util/metrics/metrics.go (about) 1 /* 2 Copyright 2021 The TestGrid Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package metrics provides metric reporting for TestGrid components. 18 package metrics 19 20 import "time" 21 22 // Metric contains common metric functions. 23 type Metric interface { 24 Name() string 25 } 26 27 // Int64 is an int64 metric. 28 type Int64 interface { 29 Metric 30 Set(int64, ...string) 31 } 32 33 // Counter is a strictly-increasing metric. 34 type Counter interface { 35 Metric 36 Add(int64, ...string) 37 } 38 39 // Duration is a metric describing a length of time 40 type Duration interface { 41 Metric 42 Set(time.Duration, ...string) 43 } 44 45 // Factory is a collection of functions that create metrics 46 type Factory struct { 47 NewInt64 func(name, desc string, fields ...string) Int64 48 NewCounter func(name, desc string, fields ...string) Counter 49 NewDuration func(name, desc string, fields ...string) Duration 50 } 51 52 // NewCyclic derives a cycle metric from the given metrics 53 func (f Factory) NewCyclic(componentName string) Cyclic { 54 fields := []string{"component"} 55 return Cyclic{ 56 errors: f.NewCounter("errors", "Number of failed updates", fields...), 57 skips: f.NewCounter("skips", "Number of skipped updates", fields...), 58 successes: f.NewCounter("successes", "Number of successful updates", fields...), 59 cycleSeconds: f.NewDuration("cycle_duration", "Seconds required to complete an update", fields...), 60 fields: []string{componentName}, 61 } 62 } 63 64 // Cyclic is a collection of metrics that measures how long a task takes to complete 65 type Cyclic struct { 66 fields []string 67 errors Counter 68 skips Counter 69 successes Counter 70 cycleSeconds Duration 71 } 72 73 // Start returns a PeriodicReporter that logs metrics when one of its methods are called. 74 func (p *Cyclic) Start() *CycleReporter { 75 if p == nil { 76 return nil 77 } 78 return &CycleReporter{metric: p, when: time.Now()} 79 } 80 81 // CycleReporter reports the status of the task that spawned it and how long it took. 82 type CycleReporter struct { 83 metric *Cyclic 84 when time.Time 85 } 86 87 func (pr *CycleReporter) done() { 88 if pr == nil || pr.metric.cycleSeconds == nil { 89 return 90 } 91 pr.metric.cycleSeconds.Set(time.Since(pr.when), pr.metric.fields...) 92 } 93 94 // Success reports success 95 func (pr *CycleReporter) Success() { 96 pr.done() 97 if pr == nil || pr.metric.successes == nil { 98 return 99 } 100 pr.metric.successes.Add(1, pr.metric.fields...) 101 } 102 103 // Fail reports a failure or unexpected error 104 func (pr *CycleReporter) Fail() { 105 pr.done() 106 if pr == nil || pr.metric.errors == nil { 107 return 108 } 109 pr.metric.errors.Add(1, pr.metric.fields...) 110 } 111 112 // Skip reports a cycle that was skipped due to an expected condition, flag, or configuration 113 func (pr *CycleReporter) Skip() { 114 pr.done() 115 if pr == nil || pr.metric.skips == nil { 116 return 117 } 118 pr.metric.skips.Add(1, pr.metric.fields...) 119 }