Skip to content

Commit

Permalink
Add toolkit package
Browse files Browse the repository at this point in the history
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 <superq@gmail.com>
  • Loading branch information
SuperQ committed Apr 1, 2023
1 parent f42e5c7 commit 6782d2c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
6 changes: 5 additions & 1 deletion web/kingpinflag/flag.go → flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package kingpinflag
package toolkit

import (
"runtime"
Expand All @@ -31,6 +31,10 @@ func AddFlags(a *kingpin.Application, defaultAddress string) *web.FlagConfig {
).Bool()
}
flags := web.FlagConfig{
MetricsPath: a.Flag(
"web.telemetry-path",
"Path under which to expose metrics.",
).Default("/metrics").String(),
WebListenAddresses: a.Flag(
"web.listen-address",
"Addresses on which to expose metrics and web interface. Repeatable for multiple addresses.",
Expand Down
66 changes: 66 additions & 0 deletions toolkit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2023 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package toolkit

import (
"errors"
"net/http"
"os"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/exporter-toolkit/web"
)

var ErrNoFlagConfig = errors.New("Missing FlagConfig")

type Config struct {
MetricsHandler http.Handler
MetricsHandlerFunc *func(http.ResponseWriter, *http.Request)
FlagConfig *web.FlagConfig
LandingConfig web.LandingConfig
Logger log.Logger
}

func Run(c Config) error {
if c.FlagConfig == nil {
return ErrNoFlagConfig
}
err := c.FlagConfig.CheckFlags()
if err != nil {
return err
}
if *c.FlagConfig.MetricsPath != "" && c.MetricsHandler != nil {
http.Handle(*c.FlagConfig.MetricsPath, c.MetricsHandler)
}
if *c.FlagConfig.MetricsPath != "" && c.MetricsHandlerFunc != nil {
http.HandleFunc(*c.FlagConfig.MetricsPath, *c.MetricsHandlerFunc)
}
if *c.FlagConfig.MetricsPath != "/" && *c.FlagConfig.MetricsPath != "" {
c.LandingConfig.Links = append(c.LandingConfig.Links,
web.LandingLinks{
Address: *c.FlagConfig.MetricsPath,
Text: "Metrics",
},
)
landingPage, err := web.NewLandingPage(c.LandingConfig)
if err != nil {
level.Error(c.Logger).Log("err", err)
os.Exit(1)
}
http.Handle("/", landingPage)
}

srv := &http.Server{}
return web.ListenAndServe(srv, c.FlagConfig, c.Logger)
}
21 changes: 19 additions & 2 deletions web/tls_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
var (
errNoTLSConfig = errors.New("TLS config is not present")
ErrNoListeners = errors.New("no web listen address or systemd socket flag specified")
ErrMissingFlag = errors.New("Flag config is empty")
)

type Config struct {
Expand All @@ -55,11 +56,26 @@ type TLSConfig struct {
}

type FlagConfig struct {
MetricsPath *string
WebListenAddresses *[]string
WebSystemdSocket *bool
WebConfigFile *string
}

// CheckFlags validates that the FlagConfig has all required values set and has at least one listener.
func (c *FlagConfig) CheckFlags() error {
if c.MetricsPath == nil {
return ErrMissingFlag
}
if c.WebSystemdSocket == nil && (c.WebListenAddresses == nil || len(*c.WebListenAddresses) == 0) {
return ErrNoListeners
}
if c.WebConfigFile == nil {
return ErrMissingFlag
}
return nil
}

// SetDirectory joins any relative file paths with dir.
func (t *TLSConfig) SetDirectory(dir string) {
t.TLSCertPath = config_util.JoinDir(dir, t.TLSCertPath)
Expand Down Expand Up @@ -204,8 +220,9 @@ func ServeMultiple(listeners []net.Listener, server *http.Server, flags *FlagCon
// WebSystemdSocket in the FlagConfig is true. The FlagConfig is also passed on
// to ServeMultiple.
func ListenAndServe(server *http.Server, flags *FlagConfig, logger log.Logger) error {
if flags.WebSystemdSocket == nil && (flags.WebListenAddresses == nil || len(*flags.WebListenAddresses) == 0) {
return ErrNoListeners
err := flags.CheckFlags()
if err != nil {
return err
}

if flags.WebSystemdSocket != nil && *flags.WebSystemdSocket {
Expand Down

0 comments on commit 6782d2c

Please sign in to comment.