Git Product home page Git Product logo

metrics's Introduction

metrics

Build Status

A Go library which provides light-weight instrumentation for your application.

For documentation, check godoc.

metrics's People

Contributors

adrianco avatar aldrinleal avatar andrew-stripe avatar codahale avatar collinvandyck avatar cryptix avatar jack-stripe avatar kr avatar ksedgwic avatar taylorchu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metrics's Issues

How to count active requests?

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?

feature request: remove a registered gauge/counter from metrics

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.

Does a counter inc operation can fail?

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.

MetricSet is only called once

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);
}

Massive amounts of confusion ensues

"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 :)

NewHistogram vs Snapshot deadlock

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()

    ....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.