Skip to content

Commit

Permalink
Add meter with fabric and go version
Browse files Browse the repository at this point in the history
FAB-13190 #done

Change-Id: I038119a3f5e7c70164093788c4186ad6f50aa625
Signed-off-by: Will Lahti <wtlahti@us.ibm.com>
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
(cherry picked from commit 969faf9)
  • Loading branch information
wlahti authored and sykesm committed Dec 18, 2018
1 parent df845e0 commit f91e87c
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 22 deletions.
41 changes: 41 additions & 0 deletions core/operations/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package operations

import (
"sync"

"github.com/hyperledger/fabric/common/metrics"
"github.com/hyperledger/fabric/common/metrics/prometheus"
)

var (
fabricVersion = metrics.GaugeOpts{
Name: "fabric_version",
Help: "The active version of Fabric.",
LabelNames: []string{"version"},
StatsdFormat: "%{#fqname}.%{version}",
}

gaugeLock sync.Mutex
promVersionGauge metrics.Gauge
)

func versionGauge(provider metrics.Provider) metrics.Gauge {
switch provider.(type) {
case *prometheus.Provider:
gaugeLock.Lock()
defer gaugeLock.Unlock()
if promVersionGauge == nil {
promVersionGauge = provider.NewGauge(fabricVersion)
}
return promVersionGauge

default:
return provider.NewGauge(fabricVersion)
}
}
8 changes: 8 additions & 0 deletions core/operations/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Options struct {
ListenAddress string
Metrics MetricsOptions
TLS TLS
Version string
}

type System struct {
Expand All @@ -67,6 +68,7 @@ type System struct {
httpServer *http.Server
mux *http.ServeMux
addr string
versionGauge metrics.Gauge
}

func NewSystem(o Options) *System {
Expand Down Expand Up @@ -108,13 +110,16 @@ func (s *System) Start() error {
return err
}

s.versionGauge.With("version", s.options.Version).Set(1)

listener, err := s.listen()
if err != nil {
return err
}
s.addr = listener.Addr().String()

go s.httpServer.Serve(listener)

return nil
}

Expand Down Expand Up @@ -167,10 +172,12 @@ func (s *System) initializeMetricsProvider() error {
ks := kitstatsd.New(prefix, s)
s.Provider = &statsd.Provider{Statsd: ks}
s.statsd = ks
s.versionGauge = versionGauge(s.Provider)
return nil

case "prometheus":
s.Provider = &prometheus.Provider{}
s.versionGauge = versionGauge(s.Provider)
s.mux.Handle("/metrics", s.handlerChain(prom.Handler(), s.options.TLS.Enabled))
return nil

Expand All @@ -180,6 +187,7 @@ func (s *System) initializeMetricsProvider() error {
}

s.Provider = &disabled.Provider{}
s.versionGauge = versionGauge(s.Provider)
return nil
}
}
Expand Down
70 changes: 48 additions & 22 deletions core/operations/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ var _ = Describe("System", func() {
ClientCertRequired: false,
ClientCACertFiles: []string{filepath.Join(tempDir, "client-ca.pem")},
},
Version: "test-version",
}

system = operations.NewSystem(options)
Expand Down Expand Up @@ -239,7 +240,7 @@ var _ = Describe("System", func() {
Expect(system.Provider).To(Equal(&prometheus.Provider{}))
})

It("does hosts a secure endpoint for metrics", func() {
It("hosts a secure endpoint for metrics", func() {
err := system.Start()
Expect(err).NotTo(HaveOccurred())

Expand All @@ -256,6 +257,21 @@ var _ = Describe("System", func() {
Expect(err).NotTo(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusUnauthorized))
})

It("records the fabric version", func() {
err := system.Start()
Expect(err).NotTo(HaveOccurred())

metricsURL := fmt.Sprintf("https://%s/metrics", system.Addr())
resp, err := client.Get(metricsURL)
Expect(err).NotTo(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
Expect(err).NotTo(HaveOccurred())
Expect(string(body)).To(ContainSubstring("# TYPE fabric_version gauge"))
Expect(string(body)).To(ContainSubstring(`fabric_version{version="test-version"}`))
})
})

Context("when the metrics provider is statsd", func() {
Expand All @@ -279,6 +295,28 @@ var _ = Describe("System", func() {
Expect(system).NotTo(BeNil())
})

recordStats := func(w io.Writer) {
defer GinkgoRecover()

// handle the dial check
conn, err := listener.Accept()
if err != nil {
return
}
conn.Close()

// handle the payload
conn, err = listener.Accept()
Expect(err).NotTo(HaveOccurred())
defer conn.Close()

conn.SetReadDeadline(time.Now().Add(time.Minute))
_, err = io.Copy(w, conn)
if err != nil && err != io.EOF {
Expect(err).NotTo(HaveOccurred())
}
}

AfterEach(func() {
listener.Close()
})
Expand All @@ -291,32 +329,20 @@ var _ = Describe("System", func() {

It("emits statsd metrics", func() {
statsBuffer := gbytes.NewBuffer()
go recordStats(statsBuffer)

go func(w io.Writer) {
defer GinkgoRecover()

// handle the dial check
conn, err := listener.Accept()
if err != nil {
return
}
conn.Close()

// handle the payload
conn, err = listener.Accept()
Expect(err).NotTo(HaveOccurred())
defer conn.Close()
err := system.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(statsBuffer).Should(gbytes.Say(`\Qprefix.go.mem.gc_last_epoch_nanotime:\E`))
})

conn.SetReadDeadline(time.Now().Add(time.Minute))
_, err = io.Copy(w, conn)
if err != nil && err != io.EOF {
Expect(err).NotTo(HaveOccurred())
}
}(statsBuffer)
It("emits the fabric version statsd metric", func() {
statsBuffer := gbytes.NewBuffer()
go recordStats(statsBuffer)

err := system.Start()
Expect(err).NotTo(HaveOccurred())
Eventually(statsBuffer).Should(gbytes.Say("prefix.go.mem.gc_last_epoch_nanotime:"))
Eventually(statsBuffer).Should(gbytes.Say(`\Qprefix.fabric_version.test-version:1.000000|g\E`))
})

Context("when checking the network and address fails", func() {
Expand Down
1 change: 1 addition & 0 deletions orderer/common/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ func newOperationsSystem(ops localconfig.Operations, metrics localconfig.Metrics
ClientCertRequired: ops.TLS.ClientAuthRequired,
ClientCACertFiles: ops.TLS.ClientRootCAs,
},
Version: metadata.Version,
})
}

Expand Down
2 changes: 2 additions & 0 deletions peer/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/hyperledger/fabric/common/grpclogging"
"github.com/hyperledger/fabric/common/grpcmetrics"
"github.com/hyperledger/fabric/common/localmsp"
"github.com/hyperledger/fabric/common/metadata"
"github.com/hyperledger/fabric/common/metrics"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/viperutil"
Expand Down Expand Up @@ -886,6 +887,7 @@ func newOperationsSystem() *operations.System {
ClientCertRequired: viper.GetBool("operations.tls.clientAuthRequired"),
ClientCACertFiles: viper.GetStringSlice("operations.tls.clientRootCAs.files"),
},
Version: metadata.Version,
})
}

Expand Down

0 comments on commit f91e87c

Please sign in to comment.