-
Notifications
You must be signed in to change notification settings - Fork 12
/
component.go
136 lines (111 loc) · 3.91 KB
/
component.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package prometheus
// prometheus is the plugin instance responsible for collection of prometheus metrics.
// All metrics should be defined in metrics_namespace.go files with different namespace for each new collection.
// Metrics naming should follow the guidelines from: https://prometheus.io/docs/practices/naming/
// In short:
// all metrics should be in base units, do not mix units,
// add suffix describing the unit,
// use 'total' suffix for accumulating counter
import (
"context"
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/libp2p/go-libp2p/core/host"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/dig"
"github.com/iotaledger/hive.go/app"
"github.com/iotaledger/hive.go/ierrors"
"github.com/iotaledger/iota-core/components/prometheus/collector"
"github.com/iotaledger/iota-core/pkg/daemon"
"github.com/iotaledger/iota-core/pkg/protocol"
)
func init() {
Component = &app.Component{
Name: "Prometheus",
DepsFunc: func(cDeps dependencies) { deps = cDeps },
Params: params,
Provide: provide,
Configure: configure,
Run: run,
IsEnabled: func(_ *dig.Container) bool {
return ParamsMetrics.Enabled
},
}
}
// PluginName is the name of the metrics collector plugin.
var (
Component *app.Component
deps dependencies
server *http.Server
)
type dependencies struct {
dig.In
Host host.Host
Protocol *protocol.Protocol
Collector *collector.Collector
}
func provide(c *dig.Container) error {
return c.Provide(collector.New)
}
func configure() error {
if ParamsMetrics.GoMetrics {
deps.Collector.Registry.MustRegister(collectors.NewGoCollector())
}
if ParamsMetrics.ProcessMetrics {
deps.Collector.Registry.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
}
deps.Collector.RegisterCollection(TangleMetrics)
deps.Collector.RegisterCollection(ConflictMetrics)
deps.Collector.RegisterCollection(InfoMetrics)
deps.Collector.RegisterCollection(DBMetrics)
deps.Collector.RegisterCollection(CommitmentsMetrics)
deps.Collector.RegisterCollection(SlotMetrics)
deps.Collector.RegisterCollection(AccountMetrics)
deps.Collector.RegisterCollection(SchedulerMetrics)
return nil
}
func run() error {
Component.LogInfo("Starting Prometheus exporter ...")
return Component.Daemon().BackgroundWorker("Prometheus exporter", func(ctx context.Context) {
Component.LogInfo("Starting Prometheus exporter ... done")
engine := echo.New()
engine.Use(middleware.Recover())
engine.GET("/metrics", func(c echo.Context) error {
deps.Collector.Collect()
handler := promhttp.HandlerFor(
deps.Collector.Registry,
promhttp.HandlerOpts{
EnableOpenMetrics: true,
},
)
if ParamsMetrics.PromhttpMetrics {
handler = promhttp.InstrumentMetricHandler(deps.Collector.Registry, handler)
}
handler.ServeHTTP(c.Response().Writer, c.Request())
return nil
})
bindAddr := ParamsMetrics.BindAddress
server = &http.Server{Addr: bindAddr, Handler: engine, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second}
go func() {
Component.LogInfof("You can now access the Prometheus exporter using: http://%s/metrics", bindAddr)
if err := server.ListenAndServe(); err != nil && !ierrors.Is(err, http.ErrServerClosed) {
Component.LogError("Stopping Prometheus exporter due to an error ... done")
}
}()
<-ctx.Done()
Component.LogInfo("Stopping Prometheus exporter ...")
shutdownCtx, shutdownCtxCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer shutdownCtxCancel()
// shutdown collector to stop all pruning executors
deps.Collector.Shutdown()
//nolint:contextcheck // false positive
err := server.Shutdown(shutdownCtx)
if err != nil {
Component.LogWarn(err.Error())
}
Component.LogInfo("Stopping Prometheus exporter ... done")
}, daemon.PriorityMetrics)
}