forked from ligato/cn-infra
/
main.go
161 lines (133 loc) 路 4.37 KB
/
main.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"fmt"
"log"
"math/rand"
"time"
"github.com/ligato/cn-infra/agent"
"github.com/ligato/cn-infra/logging"
prom "github.com/ligato/cn-infra/rpc/prometheus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// *************************************************************************
// This example demonstrates the usage of prometheus plugin that allows
// to expose metrics.
//
// Default metrics are exposed at path /metrics on port specified for http plugin
// to access these metrics following command can be used:
// curl localhost:9191/metrics
//
// There is also created custom metrics registry exposed accessible:
// curl localhost:9191/custom
// ************************************************************************/
// PluginName represents name of plugin.
const PluginName = "example"
func main() {
// Prepare example plugin and start the agent
p := &ExamplePlugin{
Deps: Deps{
Log: logging.ForPlugin(PluginName),
Prometheus: &prom.DefaultPlugin,
},
}
a := agent.NewAgent(agent.AllPlugins(p))
if err := a.Run(); err != nil {
log.Fatal(err)
}
}
// Deps group dependencies of the ExamplePlugin
type Deps struct {
Log logging.PluginLogger
Prometheus prom.API
}
// ExamplePlugin demonstrates the usage of datasync API.
type ExamplePlugin struct {
Deps
temporaryCounter prometheus.Gauge
counterVal int
gaugeVec *prometheus.GaugeVec
}
// Identifier of the custom registry
const customRegistry = "/custom"
const orderLabel = "order"
// String return plugin name.
func (plugin *ExamplePlugin) String() string {
return PluginName
}
// Init creates metric registries and adds gauges
func (plugin *ExamplePlugin) Init() error {
// add new metric to default registry (accessible at the path /metrics)
//
// the current value is returned by provided callback
// created gauge is identified by tuple(namespace, subsystem, name) only the name field is mandatory
// additional properties can be defined using labels - key-value pairs. They do not change over time for the given gauge.
err := plugin.Prometheus.RegisterGaugeFunc(prom.DefaultRegistry, "ns", "sub", "gaugeOne",
"this metrics represents randomly generated numbers", prometheus.Labels{"Property1": "ABC", "Property2": "DEF"}, func() float64 {
return rand.Float64()
})
if err != nil {
return err
}
// create new registry that will be exposed at /custom path
err = plugin.Prometheus.NewRegistry(customRegistry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError})
if err != nil {
return err
}
// create gauge using prometheus API
plugin.temporaryCounter = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "Countdown",
Help: "This gauge is decremented by 1 each second, once it reaches 0 the gauge is removed.",
})
plugin.counterVal = 60
plugin.temporaryCounter.Set(float64(plugin.counterVal))
// register created gauge to the custom registry
err = plugin.Prometheus.Register(customRegistry, plugin.temporaryCounter)
if err != nil {
return err
}
// create gauge vector and register it
plugin.gaugeVec = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "Vector",
Help: "This gauge groups multiple similar metrics.",
ConstLabels: prometheus.Labels{"type": "vector", "answer": "42"},
}, []string{orderLabel})
err = plugin.Prometheus.Register(customRegistry, plugin.gaugeVec)
return err
}
// AfterInit starts go routines that modifies metrics
func (plugin *ExamplePlugin) AfterInit() error {
go plugin.decrementCounter()
go plugin.addNewGaugesToVector()
return nil
}
// Close cleanup resources allocated by plugin
func (plugin *ExamplePlugin) Close() error {
return nil
}
func (plugin *ExamplePlugin) addNewGaugesToVector() {
for i := 1; i < 10; i++ {
// add gauge with given labels to the vector
g, err := plugin.gaugeVec.GetMetricWith(prometheus.Labels{orderLabel: fmt.Sprint(i)})
if err != nil {
plugin.Log.Error(err)
} else {
g.Set(1)
}
time.Sleep(2 * time.Second)
}
}
func (plugin *ExamplePlugin) decrementCounter() {
for {
select {
case <-time.After(time.Second):
if plugin.counterVal == 0 {
// once the countdown reaches zero remove gauge from registry+
plugin.Prometheus.Unregister(customRegistry, plugin.temporaryCounter)
return
}
plugin.counterVal--
plugin.temporaryCounter.Set(float64(plugin.counterVal))
}
}
}