Skip to content

Commit f539f43

Browse files
committed
[FAB-6006]Add prometheus reporter in metrics module
This patchset add prometheus reporter support in metrics module, it use prometheus default method and host a http server for exposing metrics endpoint. You can pull metrics set from this endpoint. Change-Id: Id6f7b152eb57c61966f5e348e76cb46810358af6 Signed-off-by: grapebaba <281165273@qq.com>
1 parent 8cdcd5e commit f539f43

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+15774
-10
lines changed

common/metrics/service.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
)
1717

1818
const (
19-
namespace string = "hyperledger.fabric"
19+
namespace string = "hyperledger_fabric"
2020
)
2121

2222
var rootScope Scope

common/metrics/tally_provider.go

+110-3
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,25 @@ SPDX-License-Identifier: Apache-2.0
77
package metrics
88

99
import (
10+
"context"
1011
"fmt"
1112
"io"
13+
"net/http"
14+
"sort"
1215
"sync"
1316
"time"
1417

15-
"sort"
16-
1718
"github.com/cactus/go-statsd-client/statsd"
19+
"github.com/op/go-logging"
20+
prom "github.com/prometheus/client_golang/prometheus"
21+
"github.com/prometheus/client_golang/prometheus/promhttp"
1822
"github.com/uber-go/tally"
23+
promreporter "github.com/uber-go/tally/prometheus"
1924
statsdreporter "github.com/uber-go/tally/statsd"
2025
)
2126

27+
var logger = logging.MustGetLogger("common/metrics/tally")
28+
2229
var scopeRegistryKey = tally.KeyForPrefixedStringMap
2330

2431
type counter struct {
@@ -187,11 +194,33 @@ func (s *scope) SubScope(prefix string) Scope {
187194

188195
type statsdReporter struct {
189196
reporter tally.StatsReporter
197+
statter statsd.Statter
198+
}
199+
200+
type promReporter struct {
201+
reporter promreporter.Reporter
202+
server *http.Server
203+
registry *prom.Registry
190204
}
191205

192206
func newStatsdReporter(statsd statsd.Statter, opts statsdreporter.Options) tally.StatsReporter {
193207
reporter := statsdreporter.NewReporter(statsd, opts)
194-
return &statsdReporter{reporter: reporter}
208+
return &statsdReporter{reporter: reporter, statter: statsd}
209+
}
210+
211+
func newPrometheusReporter(opts promreporter.Options) promreporter.Reporter {
212+
reporter := promreporter.NewReporter(opts)
213+
//TODO:Use config instead of hard code
214+
server := &http.Server{Addr: ":8080", Handler: nil}
215+
//TODO:Return this error to caller
216+
go func() {
217+
if err := server.ListenAndServe(); err != nil {
218+
logger.Errorf("Metrics prometheus reporter start failed %s", err)
219+
}
220+
}()
221+
promReporter := &promReporter{reporter: reporter, server: server, registry: opts.Registerer.(*prom.Registry)}
222+
http.Handle("/metrics", promReporter.HTTPHandler())
223+
return promReporter
195224
}
196225

197226
func (r *statsdReporter) ReportCounter(name string, tags map[string]string, value int64) {
@@ -244,6 +273,84 @@ func (r *statsdReporter) Flush() {
244273
// no-op
245274
}
246275

276+
func (r *statsdReporter) Close() error {
277+
return r.statter.Close()
278+
}
279+
280+
func (r *promReporter) RegisterCounter(
281+
name string,
282+
tagKeys []string,
283+
desc string,
284+
) (*prom.CounterVec, error) {
285+
return r.reporter.RegisterCounter(name, tagKeys, desc)
286+
}
287+
288+
// AllocateCounter implements tally.CachedStatsReporter.
289+
func (r *promReporter) AllocateCounter(name string, tags map[string]string) tally.CachedCount {
290+
return r.reporter.AllocateCounter(name, tags)
291+
}
292+
293+
func (r *promReporter) RegisterGauge(
294+
name string,
295+
tagKeys []string,
296+
desc string,
297+
) (*prom.GaugeVec, error) {
298+
return r.reporter.RegisterGauge(name, tagKeys, desc)
299+
}
300+
301+
// AllocateGauge implements tally.CachedStatsReporter.
302+
func (r *promReporter) AllocateGauge(name string, tags map[string]string) tally.CachedGauge {
303+
return r.reporter.AllocateGauge(name, tags)
304+
}
305+
306+
func (r *promReporter) RegisterTimer(
307+
name string,
308+
tagKeys []string,
309+
desc string,
310+
opts *promreporter.RegisterTimerOptions,
311+
) (promreporter.TimerUnion, error) {
312+
return r.reporter.RegisterTimer(name, tagKeys, desc, opts)
313+
}
314+
315+
// AllocateTimer implements tally.CachedStatsReporter.
316+
func (r *promReporter) AllocateTimer(name string, tags map[string]string) tally.CachedTimer {
317+
return r.reporter.AllocateTimer(name, tags)
318+
}
319+
320+
func (r *promReporter) AllocateHistogram(
321+
name string,
322+
tags map[string]string,
323+
buckets tally.Buckets,
324+
) tally.CachedHistogram {
325+
return r.reporter.AllocateHistogram(name, tags, buckets)
326+
}
327+
328+
func (r *promReporter) Capabilities() tally.Capabilities {
329+
return r
330+
}
331+
332+
func (r *promReporter) Reporting() bool {
333+
return true
334+
}
335+
336+
func (r *promReporter) Tagging() bool {
337+
return true
338+
}
339+
340+
// Flush does nothing for prometheus
341+
func (r *promReporter) Flush() {
342+
343+
}
344+
345+
func (r *promReporter) Close() error {
346+
//TODO: Timeout here?
347+
return r.server.Shutdown(context.Background())
348+
}
349+
350+
func (r *promReporter) HTTPHandler() http.Handler {
351+
return promhttp.HandlerFor(r.registry, promhttp.HandlerOpts{})
352+
}
353+
247354
func (s *scope) fullyQualifiedName(name string) string {
248355
if len(s.prefix) == 0 {
249356
return name

common/metrics/tally_provider_test.go

+56-6
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@ SPDX-License-Identifier: Apache-2.0
77
package metrics
88

99
import (
10+
"io"
11+
"io/ioutil"
12+
"net"
13+
"net/http"
14+
"strings"
1015
"sync"
1116
"sync/atomic"
1217
"testing"
1318
"time"
1419

15-
"io"
16-
"net"
17-
"strings"
18-
1920
"github.com/cactus/go-statsd-client/statsd"
21+
"github.com/prometheus/client_golang/prometheus"
2022
"github.com/stretchr/testify/assert"
2123
"github.com/uber-go/tally"
24+
promreporter "github.com/uber-go/tally/prometheus"
2225
statsdreporter "github.com/uber-go/tally/statsd"
2326
)
2427

@@ -379,8 +382,8 @@ func TestMetricsByStatsdReporter(t *testing.T) {
379382
result := string(buffer[:n])
380383

381384
expected := []string{
382-
`hyperledger.fabric.peer.success_total.component-committer.env-test:1|c`,
383-
`hyperledger.fabric.peer.channel_total.component-committer.env-test:4|g`,
385+
`hyperledger_fabric.peer.success_total.component-committer.env-test:1|c`,
386+
`hyperledger_fabric.peer.channel_total.component-committer.env-test:4|g`,
384387
}
385388

386389
for i, res := range strings.Split(result, "\n") {
@@ -390,10 +393,57 @@ func TestMetricsByStatsdReporter(t *testing.T) {
390393
}
391394
}
392395

396+
func TestMetricsByPrometheusReporter(t *testing.T) {
397+
t.Parallel()
398+
r := newTestPrometheusReporter()
399+
400+
opts := tally.ScopeOptions{
401+
Prefix: namespace,
402+
Separator: promreporter.DefaultSeparator,
403+
CachedReporter: r}
404+
405+
s, c := newRootScope(opts, 1*time.Second)
406+
defer c.Close()
407+
408+
scrape := func() string {
409+
resp, _ := http.Get("http://localhost:8080/metrics")
410+
buf, _ := ioutil.ReadAll(resp.Body)
411+
return string(buf)
412+
}
413+
subs := s.SubScope("peer").Tagged(map[string]string{"component": "committer", "env": "test"})
414+
subs.Counter("success_total").Inc(1)
415+
subs.Gauge("channel_total").Update(4)
416+
417+
time.Sleep(2 * time.Second)
418+
419+
expected := []string{
420+
`# HELP hyperledger_fabric_peer_channel_total hyperledger_fabric_peer_channel_total gauge`,
421+
`# TYPE hyperledger_fabric_peer_channel_total gauge`,
422+
`hyperledger_fabric_peer_channel_total{component="committer",env="test"} 4`,
423+
`# HELP hyperledger_fabric_peer_success_total hyperledger_fabric_peer_success_total counter`,
424+
`# TYPE hyperledger_fabric_peer_success_total counter`,
425+
`hyperledger_fabric_peer_success_total{component="committer",env="test"} 1`,
426+
``,
427+
}
428+
429+
result := strings.Split(scrape(), "\n")
430+
431+
for i, res := range result {
432+
if res != expected[i] {
433+
t.Errorf("Got `%s`, expected `%s`", res, expected[i])
434+
}
435+
}
436+
}
437+
393438
func newTestStatsdReporter() tally.StatsReporter {
394439
statter, _ := statsd.NewBufferedClient(statsdAddr,
395440
"", 100*time.Millisecond, 512)
396441

397442
opts := statsdreporter.Options{}
398443
return newStatsdReporter(statter, opts)
399444
}
445+
446+
func newTestPrometheusReporter() promreporter.Reporter {
447+
opts := promreporter.Options{Registerer: prometheus.NewRegistry()}
448+
return newPrometheusReporter(opts)
449+
}

vendor/github.com/beorn7/perks/LICENSE

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)