Skip to content

Commit 7be1270

Browse files
committed
restructured code and docs
1 parent ce81284 commit 7be1270

File tree

3 files changed

+134
-51
lines changed

3 files changed

+134
-51
lines changed

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
11
# ONE exporter
22

3-
Prometheus exporter for Open Nebula clusters, written in Go.
3+
Prometheus exporter for OpenNebula clusters, written in Go.
4+
5+
6+
## Use
7+
8+
You can run the one exporter with the `-c` flag pointing to its configuration file. If you don't include a configuration file, the exporter will use the config.yml in current directory, so `./one_exporter` and `./one_exporter -c config.yml` are identical.
9+
10+
Use the `--help` flag for more information.
11+
12+
13+
## Configuration
14+
15+
The one exporter uses the following parameters in the configuration file.
16+
17+
```yaml
18+
19+
# credentials to access OpenNebula
20+
user: oneadmin
21+
password: oneadmin
22+
23+
# OpenNebula frontend endpoint
24+
# an empty endpoint will default to http://localhost:2633/RPC2
25+
# endpoint:
26+
27+
# frequency to retrieve metrics in seconds. defaults to 60.
28+
# interval: 60
29+
30+
# FQDN and port to run the exporter on
31+
host: frontend.server.com
32+
port: 9615
33+
34+
# exporter uri to publish on. defaults to /metrics
35+
# path: /metrics
36+
37+
```

config.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
---
22

3-
# credentials to access Open Nebula
3+
# credentials to access OpenNebula
44
user: oneadmin
55
password: oneadmin
66

7+
# OpenNebula frontend endpoint
8+
# an empty endpoint will default to http://localhost:2633/RPC2
9+
# endpoint:
10+
11+
# frequency to retrieve metrics in seconds. defaults to 60.
12+
# interval: 60
13+
714
# FQDN and port to run the exporter on
8-
host: ubuntu
15+
host: frontend.server.com
916
port: 9615
17+
18+
# exporter uri to publish on. defaults to /metrics
19+
# path: /metrics
20+

one_exporter.go

Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
// Prometheus exporter for Open Nebula.
1+
// Prometheus exporter for OpenNebula.
22
package main
33

44
import (
5-
65
"net/http"
76
"os"
87
"path"
98
"strconv"
9+
"strings"
1010
"time"
1111

1212
"github.com/go-kit/kit/log"
1313
"github.com/go-kit/kit/log/level"
1414

1515
"github.com/OpenNebula/one/src/oca/go/src/goca"
16-
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/host"
1716

1817
"github.com/prometheus/client_golang/prometheus"
1918
"github.com/prometheus/client_golang/prometheus/promauto"
@@ -24,39 +23,59 @@ import (
2423
"gopkg.in/alecthomas/kingpin.v2"
2524
)
2625

27-
var (
26+
type config struct {
27+
user string
28+
password string
29+
endpoint string
30+
interval int
31+
host string
32+
port int
33+
path string
34+
}
2835

36+
var (
2937
poolTotalMemGauge = promauto.NewGauge(prometheus.GaugeOpts{
3038
Name: "one_pool_totalmem",
31-
Help: "total memory of all hosts in open nebula",
39+
Help: "total memory of all hosts in opennebula",
3240
})
3341
poolUsedMemGauge = promauto.NewGauge(prometheus.GaugeOpts{
3442
Name: "one_pool_usedmem",
35-
Help: "used memory in all hosts in open nebula",
43+
Help: "used memory in all hosts in opennebula",
3644
})
3745
poolTotalCPUGauge = promauto.NewGauge(prometheus.GaugeOpts{
3846
Name: "one_pool_totalcpu",
39-
Help: "total cpu of all hosts in open nebula",
47+
Help: "total cpu of all hosts in opennebula",
4048
})
4149
poolUsedCPUGauge = promauto.NewGauge(prometheus.GaugeOpts{
4250
Name: "one_pool_usedcpu",
43-
Help: "used cpu in all hosts in open nebula",
51+
Help: "used cpu in all hosts in opennebula",
4452
})
4553
poolActiveHostsGauge = promauto.NewGauge(prometheus.GaugeOpts{
4654
Name: "one_pool_activehosts",
47-
Help: "number of active hosts in open nebula",
55+
Help: "number of active hosts in opennebula",
4856
})
4957
poolRunningVMsGauge = promauto.NewGauge(prometheus.GaugeOpts{
5058
Name: "one_pool_runningvms",
51-
Help: "number of running virtual machines in open nebula",
59+
Help: "number of running virtual machines in opennebula",
5260
})
5361
)
5462

55-
func recordMetrics(pool *host.Pool, logger log.Logger) {
63+
// recordMetrics from OpenNebula
64+
func recordMetrics(config config, logger log.Logger) {
5665

57-
level.Info(logger).Log("msg", "recording metrics from open nebula frontend")
66+
level.Info(logger).Log("msg", "recording metrics from opennebula frontend", "interval", config.interval)
67+
68+
client := goca.NewDefaultClient(goca.NewConfig(config.user, config.password, config.endpoint))
69+
controller := goca.NewController(client)
5870

5971
for {
72+
73+
pool, err := controller.Hosts().Info()
74+
if err != nil {
75+
level.Error(logger).Log("msg", "error retrieving hosts info", "error", err)
76+
panic(err)
77+
}
78+
6079
var totalMem int = 0
6180
var usedMem int = 0
6281
var totalCPU int = 0
@@ -67,7 +86,13 @@ func recordMetrics(pool *host.Pool, logger log.Logger) {
6786

6887
for _, host := range pool.Hosts {
6988

70-
level.Debug(logger).Log("msg", "host metrics", "host", host.Name)
89+
level.Debug(logger).Log("msg", "host metrics",
90+
"host", host.Name,
91+
"TotalMem", host.Share.TotalMem,
92+
"UsedMem", host.Share.UsedMem,
93+
"TotalCPU", host.Share.TotalCPU,
94+
"UsedCPU", host.Share.UsedCPU,
95+
"RunningVMs", host.Share.RunningVMs)
7196

7297
totalMem = totalMem + host.Share.TotalMem
7398
usedMem = usedMem + host.Share.UsedMem
@@ -88,65 +113,78 @@ func recordMetrics(pool *host.Pool, logger log.Logger) {
88113

89114
poolActiveHostsGauge.Set(float64(activeHosts))
90115

91-
time.Sleep(30 * time.Second)
116+
time.Sleep(time.Duration(config.interval) * time.Second)
92117
}
93118
}
94119

95-
func main() {
120+
func newConfig(fileName string, logger log.Logger) config {
96121

97-
var (
98-
user string
99-
password string
100-
host string
101-
port string
102-
)
122+
viper.SetDefault("endpoint", "") // "" will be set to "http://localhost:2633/RPC2" by goca
123+
viper.SetDefault("interval", 60)
124+
viper.SetDefault("path", "/metrics")
125+
viper.SetDefault("port", 9615)
103126

104-
logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
105-
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
106-
107-
level.Info(logger).Log("msg", "starting exporter for Open Nebula")
108-
109-
config := kingpin.Flag("config", "config file for one_exporter").Short('c').String()
110-
kingpin.Parse()
111127

112128
viper.SetConfigType("yaml")
113129
viper.AddConfigPath(".")
114130

115-
if *config != "" {
116-
level.Info(logger).Log("msg", "using provided configuration file", "config", *config)
131+
if fileName != "" {
132+
level.Info(logger).Log("msg", "using provided configuration file", "file", fileName)
117133

118-
dir, file := path.Split(*config)
134+
dir, file := path.Split(fileName)
119135
viper.SetConfigName(file)
120136
viper.AddConfigPath(dir)
121137
}
122138

123139
err := viper.ReadInConfig()
124140
if err != nil {
125141
level.Error(logger).Log("msg", "error reading config file", "error", err)
126-
return
142+
panic(err)
127143
}
128144

129-
user = viper.Get("user").(string)
130-
password = viper.Get("password").(string)
131-
host = viper.Get("host").(string)
132-
port = strconv.Itoa(viper.Get("port").(int))
145+
return config{
146+
user: viper.Get("user").(string),
147+
password: viper.Get("password").(string),
148+
endpoint: "",
149+
interval: viper.Get("interval").(int),
150+
host: viper.Get("host").(string),
151+
port: viper.Get("port").(int),
152+
path: viper.Get("path").(string),
153+
}
133154

134-
level.Info(logger).Log("msg", "using config:", "user", user, "host", host, "port", port)
155+
}
135156

136-
conf := goca.NewConfig( user, password, "")
137-
client := goca.NewDefaultClient(conf)
138-
controller := goca.NewController(client)
157+
func allowedLevel(logLevel string) level.Option {
139158

140-
pool, err := controller.Hosts().Info()
141-
if err != nil {
142-
level.Error(logger).Log("msg", "error retrieving hosts info", "error", err)
143-
return
159+
switch strings.ToLower(logLevel) {
160+
case "error":
161+
return level.AllowError()
162+
case "debug":
163+
return level.AllowDebug()
164+
default:
165+
return level.AllowInfo()
144166
}
167+
}
168+
169+
func main() {
170+
171+
logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
172+
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
173+
174+
cfgFile := kingpin.Flag("config", "config file for one_exporter").Short('c').String()
175+
logLevel := kingpin.Flag("loglevel", "the log level to output. options are error, info or debug. defaults to info").Short('l').Default("info").String()
176+
kingpin.Parse()
177+
178+
logger = level.NewFilter(logger, allowedLevel(*logLevel))
179+
level.Info(logger).Log("msg", "starting exporter for OpenNebula")
180+
181+
config := newConfig(*cfgFile, logger)
182+
level.Debug(logger).Log("msg", "loaded config", "user", config.user, "endpoint", config.endpoint)
145183

146-
go recordMetrics(pool, logger)
184+
go recordMetrics(config, logger)
147185

148-
level.Info(logger).Log("msg", "starting exporter on endpoint /metrics")
149-
http.Handle("/metrics", promhttp.Handler())
150-
http.ListenAndServe(host + ":" + port, nil)
186+
level.Info(logger).Log("msg", "starting exporter", "host", config.host, "port", config.port, "path", config.path)
187+
http.Handle(config.path, promhttp.Handler())
188+
http.ListenAndServe(config.host+":"+strconv.Itoa(config.port), nil)
151189

152190
}

0 commit comments

Comments
 (0)