github.com/blend/go-sdk@v1.20220411.3/stats/mock_collector.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package stats 9 10 import ( 11 "time" 12 13 "github.com/blend/go-sdk/timeutil" 14 ) 15 16 // Assert that the mock collector implements Collector. 17 var ( 18 _ Collector = (*MockCollector)(nil) 19 ) 20 21 // NewMockCollector returns a new mock collector. 22 func NewMockCollector(capacity int) *MockCollector { 23 return &MockCollector{ 24 Metrics: make(chan MockMetric, capacity), 25 Errors: make(chan error, capacity), 26 FlushErrors: make(chan error, capacity), 27 CloseErrors: make(chan error, capacity), 28 } 29 } 30 31 // MockCollector is a mocked collector for stats. 32 type MockCollector struct { 33 Field struct { 34 Namespace string 35 DefaultTags []string 36 } 37 38 Metrics chan MockMetric 39 Errors chan error 40 FlushErrors chan error 41 CloseErrors chan error 42 } 43 44 // AllMetrics returns all the metrics from the collector. 45 func (mc *MockCollector) AllMetrics() (output []MockMetric) { 46 metricCount := len(mc.Metrics) 47 for x := 0; x < metricCount; x++ { 48 output = append(output, <-mc.Metrics) 49 } 50 return 51 } 52 53 // GetCount returns the number of events logged for a given metric name. 54 func (mc *MockCollector) GetCount(metricName string) (count int) { 55 var metric MockMetric 56 metricCount := len(mc.Metrics) 57 for x := 0; x < metricCount; x++ { 58 metric = <-mc.Metrics 59 if metric.Name == metricName { 60 count++ 61 } 62 mc.Metrics <- metric 63 } 64 return 65 } 66 67 // GetTagCount returns the number of events logged for a given metric name & tag name. 68 func (mc *MockCollector) GetTagCount(metricName string, tagName string) (count int) { 69 metrics := mc.AllMetrics() 70 metricCount := len(metrics) 71 for x := 0; x < metricCount; x++ { 72 metric := metrics[x] 73 if metric.Name == metricName { 74 for i := 0; i < len(metric.Tags); i++ { 75 if tagName == metric.Tags[i] { 76 count++ 77 } 78 } 79 } 80 } 81 return 82 } 83 84 func (mc *MockCollector) makeName(name string) string { 85 if mc.Field.Namespace != "" { 86 return mc.Field.Namespace + name 87 } 88 return name 89 } 90 91 // AddDefaultTag adds a default tag. 92 func (mc *MockCollector) AddDefaultTag(name, value string) { 93 mc.Field.DefaultTags = append(mc.Field.DefaultTags, Tag(name, value)) 94 } 95 96 // AddDefaultTags adds default tags. 97 func (mc *MockCollector) AddDefaultTags(tags ...string) { 98 mc.Field.DefaultTags = append(mc.Field.DefaultTags, tags...) 99 } 100 101 // DefaultTags returns the default tags set. 102 func (mc MockCollector) DefaultTags() []string { 103 return mc.Field.DefaultTags 104 } 105 106 // Count adds a mock count event to the event stream. 107 func (mc MockCollector) Count(name string, value int64, tags ...string) error { 108 mc.Metrics <- MockMetric{Name: mc.makeName(name), Count: value, Tags: append(mc.Field.DefaultTags, tags...)} 109 if len(mc.Errors) > 0 { 110 return <-mc.Errors 111 } 112 return nil 113 } 114 115 // Increment adds a mock count event to the event stream with value (1). 116 func (mc MockCollector) Increment(name string, tags ...string) error { 117 mc.Metrics <- MockMetric{Name: mc.makeName(name), Count: 1, Tags: append(mc.Field.DefaultTags, tags...)} 118 if len(mc.Errors) > 0 { 119 return <-mc.Errors 120 } 121 return nil 122 } 123 124 // Gauge adds a mock count event to the event stream with value (1). 125 func (mc MockCollector) Gauge(name string, value float64, tags ...string) error { 126 mc.Metrics <- MockMetric{Name: mc.makeName(name), Gauge: value, Tags: append(mc.Field.DefaultTags, tags...)} 127 if len(mc.Errors) > 0 { 128 return <-mc.Errors 129 } 130 return nil 131 } 132 133 // Histogram adds a mock count event to the event stream with value (1). 134 func (mc MockCollector) Histogram(name string, value float64, tags ...string) error { 135 mc.Metrics <- MockMetric{Name: mc.makeName(name), Histogram: value, Tags: append(mc.Field.DefaultTags, tags...)} 136 if len(mc.Errors) > 0 { 137 return <-mc.Errors 138 } 139 return nil 140 } 141 142 // Distribution adds a mock count event to the event stream with value (1). 143 func (mc MockCollector) Distribution(name string, value float64, tags ...string) error { 144 mc.Metrics <- MockMetric{Name: mc.makeName(name), Distribution: value, Tags: append(mc.Field.DefaultTags, tags...)} 145 if len(mc.Errors) > 0 { 146 return <-mc.Errors 147 } 148 return nil 149 } 150 151 // TimeInMilliseconds adds a mock time in millis event to the event stream with a value. 152 func (mc MockCollector) TimeInMilliseconds(name string, value time.Duration, tags ...string) error { 153 mc.Metrics <- MockMetric{Name: mc.makeName(name), TimeInMilliseconds: timeutil.Milliseconds(value), Tags: append(mc.Field.DefaultTags, tags...)} 154 if len(mc.Errors) > 0 { 155 return <-mc.Errors 156 } 157 return nil 158 } 159 160 // Flush does nothing on a MockCollector. 161 func (mc MockCollector) Flush() error { 162 if len(mc.FlushErrors) > 0 { 163 return <-mc.FlushErrors 164 } 165 return nil 166 } 167 168 // Close returns an error from the errors channel if any. 169 func (mc MockCollector) Close() error { 170 if len(mc.CloseErrors) > 0 { 171 return <-mc.CloseErrors 172 } 173 return nil 174 } 175 176 // MockMetric is a mock metric. 177 type MockMetric struct { 178 Name string 179 Count int64 180 Gauge float64 181 Histogram float64 182 Distribution float64 183 TimeInMilliseconds float64 184 Tags []string 185 }