remove unused code from vendor
This commit is contained in:
-64
@@ -1,64 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 xkit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
)
|
||||
|
||||
// LoggerOption sets a parameter for the Logger.
|
||||
type LoggerOption func(*Logger)
|
||||
|
||||
// MessageKey sets the key for the actual log message. By default, it's "msg".
|
||||
func MessageKey(key string) LoggerOption {
|
||||
return func(l *Logger) { l.messageKey = key }
|
||||
}
|
||||
|
||||
// Logger wraps a go-kit logger instance in a Jaeger client compatible one.
|
||||
type Logger struct {
|
||||
infoLogger log.Logger
|
||||
errorLogger log.Logger
|
||||
|
||||
messageKey string
|
||||
}
|
||||
|
||||
// NewLogger creates a new Jaeger client logger from a go-kit one.
|
||||
func NewLogger(kitlogger log.Logger, options ...LoggerOption) *Logger {
|
||||
logger := &Logger{
|
||||
infoLogger: level.Info(kitlogger),
|
||||
errorLogger: level.Error(kitlogger),
|
||||
|
||||
messageKey: "msg",
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(logger)
|
||||
}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
// Error implements the github.com/uber/jaeger-client-go/log.Logger interface.
|
||||
func (l *Logger) Error(msg string) {
|
||||
l.errorLogger.Log(l.messageKey, msg)
|
||||
}
|
||||
|
||||
// Infof implements the github.com/uber/jaeger-client-go/log.Logger interface.
|
||||
func (l *Logger) Infof(msg string, args ...interface{}) {
|
||||
l.infoLogger.Log(l.messageKey, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 expvar
|
||||
|
||||
import (
|
||||
"github.com/go-kit/kit/metrics"
|
||||
"github.com/go-kit/kit/metrics/expvar"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics/go-kit"
|
||||
)
|
||||
|
||||
// NewFactory creates a new metrics factory using go-kit expvar package.
|
||||
// buckets is the number of buckets to be used in histograms.
|
||||
func NewFactory(buckets int) xkit.Factory {
|
||||
return factory{
|
||||
buckets: buckets,
|
||||
}
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
buckets int
|
||||
}
|
||||
|
||||
func (f factory) Counter(name string) metrics.Counter {
|
||||
return expvar.NewCounter(name)
|
||||
}
|
||||
|
||||
func (f factory) Histogram(name string) metrics.Histogram {
|
||||
return expvar.NewHistogram(name, f.buckets)
|
||||
}
|
||||
|
||||
func (f factory) Gauge(name string) metrics.Gauge {
|
||||
return expvar.NewGauge(name)
|
||||
}
|
||||
|
||||
func (f factory) Capabilities() xkit.Capabilities {
|
||||
return xkit.Capabilities{Tagging: false}
|
||||
}
|
||||
-161
@@ -1,161 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 xkit
|
||||
|
||||
import (
|
||||
kit "github.com/go-kit/kit/metrics"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics"
|
||||
)
|
||||
|
||||
// Factory provides a unified interface for creating named metrics
|
||||
// from various go-kit metrics implementations.
|
||||
type Factory interface {
|
||||
Counter(name string) kit.Counter
|
||||
Gauge(name string) kit.Gauge
|
||||
Histogram(name string) kit.Histogram
|
||||
Capabilities() Capabilities
|
||||
}
|
||||
|
||||
// Capabilities describes capabilities of a specific metrics factory.
|
||||
type Capabilities struct {
|
||||
// Tagging indicates whether the factory has the capability for tagged metrics
|
||||
Tagging bool
|
||||
}
|
||||
|
||||
// FactoryOption is a function that adjusts some parameters of the factory.
|
||||
type FactoryOption func(*factory)
|
||||
|
||||
// Wrap is used to create an adapter from xkit.Factory to metrics.Factory.
|
||||
func Wrap(namespace string, f Factory, options ...FactoryOption) metrics.Factory {
|
||||
factory := &factory{
|
||||
scope: namespace,
|
||||
factory: f,
|
||||
scopeSep: ".",
|
||||
tagsSep: ".",
|
||||
tagKVSep: "_",
|
||||
}
|
||||
for i := range options {
|
||||
options[i](factory)
|
||||
}
|
||||
return factory
|
||||
}
|
||||
|
||||
// ScopeSeparator returns an option that overrides default scope separator.
|
||||
func ScopeSeparator(scopeSep string) FactoryOption {
|
||||
return func(f *factory) {
|
||||
f.scopeSep = scopeSep
|
||||
}
|
||||
}
|
||||
|
||||
// TagsSeparator returns an option that overrides default tags separator.
|
||||
func TagsSeparator(tagsSep string) FactoryOption {
|
||||
return func(f *factory) {
|
||||
f.tagsSep = tagsSep
|
||||
}
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
scope string
|
||||
tags map[string]string
|
||||
factory Factory
|
||||
scopeSep string
|
||||
tagsSep string
|
||||
tagKVSep string
|
||||
}
|
||||
|
||||
func (f *factory) subScope(name string) string {
|
||||
if f.scope == "" {
|
||||
return name
|
||||
}
|
||||
if name == "" {
|
||||
return f.scope
|
||||
}
|
||||
return f.scope + f.scopeSep + name
|
||||
}
|
||||
|
||||
// nameAndTagsList returns a name and tags list for the new metrics.
|
||||
// The name is a concatenation of nom and the current factory scope.
|
||||
// The tags list is a flattened list of passed tags merged with factory tags.
|
||||
// If the underlying factory does not support tags, then the tags are
|
||||
// transformed into a string and appended to the name.
|
||||
func (f *factory) nameAndTagsList(nom string, tags map[string]string) (name string, tagsList []string) {
|
||||
mergedTags := f.mergeTags(tags)
|
||||
name = f.subScope(nom)
|
||||
tagsList = f.tagsList(mergedTags)
|
||||
if len(tagsList) == 0 || f.factory.Capabilities().Tagging {
|
||||
return
|
||||
}
|
||||
name = metrics.GetKey(name, mergedTags, f.tagsSep, f.tagKVSep)
|
||||
tagsList = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (f *factory) Counter(name string, tags map[string]string) metrics.Counter {
|
||||
name, tagsList := f.nameAndTagsList(name, tags)
|
||||
counter := f.factory.Counter(name)
|
||||
if len(tagsList) > 0 {
|
||||
counter = counter.With(tagsList...)
|
||||
}
|
||||
return NewCounter(counter)
|
||||
}
|
||||
|
||||
func (f *factory) Timer(name string, tags map[string]string) metrics.Timer {
|
||||
name, tagsList := f.nameAndTagsList(name, tags)
|
||||
hist := f.factory.Histogram(name)
|
||||
if len(tagsList) > 0 {
|
||||
hist = hist.With(tagsList...)
|
||||
}
|
||||
return NewTimer(hist)
|
||||
}
|
||||
|
||||
func (f *factory) Gauge(name string, tags map[string]string) metrics.Gauge {
|
||||
name, tagsList := f.nameAndTagsList(name, tags)
|
||||
gauge := f.factory.Gauge(name)
|
||||
if len(tagsList) > 0 {
|
||||
gauge = gauge.With(tagsList...)
|
||||
}
|
||||
return NewGauge(gauge)
|
||||
}
|
||||
|
||||
func (f *factory) Namespace(name string, tags map[string]string) metrics.Factory {
|
||||
return &factory{
|
||||
scope: f.subScope(name),
|
||||
tags: f.mergeTags(tags),
|
||||
factory: f.factory,
|
||||
scopeSep: f.scopeSep,
|
||||
tagsSep: f.tagsSep,
|
||||
tagKVSep: f.tagKVSep,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *factory) tagsList(a map[string]string) []string {
|
||||
ret := make([]string, 0, 2*len(a))
|
||||
for k, v := range a {
|
||||
ret = append(ret, k, v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *factory) mergeTags(tags map[string]string) map[string]string {
|
||||
ret := make(map[string]string, len(f.tags)+len(tags))
|
||||
for k, v := range f.tags {
|
||||
ret[k] = v
|
||||
}
|
||||
for k, v := range tags {
|
||||
ret[k] = v
|
||||
}
|
||||
return ret
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 influx
|
||||
|
||||
import (
|
||||
"github.com/go-kit/kit/metrics"
|
||||
"github.com/go-kit/kit/metrics/influx"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics/go-kit"
|
||||
)
|
||||
|
||||
// NewFactory creates a new metrics factory using go-kit influx package.
|
||||
func NewFactory(client *influx.Influx) xkit.Factory {
|
||||
return factory{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
client *influx.Influx
|
||||
}
|
||||
|
||||
func (f factory) Counter(name string) metrics.Counter {
|
||||
return f.client.NewCounter(name)
|
||||
}
|
||||
|
||||
func (f factory) Histogram(name string) metrics.Histogram {
|
||||
return f.client.NewHistogram(name)
|
||||
}
|
||||
|
||||
func (f factory) Gauge(name string) metrics.Gauge {
|
||||
return f.client.NewGauge(name)
|
||||
}
|
||||
|
||||
func (f factory) Capabilities() xkit.Capabilities {
|
||||
return xkit.Capabilities{Tagging: true}
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 xkit
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
kit "github.com/go-kit/kit/metrics"
|
||||
)
|
||||
|
||||
// Counter is an adapter from go-kit Counter to jaeger-lib Counter
|
||||
type Counter struct {
|
||||
counter kit.Counter
|
||||
}
|
||||
|
||||
// NewCounter creates a new Counter
|
||||
func NewCounter(counter kit.Counter) *Counter {
|
||||
return &Counter{counter: counter}
|
||||
}
|
||||
|
||||
// Inc adds the given value to the counter.
|
||||
func (c *Counter) Inc(delta int64) {
|
||||
c.counter.Add(float64(delta))
|
||||
}
|
||||
|
||||
// Gauge is an adapter from go-kit Gauge to jaeger-lib Gauge
|
||||
type Gauge struct {
|
||||
gauge kit.Gauge
|
||||
}
|
||||
|
||||
// NewGauge creates a new Gauge
|
||||
func NewGauge(gauge kit.Gauge) *Gauge {
|
||||
return &Gauge{gauge: gauge}
|
||||
}
|
||||
|
||||
// Update the gauge to the value passed in.
|
||||
func (g *Gauge) Update(value int64) {
|
||||
g.gauge.Set(float64(value))
|
||||
}
|
||||
|
||||
// Timer is an adapter from go-kit Histogram to jaeger-lib Timer
|
||||
type Timer struct {
|
||||
hist kit.Histogram
|
||||
}
|
||||
|
||||
// NewTimer creates a new Timer
|
||||
func NewTimer(hist kit.Histogram) *Timer {
|
||||
return &Timer{hist: hist}
|
||||
}
|
||||
|
||||
// Record saves the time passed in.
|
||||
func (t *Timer) Record(delta time.Duration) {
|
||||
t.hist.Observe(delta.Seconds())
|
||||
}
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 prometheus
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/kit/metrics"
|
||||
kitprom "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics/go-kit"
|
||||
)
|
||||
|
||||
var normalizer = strings.NewReplacer(
|
||||
".", "_",
|
||||
"-", "_",
|
||||
)
|
||||
|
||||
// NewFactory creates a new metrics factory using go-kit prometheus package.
|
||||
// buckets define the buckets into which histogram observations are counted.
|
||||
// If buckets == nil, the default value prometheus.DefBuckets is used.
|
||||
func NewFactory(namespace, subsystem string, buckets []float64) xkit.Factory {
|
||||
return &factory{
|
||||
namespace: namespace,
|
||||
subsystem: subsystem,
|
||||
buckets: buckets,
|
||||
}
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
namespace string
|
||||
subsystem string
|
||||
buckets []float64
|
||||
}
|
||||
|
||||
func (f *factory) Counter(name string) metrics.Counter {
|
||||
opts := prometheus.CounterOpts{
|
||||
Namespace: f.namespace,
|
||||
Subsystem: f.subsystem,
|
||||
Name: normalizer.Replace(name),
|
||||
Help: name,
|
||||
}
|
||||
return kitprom.NewCounterFrom(opts, nil)
|
||||
}
|
||||
|
||||
func (f *factory) Histogram(name string) metrics.Histogram {
|
||||
opts := prometheus.HistogramOpts{
|
||||
Namespace: f.namespace,
|
||||
Subsystem: f.subsystem,
|
||||
Name: normalizer.Replace(name),
|
||||
Help: name,
|
||||
Buckets: f.buckets,
|
||||
}
|
||||
return kitprom.NewHistogramFrom(opts, nil)
|
||||
}
|
||||
|
||||
func (f *factory) Gauge(name string) metrics.Gauge {
|
||||
opts := prometheus.GaugeOpts{
|
||||
Namespace: f.namespace,
|
||||
Subsystem: f.subsystem,
|
||||
Name: normalizer.Replace(name),
|
||||
Help: name,
|
||||
}
|
||||
return kitprom.NewGaugeFrom(opts, nil)
|
||||
}
|
||||
|
||||
func (f *factory) Capabilities() xkit.Capabilities {
|
||||
return xkit.Capabilities{Tagging: true}
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 multi
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics"
|
||||
)
|
||||
|
||||
// Factory is a metrics factory that dispatches to multiple metrics backends.
|
||||
type Factory struct {
|
||||
factories []metrics.Factory
|
||||
}
|
||||
|
||||
// New creates a new multi.Factory that will dispatch to multiple metrics backends.
|
||||
func New(factories ...metrics.Factory) *Factory {
|
||||
return &Factory{
|
||||
factories: factories,
|
||||
}
|
||||
}
|
||||
|
||||
type counter struct {
|
||||
counters []metrics.Counter
|
||||
}
|
||||
|
||||
func (c *counter) Inc(delta int64) {
|
||||
for _, counter := range c.counters {
|
||||
counter.Inc(delta)
|
||||
}
|
||||
}
|
||||
|
||||
// Counter implements metrics.Factory interface
|
||||
func (f *Factory) Counter(name string, tags map[string]string) metrics.Counter {
|
||||
counter := &counter{
|
||||
counters: make([]metrics.Counter, len(f.factories)),
|
||||
}
|
||||
for i, factory := range f.factories {
|
||||
counter.counters[i] = factory.Counter(name, tags)
|
||||
}
|
||||
return counter
|
||||
}
|
||||
|
||||
type timer struct {
|
||||
timers []metrics.Timer
|
||||
}
|
||||
|
||||
func (t *timer) Record(delta time.Duration) {
|
||||
for _, timer := range t.timers {
|
||||
timer.Record(delta)
|
||||
}
|
||||
}
|
||||
|
||||
// Timer implements metrics.Factory interface
|
||||
func (f *Factory) Timer(name string, tags map[string]string) metrics.Timer {
|
||||
timer := &timer{
|
||||
timers: make([]metrics.Timer, len(f.factories)),
|
||||
}
|
||||
for i, factory := range f.factories {
|
||||
timer.timers[i] = factory.Timer(name, tags)
|
||||
}
|
||||
return timer
|
||||
}
|
||||
|
||||
type gauge struct {
|
||||
gauges []metrics.Gauge
|
||||
}
|
||||
|
||||
func (t *gauge) Update(value int64) {
|
||||
for _, gauge := range t.gauges {
|
||||
gauge.Update(value)
|
||||
}
|
||||
}
|
||||
|
||||
// Gauge implements metrics.Factory interface
|
||||
func (f *Factory) Gauge(name string, tags map[string]string) metrics.Gauge {
|
||||
gauge := &gauge{
|
||||
gauges: make([]metrics.Gauge, len(f.factories)),
|
||||
}
|
||||
for i, factory := range f.factories {
|
||||
gauge.gauges[i] = factory.Gauge(name, tags)
|
||||
}
|
||||
return gauge
|
||||
}
|
||||
|
||||
// Namespace implements metrics.Factory interface
|
||||
func (f *Factory) Namespace(name string, tags map[string]string) metrics.Factory {
|
||||
newFactory := &Factory{
|
||||
factories: make([]metrics.Factory, len(f.factories)),
|
||||
}
|
||||
for i, factory := range f.factories {
|
||||
newFactory.factories[i] = factory.Namespace(name, tags)
|
||||
}
|
||||
return newFactory
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
// Copyright (c) 2017 The Jaeger 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 prometheus
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type vectorCache struct {
|
||||
registerer prometheus.Registerer
|
||||
lock sync.Mutex
|
||||
cVecs map[string]*prometheus.CounterVec
|
||||
gVecs map[string]*prometheus.GaugeVec
|
||||
hVecs map[string]*prometheus.HistogramVec
|
||||
}
|
||||
|
||||
func newVectorCache(registerer prometheus.Registerer) *vectorCache {
|
||||
return &vectorCache{
|
||||
registerer: registerer,
|
||||
cVecs: make(map[string]*prometheus.CounterVec),
|
||||
gVecs: make(map[string]*prometheus.GaugeVec),
|
||||
hVecs: make(map[string]*prometheus.HistogramVec),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *vectorCache) getOrMakeCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
cacheKey := c.getCacheKey(opts.Name, labelNames)
|
||||
cv, cvExists := c.cVecs[cacheKey]
|
||||
if !cvExists {
|
||||
cv = prometheus.NewCounterVec(opts, labelNames)
|
||||
c.registerer.MustRegister(cv)
|
||||
c.cVecs[cacheKey] = cv
|
||||
}
|
||||
return cv
|
||||
}
|
||||
|
||||
func (c *vectorCache) getOrMakeGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
cacheKey := c.getCacheKey(opts.Name, labelNames)
|
||||
gv, gvExists := c.gVecs[cacheKey]
|
||||
if !gvExists {
|
||||
gv = prometheus.NewGaugeVec(opts, labelNames)
|
||||
c.registerer.MustRegister(gv)
|
||||
c.gVecs[cacheKey] = gv
|
||||
}
|
||||
return gv
|
||||
}
|
||||
|
||||
func (c *vectorCache) getOrMakeHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
cacheKey := c.getCacheKey(opts.Name, labelNames)
|
||||
hv, hvExists := c.hVecs[cacheKey]
|
||||
if !hvExists {
|
||||
hv = prometheus.NewHistogramVec(opts, labelNames)
|
||||
c.registerer.MustRegister(hv)
|
||||
c.hVecs[cacheKey] = hv
|
||||
}
|
||||
return hv
|
||||
}
|
||||
|
||||
func (c *vectorCache) getCacheKey(name string, labels []string) string {
|
||||
return strings.Join(append([]string{name}, labels...), "||")
|
||||
}
|
||||
-216
@@ -1,216 +0,0 @@
|
||||
// Copyright (c) 2017 The Jaeger 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 prometheus
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics"
|
||||
)
|
||||
|
||||
// Factory implements metrics.Factory backed by Prometheus registry.
|
||||
type Factory struct {
|
||||
scope string
|
||||
tags map[string]string
|
||||
cache *vectorCache
|
||||
buckets []float64
|
||||
normalizer *strings.Replacer
|
||||
}
|
||||
|
||||
type options struct {
|
||||
registerer prometheus.Registerer
|
||||
buckets []float64
|
||||
}
|
||||
|
||||
// Option is a function that sets some option for the Factory constructor.
|
||||
type Option func(*options)
|
||||
|
||||
// WithRegisterer returns an option that sets the registerer.
|
||||
// If not used we fallback to prometheus.DefaultRegisterer.
|
||||
func WithRegisterer(registerer prometheus.Registerer) Option {
|
||||
return func(opts *options) {
|
||||
opts.registerer = registerer
|
||||
}
|
||||
}
|
||||
|
||||
// WithBuckets returns an option that sets the default buckets for histogram.
|
||||
// If not used, we fallback to default Prometheus buckets.
|
||||
func WithBuckets(buckets []float64) Option {
|
||||
return func(opts *options) {
|
||||
opts.buckets = buckets
|
||||
}
|
||||
}
|
||||
|
||||
func applyOptions(opts []Option) *options {
|
||||
options := new(options)
|
||||
for _, o := range opts {
|
||||
o(options)
|
||||
}
|
||||
if options.registerer == nil {
|
||||
options.registerer = prometheus.DefaultRegisterer
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
// New creates a Factory backed by Prometheus registry.
|
||||
// Typically the first argument should be prometheus.DefaultRegisterer.
|
||||
//
|
||||
// Parameter buckets defines the buckets into which Timer observations are counted.
|
||||
// Each element in the slice is the upper inclusive bound of a bucket. The
|
||||
// values must be sorted in strictly increasing order. There is no need
|
||||
// to add a highest bucket with +Inf bound, it will be added
|
||||
// implicitly. The default value is prometheus.DefBuckets.
|
||||
func New(opts ...Option) *Factory {
|
||||
options := applyOptions(opts)
|
||||
return newFactory(
|
||||
&Factory{ // dummy struct to be discarded
|
||||
cache: newVectorCache(options.registerer),
|
||||
buckets: options.buckets,
|
||||
normalizer: strings.NewReplacer(".", "_", "-", "_"),
|
||||
},
|
||||
"", // scope
|
||||
nil) // tags
|
||||
}
|
||||
|
||||
func newFactory(parent *Factory, scope string, tags map[string]string) *Factory {
|
||||
return &Factory{
|
||||
cache: parent.cache,
|
||||
buckets: parent.buckets,
|
||||
normalizer: parent.normalizer,
|
||||
scope: scope,
|
||||
tags: tags,
|
||||
}
|
||||
}
|
||||
|
||||
// Counter implements Counter of metrics.Factory.
|
||||
func (f *Factory) Counter(name string, tags map[string]string) metrics.Counter {
|
||||
name = f.subScope(name)
|
||||
tags = f.mergeTags(tags)
|
||||
labelNames := f.tagNames(tags)
|
||||
opts := prometheus.CounterOpts{
|
||||
Name: name,
|
||||
Help: name,
|
||||
}
|
||||
cv := f.cache.getOrMakeCounterVec(opts, labelNames)
|
||||
return &counter{
|
||||
counter: cv.WithLabelValues(f.tagsAsLabelValues(labelNames, tags)...),
|
||||
}
|
||||
}
|
||||
|
||||
// Gauge implements Gauge of metrics.Factory.
|
||||
func (f *Factory) Gauge(name string, tags map[string]string) metrics.Gauge {
|
||||
name = f.subScope(name)
|
||||
tags = f.mergeTags(tags)
|
||||
labelNames := f.tagNames(tags)
|
||||
opts := prometheus.GaugeOpts{
|
||||
Name: name,
|
||||
Help: name,
|
||||
}
|
||||
gv := f.cache.getOrMakeGaugeVec(opts, labelNames)
|
||||
return &gauge{
|
||||
gauge: gv.WithLabelValues(f.tagsAsLabelValues(labelNames, tags)...),
|
||||
}
|
||||
}
|
||||
|
||||
// Timer implements Timer of metrics.Factory.
|
||||
func (f *Factory) Timer(name string, tags map[string]string) metrics.Timer {
|
||||
name = f.subScope(name)
|
||||
tags = f.mergeTags(tags)
|
||||
labelNames := f.tagNames(tags)
|
||||
opts := prometheus.HistogramOpts{
|
||||
Name: name,
|
||||
Help: name,
|
||||
Buckets: f.buckets,
|
||||
}
|
||||
hv := f.cache.getOrMakeHistogramVec(opts, labelNames)
|
||||
return &timer{
|
||||
histogram: hv.WithLabelValues(f.tagsAsLabelValues(labelNames, tags)...),
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace implements Namespace of metrics.Factory.
|
||||
func (f *Factory) Namespace(name string, tags map[string]string) metrics.Factory {
|
||||
return newFactory(f, f.subScope(name), f.mergeTags(tags))
|
||||
}
|
||||
|
||||
type counter struct {
|
||||
counter prometheus.Counter
|
||||
}
|
||||
|
||||
func (c *counter) Inc(v int64) {
|
||||
c.counter.Add(float64(v))
|
||||
}
|
||||
|
||||
type gauge struct {
|
||||
gauge prometheus.Gauge
|
||||
}
|
||||
|
||||
func (g *gauge) Update(v int64) {
|
||||
g.gauge.Set(float64(v))
|
||||
}
|
||||
|
||||
type timer struct {
|
||||
histogram prometheus.Histogram
|
||||
}
|
||||
|
||||
func (t *timer) Record(v time.Duration) {
|
||||
t.histogram.Observe(float64(v.Nanoseconds()) / float64(time.Second/time.Nanosecond))
|
||||
}
|
||||
|
||||
func (f *Factory) subScope(name string) string {
|
||||
if f.scope == "" {
|
||||
return f.normalize(name)
|
||||
}
|
||||
if name == "" {
|
||||
return f.normalize(f.scope)
|
||||
}
|
||||
return f.normalize(f.scope + ":" + name)
|
||||
}
|
||||
|
||||
func (f *Factory) normalize(v string) string {
|
||||
return f.normalizer.Replace(v)
|
||||
}
|
||||
|
||||
func (f *Factory) mergeTags(tags map[string]string) map[string]string {
|
||||
ret := make(map[string]string, len(f.tags)+len(tags))
|
||||
for k, v := range f.tags {
|
||||
ret[k] = v
|
||||
}
|
||||
for k, v := range tags {
|
||||
ret[k] = v
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Factory) tagNames(tags map[string]string) []string {
|
||||
ret := make([]string, 0, len(tags))
|
||||
for k := range tags {
|
||||
ret = append(ret, k)
|
||||
}
|
||||
sort.Strings(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Factory) tagsAsLabelValues(labels []string, tags map[string]string) []string {
|
||||
ret := make([]string, 0, len(tags))
|
||||
for _, l := range labels {
|
||||
ret = append(ret, tags[l])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 tally
|
||||
|
||||
import (
|
||||
"github.com/uber-go/tally"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics"
|
||||
)
|
||||
|
||||
// Wrap takes a tally Scope and returns jaeger-lib metrics.Factory.
|
||||
func Wrap(scope tally.Scope) metrics.Factory {
|
||||
return &factory{
|
||||
tally: scope,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO implement support for tags if tally.Scope does not support them
|
||||
type factory struct {
|
||||
tally tally.Scope
|
||||
}
|
||||
|
||||
func (f *factory) Counter(name string, tags map[string]string) metrics.Counter {
|
||||
scope := f.tally
|
||||
if len(tags) > 0 {
|
||||
scope = scope.Tagged(tags)
|
||||
}
|
||||
return NewCounter(scope.Counter(name))
|
||||
}
|
||||
|
||||
func (f *factory) Gauge(name string, tags map[string]string) metrics.Gauge {
|
||||
scope := f.tally
|
||||
if len(tags) > 0 {
|
||||
scope = scope.Tagged(tags)
|
||||
}
|
||||
return NewGauge(scope.Gauge(name))
|
||||
}
|
||||
|
||||
func (f *factory) Timer(name string, tags map[string]string) metrics.Timer {
|
||||
scope := f.tally
|
||||
if len(tags) > 0 {
|
||||
scope = scope.Tagged(tags)
|
||||
}
|
||||
return NewTimer(scope.Timer(name))
|
||||
}
|
||||
|
||||
func (f *factory) Namespace(name string, tags map[string]string) metrics.Factory {
|
||||
return &factory{
|
||||
tally: f.tally.SubScope(name).Tagged(tags),
|
||||
}
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 tally
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/uber-go/tally"
|
||||
)
|
||||
|
||||
// Counter is an adapter from go-tally Counter to jaeger-lib Counter
|
||||
type Counter struct {
|
||||
counter tally.Counter
|
||||
}
|
||||
|
||||
// NewCounter creates a new Counter
|
||||
func NewCounter(counter tally.Counter) *Counter {
|
||||
return &Counter{counter: counter}
|
||||
}
|
||||
|
||||
// Inc adds the given value to the counter.
|
||||
func (c *Counter) Inc(delta int64) {
|
||||
c.counter.Inc(delta)
|
||||
}
|
||||
|
||||
// Gauge is an adapter from go-tally Gauge to jaeger-lib Gauge
|
||||
type Gauge struct {
|
||||
gauge tally.Gauge
|
||||
}
|
||||
|
||||
// NewGauge creates a new Gauge
|
||||
func NewGauge(gauge tally.Gauge) *Gauge {
|
||||
return &Gauge{gauge: gauge}
|
||||
}
|
||||
|
||||
// Update the gauge to the value passed in.
|
||||
func (g *Gauge) Update(value int64) {
|
||||
g.gauge.Update(float64(value))
|
||||
}
|
||||
|
||||
// Timer is an adapter from go-tally Histogram to jaeger-lib Timer
|
||||
type Timer struct {
|
||||
timer tally.Timer
|
||||
}
|
||||
|
||||
// NewTimer creates a new Timer
|
||||
func NewTimer(timer tally.Timer) *Timer {
|
||||
return &Timer{timer: timer}
|
||||
}
|
||||
|
||||
// Record saves the time passed in.
|
||||
func (t *Timer) Record(delta time.Duration) {
|
||||
t.timer.Record(delta)
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 testutils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/uber/jaeger-lib/metrics"
|
||||
)
|
||||
|
||||
// ExpectedMetric contains metrics under test.
|
||||
type ExpectedMetric struct {
|
||||
Name string
|
||||
Tags map[string]string
|
||||
Value int
|
||||
}
|
||||
|
||||
// TODO do something similar for Timers
|
||||
|
||||
// AssertCounterMetrics checks if counter metrics exist.
|
||||
func AssertCounterMetrics(t *testing.T, f *metrics.LocalFactory, expectedMetrics ...ExpectedMetric) {
|
||||
counters, _ := f.Snapshot()
|
||||
assertMetrics(t, counters, expectedMetrics...)
|
||||
}
|
||||
|
||||
// AssertGaugeMetrics checks if gauge metrics exist.
|
||||
func AssertGaugeMetrics(t *testing.T, f *metrics.LocalFactory, expectedMetrics ...ExpectedMetric) {
|
||||
_, gauges := f.Snapshot()
|
||||
assertMetrics(t, gauges, expectedMetrics...)
|
||||
}
|
||||
|
||||
func assertMetrics(t *testing.T, actualMetrics map[string]int64, expectedMetrics ...ExpectedMetric) {
|
||||
for _, expected := range expectedMetrics {
|
||||
key := metrics.GetKey(expected.Name, expected.Tags, "|", "=")
|
||||
assert.EqualValues(t,
|
||||
expected.Value,
|
||||
actualMetrics[key],
|
||||
"expected metric name: %s, tags: %+v", expected.Name, expected.Tags,
|
||||
)
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 sample
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SayHello is a sample function
|
||||
func SayHello() {
|
||||
fmt.Println("Hello, playground")
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
COVER=.cover
|
||||
ROOT_PKG=github.com/uber/jaeger-lib/
|
||||
|
||||
if [[ -d "$COVER" ]]; then
|
||||
rm -rf "$COVER"
|
||||
fi
|
||||
mkdir -p "$COVER"
|
||||
|
||||
# If a package directory has a .nocover file, don't count it when calculating
|
||||
# coverage.
|
||||
filter=""
|
||||
for pkg in "$@"; do
|
||||
if [[ -f "$GOPATH/src/$pkg/.nocover" ]]; then
|
||||
if [[ -n "$filter" ]]; then
|
||||
filter="$filter, "
|
||||
fi
|
||||
filter="\"$pkg\": true"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$filter" = "" ]]; then
|
||||
# make up some name to avoid breaking jq's select(in({}))
|
||||
filter='"no-filter": true'
|
||||
fi
|
||||
|
||||
i=0
|
||||
for pkg in "$@"; do
|
||||
i=$((i + 1))
|
||||
|
||||
extracoverpkg=""
|
||||
if [[ -f "$GOPATH/src/$pkg/.extra-coverpkg" ]]; then
|
||||
extracoverpkg=$( \
|
||||
sed -e "s|^|$pkg/|g" < "$GOPATH/src/$pkg/.extra-coverpkg" \
|
||||
| tr '\n' ',')
|
||||
fi
|
||||
|
||||
coverpkg=$(go list -json "$pkg" | jq -r '
|
||||
.Deps
|
||||
| . + ["'"$pkg"'"]
|
||||
| map
|
||||
( select(startswith("'"$ROOT_PKG"'"))
|
||||
| select(contains("/vendor/") | not)
|
||||
| select(in({'"$filter"'}) | not)
|
||||
)
|
||||
| join(",")
|
||||
')
|
||||
if [[ -n "$extracoverpkg" ]]; then
|
||||
coverpkg="$extracoverpkg$coverpkg"
|
||||
fi
|
||||
|
||||
args=""
|
||||
if [[ -n "$coverpkg" ]]; then
|
||||
args="-coverprofile $COVER/cover.${i}.out" # -coverpkg $coverpkg"
|
||||
fi
|
||||
|
||||
echo go test -v -race "$pkg"
|
||||
go test $args -v -race "$pkg"
|
||||
done
|
||||
|
||||
gocovmerge "$COVER"/*.out > cover.out
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
python scripts/updateLicense.py $(go list -json $(glide nv) | jq -r '.Dir + "/" + (.GoFiles | .[])')
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// 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 utils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RateLimiter is a filter used to check if a message that is worth itemCost units is within the rate limits.
|
||||
type RateLimiter interface {
|
||||
CheckCredit(itemCost float64) bool
|
||||
}
|
||||
|
||||
type rateLimiter struct {
|
||||
sync.Mutex
|
||||
|
||||
creditsPerSecond float64
|
||||
balance float64
|
||||
maxBalance float64
|
||||
lastTick time.Time
|
||||
|
||||
timeNow func() time.Time
|
||||
}
|
||||
|
||||
// NewRateLimiter creates a new rate limiter based on leaky bucket algorithm, formulated in terms of a
|
||||
// credits balance that is replenished every time CheckCredit() method is called (tick) by the amount proportional
|
||||
// to the time elapsed since the last tick, up to max of creditsPerSecond. A call to CheckCredit() takes a cost
|
||||
// of an item we want to pay with the balance. If the balance exceeds the cost of the item, the item is "purchased"
|
||||
// and the balance reduced, indicated by returned value of true. Otherwise the balance is unchanged and return false.
|
||||
//
|
||||
// This can be used to limit a rate of messages emitted by a service by instantiating the Rate Limiter with the
|
||||
// max number of messages a service is allowed to emit per second, and calling CheckCredit(1.0) for each message
|
||||
// to determine if the message is within the rate limit.
|
||||
//
|
||||
// It can also be used to limit the rate of traffic in bytes, by setting creditsPerSecond to desired throughput
|
||||
// as bytes/second, and calling CheckCredit() with the actual message size.
|
||||
func NewRateLimiter(creditsPerSecond, maxBalance float64) RateLimiter {
|
||||
return &rateLimiter{
|
||||
creditsPerSecond: creditsPerSecond,
|
||||
balance: maxBalance,
|
||||
maxBalance: maxBalance,
|
||||
lastTick: time.Now(),
|
||||
timeNow: time.Now}
|
||||
}
|
||||
|
||||
func (b *rateLimiter) CheckCredit(itemCost float64) bool {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
// calculate how much time passed since the last tick, and update current tick
|
||||
currentTime := b.timeNow()
|
||||
elapsedTime := currentTime.Sub(b.lastTick)
|
||||
b.lastTick = currentTime
|
||||
// calculate how much credit have we accumulated since the last tick
|
||||
b.balance += elapsedTime.Seconds() * b.creditsPerSecond
|
||||
if b.balance > b.maxBalance {
|
||||
b.balance = b.maxBalance
|
||||
}
|
||||
// if we have enough credits to pay for current item, then reduce balance and allow
|
||||
if b.balance >= itemCost {
|
||||
b.balance -= itemCost
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user