Skip to content

Commit 6557753

Browse files
committed
Add toolkit package
Implement a top level package to make it easy to bootstrap an exporter. * Move the flag package to the top level. * Add support for `--web.telemetry-path` flag. Defaults to`/metrics`. * Add a self-check function to the web FlagConfig. Signed-off-by: SuperQ <[email protected]>
1 parent f42e5c7 commit 6557753

File tree

3 files changed

+100
-3
lines changed

3 files changed

+100
-3
lines changed

web/kingpinflag/flag.go renamed to flag.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
13-
package kingpinflag
13+
package toolkit
1414

1515
import (
1616
"runtime"
@@ -31,6 +31,10 @@ func AddFlags(a *kingpin.Application, defaultAddress string) *web.FlagConfig {
3131
).Bool()
3232
}
3333
flags := web.FlagConfig{
34+
MetricsPath: a.Flag(
35+
"web.telemetry-path",
36+
"Path under which to expose metrics.",
37+
).Default("/metrics").String(),
3438
WebListenAddresses: a.Flag(
3539
"web.listen-address",
3640
"Addresses on which to expose metrics and web interface. Repeatable for multiple addresses.",

toolkit.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2023 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
package toolkit
14+
15+
import (
16+
"errors"
17+
"net/http"
18+
"os"
19+
20+
"github.com/go-kit/log"
21+
"github.com/go-kit/log/level"
22+
"github.com/prometheus/exporter-toolkit/web"
23+
)
24+
25+
var (
26+
ErrNoFlagConfig = errors.New("Missing FlagConfig")
27+
ErrNoHandler = errors.New("Missing one of MetricsHandler or MetricsHandlerFunc")
28+
ErrOneHandler = errors.New("Only one of MetricsHandler or MetricsHandlerFunc allowed")
29+
)
30+
31+
type Config struct {
32+
MetricsHandler http.Handler
33+
MetricsHandlerFunc *func(http.ResponseWriter, *http.Request)
34+
FlagConfig *web.FlagConfig
35+
LandingConfig web.LandingConfig
36+
Logger log.Logger
37+
}
38+
39+
func Run(c Config) error {
40+
if c.FlagConfig == nil {
41+
return ErrNoFlagConfig
42+
}
43+
err := c.FlagConfig.CheckFlags()
44+
if err != nil {
45+
return err
46+
}
47+
if c.MetricsHandler == nil && c.MetricsHandlerFunc == nil {
48+
return ErrNoHandler
49+
}
50+
if c.MetricsHandler != nil && c.MetricsHandlerFunc != nil {
51+
return ErrOneHandler
52+
}
53+
if *c.FlagConfig.MetricsPath != "" && c.MetricsHandler != nil {
54+
http.Handle(*c.FlagConfig.MetricsPath, c.MetricsHandler)
55+
}
56+
if *c.FlagConfig.MetricsPath != "" && c.MetricsHandlerFunc != nil {
57+
http.HandleFunc(*c.FlagConfig.MetricsPath, *c.MetricsHandlerFunc)
58+
}
59+
if *c.FlagConfig.MetricsPath != "/" && *c.FlagConfig.MetricsPath != "" {
60+
c.LandingConfig.Links = append(c.LandingConfig.Links,
61+
web.LandingLinks{
62+
Address: *c.FlagConfig.MetricsPath,
63+
Text: "Metrics",
64+
},
65+
)
66+
landingPage, err := web.NewLandingPage(c.LandingConfig)
67+
if err != nil {
68+
level.Error(c.Logger).Log("err", err)
69+
os.Exit(1)
70+
}
71+
http.Handle("/", landingPage)
72+
}
73+
74+
srv := &http.Server{}
75+
return web.ListenAndServe(srv, c.FlagConfig, c.Logger)
76+
}

web/tls_config.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
var (
3535
errNoTLSConfig = errors.New("TLS config is not present")
3636
ErrNoListeners = errors.New("no web listen address or systemd socket flag specified")
37+
ErrMissingFlag = errors.New("Flag config is empty")
3738
)
3839

3940
type Config struct {
@@ -55,11 +56,26 @@ type TLSConfig struct {
5556
}
5657

5758
type FlagConfig struct {
59+
MetricsPath *string
5860
WebListenAddresses *[]string
5961
WebSystemdSocket *bool
6062
WebConfigFile *string
6163
}
6264

65+
// CheckFlags validates that the FlagConfig has all required values set and has at least one listener.
66+
func (c *FlagConfig) CheckFlags() error {
67+
if c.MetricsPath == nil {
68+
return ErrMissingFlag
69+
}
70+
if c.WebSystemdSocket == nil && (c.WebListenAddresses == nil || len(*c.WebListenAddresses) == 0) {
71+
return ErrNoListeners
72+
}
73+
if c.WebConfigFile == nil {
74+
return ErrMissingFlag
75+
}
76+
return nil
77+
}
78+
6379
// SetDirectory joins any relative file paths with dir.
6480
func (t *TLSConfig) SetDirectory(dir string) {
6581
t.TLSCertPath = config_util.JoinDir(dir, t.TLSCertPath)
@@ -204,8 +220,9 @@ func ServeMultiple(listeners []net.Listener, server *http.Server, flags *FlagCon
204220
// WebSystemdSocket in the FlagConfig is true. The FlagConfig is also passed on
205221
// to ServeMultiple.
206222
func ListenAndServe(server *http.Server, flags *FlagConfig, logger log.Logger) error {
207-
if flags.WebSystemdSocket == nil && (flags.WebListenAddresses == nil || len(*flags.WebListenAddresses) == 0) {
208-
return ErrNoListeners
223+
err := flags.CheckFlags()
224+
if err != nil {
225+
return err
209226
}
210227

211228
if flags.WebSystemdSocket != nil && *flags.WebSystemdSocket {

0 commit comments

Comments
 (0)