A Go library which provides light-weight instrumentation for your application.
For documentation, check godoc.
This is not the Java library.
Home Page: https://github.com/dropwizard/metrics
License: MIT License
A Go library which provides light-weight instrumentation for your application.
For documentation, check godoc.
Hello,
First of all, I'm very happy to see this Go package from original Metrics author. I hope it will became the most popular implementation, and it will be easier to choose from many similar packages.
I want to use this package to count a number of active long-polling HTTP requests in my service. Counter is defined as "monotonically-increasing" integer, and its API actively resists decrements โ AddN
accepts only unit64
. I can use SetFunc
, but then I have to track number of requests separately. And I can't use Guage because there is no easy way to increment and decrement value.
Probably Counter should be redefined. Probably Gauge should allow increments and decrements. What do you think?
Use case:
We want to have a gauge to record the sending/receiving rates between a local node and remote nodes.
The remote node might come and go. So we want the ability to add/remove gauge from metrics.
Do you think it is a reasonable feature to have? I can send a pull request if it is.
I am using Counter and try to increment it from different threads simultaneously. does one or more of the increment operation can fail number of times and evantually just don't update the counter? Or does it tries to update it until it succeeds? I am asking it since I have inconsistency with two different Counters values that are supposed to have the same value because they are pretty much incremented together when a certain event happens.
I have a simple class that implements the "MetricSet" interface and in the "Map<String, Metric> getMetrics()" method I am getting the HystrixCommandMetrics instances and reporting the current metrics.
I then registered my MetricSet class via the "metrics:register" bean in my Spring configuration. I see the "getMetrics" method called once, but then it is never called again. I am using other MetricsSets, like "com.codahale.metrics.jvm.MemoryUsageGaugeSet" and they work fine. Looking at the code of the other MetricsSet classes I don't see why my class is only called once.
I must be missing something really obvious here.. Any help is appreciated.
<metrics:register metric-registry="metrics">
<bean metrics:name="jvm.gc" class="com.codahale.metrics.jvm.GarbageCollectorMetricSet" />
<bean metrics:name="jvm.memory" class="com.codahale.metrics.jvm.MemoryUsageGaugeSet" />
<bean metrics:name="jvm.thread-states" class="com.codahale.metrics.jvm.ThreadStatesGaugeSet" />
<bean metrics:name="jvm.fd.usage" class="com.codahale.metrics.jvm.FileDescriptorRatioGauge" />
<bean metrics:name="hystrix.metrics" class="com.mycompany.util.metrics.HystrixCodahaleMetricSet" />
</metrics:register>
public class HystrixCodahaleMetricSet implements MetricSet {
@Override
public Map<String, Metric> getMetrics() {
final Map<String, Metric> gauges = new HashMap<String, Metric>();
// code to add gauges left out for brevity, but is similar to that in the MemoryUsageGaugeSet class
return Collections.unmodifiableMap(gauges);
}
"Why can't I import Codahale metrics.go into Java?" - Everyone, soon
As the creation of this repository removes the redirect to dropwizard/metrics, would you mind placing a nice big note in the readme which points at the java repo?
Thanks, and godspeed :)
We observed deadlock in a program which uses codahale/metrics. Here are the relevant backtraces:
goroutine 1549 [semacquire, 828 minutes]:
sync.runtime_Semacquire(0xc878bc)
/usr/local/go/src/runtime/sema.go:47 +0x30
sync.(*Mutex).Lock(0xc878b8)
/usr/local/go/src/sync/mutex.go:85 +0xd0
github.com/codahale/metrics.Gauge.SetBatchFunc(0xc421b78940, 0x17, 0x91b5c0, 0xc4263433f0, 0xc4263433e0, 0xc421b78900)
/home/meng/prod/ghostback/src/github.com/codahale/metrics/metrics.go:122 +0x31
github.com/codahale/metrics.NewHistogram(0xc420c18080, 0x13, 0x0, 0xf4240, 0x3, 0x0)
/home/meng/prod/ghostback/src/github.com/codahale/metrics/metrics.go:212 +0x6d2
common.(*TelemetryInstance).RecordTime(0xc4203f0dc0, 0xc420c18080, 0x13, 0x11f03447)
/home/meng/prod/ghostback/src/common/telemetry.go:158 +0xfa
common.TelemetryLag(0xc420c18080, 0x13, 0x11f03447)
/home/meng/prod/ghostback/src/common/telemetry.go:182 +0x10a
common.TelemetryProcessResponse(0xc4219c2410, 0xc422b41770, 0x1478abbbaeef0ea3)
/home/meng/prod/ghostback/src/common/telemetry.go:76 +0x81
httpworker.(*Instance).incomingHandler(0xc420077680, 0xc4239587e0, 0x0, 0x0)
/home/meng/prod/ghostback/src/httpworker/worker.go:172 +0x22b
httpworker.(*Instance).(httpworker.incomingHandler)-fm(0xc4239587e0, 0xc42514f201, 0x101)
/home/meng/prod/ghostback/src/httpworker/worker.go:91 +0x34
github.com/nsqio/go-nsq.HandlerFunc.HandleMessage(0xc420888040, 0xc4239587e0, 0x94c200, 0xc420888040)
/home/meng/prod/ghostback/src/github.com/nsqio/go-nsq/consumer.go:42 +0x30
github.com/nsqio/go-nsq.(*Consumer).handlerLoop(0xc420904000, 0xc40160, 0xc420888040)
/home/meng/prod/ghostback/src/github.com/nsqio/go-nsq/consumer.go:1105 +0x14a
created by github.com/nsqio/go-nsq.(*Consumer).AddConcurrentHandlers
/home/meng/prod/ghostback/src/github.com/nsqio/go-nsq/consumer.go:1087 +0xaa
goroutine 1606087 [semacquire, 828 minutes]:
sync.runtime_Semacquire(0xc878c4)
/usr/local/go/src/runtime/sema.go:47 +0x30
sync.(*Mutex).Lock(0xc878c0)
/usr/local/go/src/sync/mutex.go:85 +0xd0
github.com/codahale/metrics.Snapshot(0x0, 0x0)
/home/meng/prod/ghostback/src/github.com/codahale/metrics/metrics.go:166 +0xd2
github.com/codahale/metrics.init.1.func1(0xc423aa1800, 0x455d50)
/home/meng/prod/ghostback/src/github.com/codahale/metrics/metrics.go:313 +0x26
expvar.Func.String(0xa36258, 0xa36210, 0xc426c8aa80)
/usr/local/go/src/expvar/expvar.go:241 +0x27
fmt.(*pp).handleMethods(0xc426c8aa80, 0x73, 0x1)
/usr/local/go/src/fmt/print.go:590 +0x2f6
fmt.(*pp).printArg(0xc426c8aa80, 0x946560, 0xa36258, 0x73)
/usr/local/go/src/fmt/print.go:665 +0x17b
fmt.(*pp).doPrintf(0xc426c8aa80, 0x9f4e7a, 0x6, 0xc42c6b5b60, 0x2, 0x2)
/usr/local/go/src/fmt/print.go:985 +0x123d
fmt.Fprintf(0xc3f560, 0xc4215b5e10, 0x9f4e7a, 0x6, 0xc42c6b5b60, 0x2, 0x2, 0x2, 0x0, 0x0)
/usr/local/go/src/fmt/print.go:181 +0x76
expvar.expvarHandler.func1(0x9f6a34, 0x7, 0xc40060, 0xa36258)
/usr/local/go/src/expvar/expvar.go:320 +0x15b
expvar.Do(0xc42c6b5c48)
/usr/local/go/src/expvar/expvar.go:307 +0xef
expvar.expvarHandler(0xc43980, 0xc4215b5e10, 0xc420a2be00)
/usr/local/go/src/expvar/expvar.go:321 +0x12b
net/http.HandlerFunc.ServeHTTP(0xa361f8, 0xc43980, 0xc4215b5e10, 0xc420a2be00)
/usr/local/go/src/net/http/server.go:1726 +0x44
net/http.(*ServeMux).ServeHTTP(0xc683e0, 0xc43980, 0xc4215b5e10, 0xc420a2be00)
/usr/local/go/src/net/http/server.go:2022 +0x7f
net/http.serverHandler.ServeHTTP(0xc42085e000, 0xc43980, 0xc4215b5e10, 0xc420a2be00)
/usr/local/go/src/net/http/server.go:2202 +0x7d
net/http.(*conn).serve(0xc421063380, 0xc44580, 0xc423ebb600)
/usr/local/go/src/net/http/server.go:1579 +0x4b7
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2293 +0x44d
One thread is creating a NewHistogram, acquires hm and tries for gm:
func NewHistogram(name string, minValue, maxValue int64, sigfigs int) *Histogram {
hm.Lock()
defer hm.Unlock()
if _, ok := histograms[name]; ok {
panic(name + " already exists")
}
hist := &Histogram{
name: name,
hist: hdrhistogram.NewWindowed(5, minValue, maxValue, sigfigs),
}
histograms[name] = hist
Gauge(name+".P50").SetBatchFunc(hname(name), hist.merge, hist.valueAt(50))
Gauge(name+".P75").SetBatchFunc(hname(name), hist.merge, hist.valueAt(75))
Gauge(name+".P90").SetBatchFunc(hname(name), hist.merge, hist.valueAt(90))
Gauge(name+".P95").SetBatchFunc(hname(name), hist.merge, hist.valueAt(95))
Gauge(name+".P99").SetBatchFunc(hname(name), hist.merge, hist.valueAt(99))
Gauge(name+".P999").SetBatchFunc(hname(name), hist.merge, hist.valueAt(99.9))
return hist
}
func (g Gauge) SetBatchFunc(key interface{}, init func(), f func() int64) {
gm.Lock()
defer gm.Unlock()
gauges[string(g)] = f
if _, ok := inits[key]; !ok {
inits[key] = init
}
}
The other thread is sampling the data, acquires gm and tries for hm:
func Snapshot() (c map[string]uint64, g map[string]int64) {
cm.Lock()
defer cm.Unlock()
gm.Lock()
defer gm.Unlock()
hm.Lock()
defer hm.Unlock()
....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.