Skip to content

Commit cad437c

Browse files
committed
updated vendor files
Signed-off-by: Genady Gurevich <genadyg@il.ibm.com>
1 parent 5925cac commit cad437c

File tree

346 files changed

+52425
-2132
lines changed

Some content is hidden

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

346 files changed

+52425
-2132
lines changed

common/monitoring/monitor.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package monitoring
8+
9+
import (
10+
"context"
11+
"fmt"
12+
"net"
13+
"time"
14+
15+
"github.com/hyperledger/fabric-lib-go/common/flogging"
16+
"github.com/hyperledger/fabric-x-orderer/common/types"
17+
)
18+
19+
type MonitoringMetric struct {
20+
Interval time.Duration
21+
Value *uint64
22+
Labels []string
23+
}
24+
25+
type Monitor struct {
26+
Provider *Provider
27+
logger types.Logger
28+
endpoint Endpoint
29+
// stop is used to stop the monitoring service
30+
stop context.CancelFunc
31+
listener net.Listener
32+
}
33+
34+
func NewMonitor(endpoint Endpoint, prefix string) *Monitor {
35+
logger := flogging.MustGetLogger(fmt.Sprintf("%s.monitoring", prefix))
36+
return &Monitor{Provider: NewProvider(logger), endpoint: endpoint, logger: logger}
37+
}
38+
39+
func (m *Monitor) Start() {
40+
ctx, cancel := context.WithCancel(context.Background())
41+
m.stop = cancel
42+
43+
var err error
44+
serverConfig := ServerConfig{Endpoint: &m.endpoint, logger: m.logger}
45+
m.listener, err = serverConfig.Listener()
46+
if err != nil {
47+
m.logger.Panicf("%v", err)
48+
}
49+
m.endpoint.Port = serverConfig.Endpoint.Port
50+
51+
go func() {
52+
m.Provider.StartPrometheusServer(ctx, m.listener)
53+
}()
54+
}
55+
56+
func (m *Monitor) Stop() {
57+
if m.stop != nil {
58+
m.stop()
59+
}
60+
if m.listener != nil {
61+
m.listener.Close()
62+
}
63+
}
64+
65+
func (m *Monitor) Address() string {
66+
return fmt.Sprintf("http://%s/metrics", m.endpoint.Address())
67+
}

common/monitoring/provider.go

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package monitoring
8+
9+
import (
10+
"context"
11+
"net"
12+
"net/http"
13+
"net/url"
14+
"time"
15+
16+
kitmetrics "github.com/go-kit/kit/metrics"
17+
"github.com/go-kit/kit/metrics/prometheus"
18+
"github.com/hyperledger/fabric-lib-go/common/metrics"
19+
"github.com/hyperledger/fabric-x-orderer/common/types"
20+
"github.com/pkg/errors"
21+
prom "github.com/prometheus/client_golang/prometheus"
22+
"github.com/prometheus/client_golang/prometheus/promhttp"
23+
"golang.org/x/sync/errgroup"
24+
)
25+
26+
const (
27+
scheme = "http://"
28+
metricsSubPath = "/metrics"
29+
)
30+
31+
// Provider is a prometheus metrics provider.
32+
type Provider struct {
33+
logger types.Logger
34+
url string
35+
}
36+
37+
// NewProvider creates a new prometheus metrics provider.
38+
func NewProvider(logger types.Logger) *Provider {
39+
return &Provider{logger: logger}
40+
}
41+
42+
// StartPrometheusServer starts a prometheus server.
43+
// It also starts the given monitoring methods. Their context will cancel once the server is cancelled.
44+
// This method returns once the server is shutdown and all monitoring methods returns.
45+
func (p *Provider) StartPrometheusServer(
46+
ctx context.Context, listener net.Listener, monitor ...func(context.Context),
47+
) error {
48+
p.logger.Debugf("Creating prometheus server")
49+
mux := http.NewServeMux()
50+
mux.Handle(
51+
metricsSubPath,
52+
promhttp.Handler(),
53+
)
54+
server := &http.Server{
55+
ReadTimeout: 30 * time.Second,
56+
Handler: mux,
57+
}
58+
59+
// l, err := serverConfig.Listener()
60+
// if err != nil {
61+
// return errors.Wrap(err, "failed to start prometheus server")
62+
// }
63+
// defer l.Close()
64+
65+
var err error
66+
p.url, err = MakeMetricsURL(listener.Addr().String())
67+
if err != nil {
68+
return errors.Wrap(err, "failed formatting URL")
69+
}
70+
71+
g, gCtx := errgroup.WithContext(ctx)
72+
g.Go(func() error {
73+
p.logger.Infof("Prometheus serving on URL: %s", p.url)
74+
defer p.logger.Infof("Prometheus stopped serving")
75+
return server.Serve(listener)
76+
})
77+
78+
// The following ensures the method does not return before all monitor methods return.
79+
for _, m := range monitor {
80+
g.Go(func() error {
81+
m(gCtx)
82+
return nil
83+
})
84+
}
85+
86+
// The following ensures the method does not return before the close procedure is complete.
87+
stopAfter := context.AfterFunc(ctx, func() {
88+
g.Go(func() error {
89+
if errClose := server.Close(); err != nil {
90+
return errors.Wrap(errClose, "failed to close prometheus server")
91+
}
92+
return nil
93+
})
94+
})
95+
defer stopAfter()
96+
97+
if err = g.Wait(); !errors.Is(err, http.ErrServerClosed) {
98+
return errors.Wrap(err, "prometheus server stopped with an error")
99+
}
100+
return nil
101+
}
102+
103+
// URL returns the prometheus server URL.
104+
func (p *Provider) URL() string {
105+
return p.url
106+
}
107+
108+
// MakeMetricsURL construct the Prometheus metrics URL.
109+
func MakeMetricsURL(address string) (string, error) {
110+
return url.JoinPath(scheme, address, metricsSubPath)
111+
}
112+
113+
func (p *Provider) NewCounter(o metrics.CounterOpts) metrics.Counter {
114+
return &Counter{
115+
Counter: prometheus.NewCounterFrom(
116+
prom.CounterOpts{
117+
Namespace: o.Namespace,
118+
Subsystem: o.Subsystem,
119+
Name: o.Name,
120+
Help: o.Help,
121+
},
122+
o.LabelNames,
123+
),
124+
}
125+
}
126+
127+
func (p *Provider) NewGauge(o metrics.GaugeOpts) metrics.Gauge {
128+
return &Gauge{
129+
Gauge: prometheus.NewGaugeFrom(
130+
prom.GaugeOpts{
131+
Namespace: o.Namespace,
132+
Subsystem: o.Subsystem,
133+
Name: o.Name,
134+
Help: o.Help,
135+
},
136+
o.LabelNames,
137+
),
138+
}
139+
}
140+
141+
func (p *Provider) NewHistogram(o metrics.HistogramOpts) metrics.Histogram {
142+
return &Histogram{
143+
Histogram: prometheus.NewHistogramFrom(
144+
prom.HistogramOpts{
145+
Namespace: o.Namespace,
146+
Subsystem: o.Subsystem,
147+
Name: o.Name,
148+
Help: o.Help,
149+
Buckets: o.Buckets,
150+
},
151+
o.LabelNames,
152+
),
153+
}
154+
}
155+
156+
type Counter struct{ kitmetrics.Counter }
157+
158+
func (c *Counter) With(labelValues ...string) metrics.Counter {
159+
return &Counter{Counter: c.Counter.With(labelValues...)}
160+
}
161+
162+
type Gauge struct{ kitmetrics.Gauge }
163+
164+
func (g *Gauge) With(labelValues ...string) metrics.Gauge {
165+
return &Gauge{Gauge: g.Gauge.With(labelValues...)}
166+
}
167+
168+
type Histogram struct{ kitmetrics.Histogram }
169+
170+
func (h *Histogram) With(labelValues ...string) metrics.Histogram {
171+
return &Histogram{Histogram: h.Histogram.With(labelValues...)}
172+
}

common/monitoring/server_util.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package monitoring
8+
9+
import (
10+
"net"
11+
"os/exec"
12+
"strconv"
13+
"strings"
14+
15+
"github.com/hyperledger/fabric-x-orderer/common/types"
16+
"github.com/pkg/errors"
17+
)
18+
19+
const protocol = "tcp"
20+
21+
type Endpoint struct {
22+
Host string
23+
Port int
24+
}
25+
26+
// Address returns a string representation of the endpoint's address.
27+
func (e *Endpoint) Address() string {
28+
return net.JoinHostPort(e.Host, strconv.Itoa(e.Port))
29+
}
30+
31+
type ServerConfig struct {
32+
Endpoint *Endpoint
33+
preAllocatedListener net.Listener
34+
logger types.Logger
35+
}
36+
37+
// Listener instantiate a [net.Listener] and updates the config port with the effective port.
38+
func (s *ServerConfig) Listener() (net.Listener, error) {
39+
if s.preAllocatedListener != nil {
40+
return s.preAllocatedListener, nil
41+
}
42+
listener, err := net.Listen(protocol, s.Endpoint.Address())
43+
if err != nil {
44+
return nil, errors.Wrap(err, "failed to listen")
45+
}
46+
47+
addr := listener.Addr()
48+
tcpAddress, ok := addr.(*net.TCPAddr)
49+
if !ok {
50+
return nil, errors.New(strings.Join([]string{"failed to cast to TCP address", listener.Close().Error()}, "; "))
51+
}
52+
s.Endpoint.Port = tcpAddress.Port
53+
54+
s.logger.Infof("Listening on: %s://%s", protocol, s.Endpoint.Address())
55+
return listener, nil
56+
}
57+
58+
// PreAllocateListener is used to allocate a port and bind to ahead of the server initialization.
59+
// It stores the listener object internally to be reused on subsequent calls to Listener().
60+
func (c *ServerConfig) PreAllocateListener() (net.Listener, error) {
61+
listener, err := c.Listener()
62+
if err != nil {
63+
return nil, err
64+
}
65+
c.preAllocatedListener = listener
66+
return listener, nil
67+
}
68+
69+
func FQDN() (string, error) {
70+
out, err := exec.Command("hostname", "--fqdn").Output()
71+
if err != nil {
72+
return "", err
73+
}
74+
return string(out), nil
75+
}

0 commit comments

Comments
 (0)