Skip to content
This repository was archived by the owner on Sep 1, 2024. It is now read-only.

Commit b97f88e

Browse files
committed
add support for prometheus exporter-toolkit web config
1 parent 1238e98 commit b97f88e

File tree

701 files changed

+272520
-14677
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

701 files changed

+272520
-14677
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ USAGE:
8787
openldap_exporter [global options] [arguments...]
8888
8989
VERSION:
90-
v2.0-7-gf81504e (f81504e)
90+
v2.1.2
9191
9292
GLOBAL OPTIONS:
9393
--promAddr value Bind address for Prometheus HTTP metrics server (default: ":9330") [$PROM_ADDR]
@@ -97,6 +97,7 @@ GLOBAL OPTIONS:
9797
--ldapUser value OpenLDAP bind username (optional) [$LDAP_USER]
9898
--ldapPass value OpenLDAP bind password (optional) [$LDAP_PASS]
9999
--interval value Scrape interval (default: 30s) [$INTERVAL]
100+
--webCfgFile FILE Prometheus metrics web config FILE (optional) [$WEB_CFG_FILE]
100101
--config YAML_FILE Optional configuration from a YAML_FILE
101102
--help, -h show help (default: false)
102103
--version, -v print the version (default: false)
@@ -116,7 +117,12 @@ ldapUser: "cn=monitoring,cn=Monitor"
116117
ldapPass: "sekret"
117118
```
118119
120+
NOTES:
121+
122+
* `--ldapNet` allows you to configure `tcp` or `unix` socket connections to your co-located OpenLDAP server.
123+
* `--webCfgFile` can be used to provide authentiction and TLS configuration for the [prometheus web exporter](https://github.com/prometheus/exporter-toolkit/tree/master/web).
124+
119125
## Build
120126

121-
1. Install Go 1.13 from https://golang.org/
127+
1. Install Go 1.16 from https://golang.org/
122128
2. Build the binaries: `make build`

cmd/openldap_exporter/main.go

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
package main
22

33
import (
4+
"context"
45
"log"
56
"os"
7+
"os/signal"
8+
"syscall"
69
"time"
710

811
exporter "github.com/tomcz/openldap_exporter"
912

1013
"github.com/urfave/cli/v2"
1114
"github.com/urfave/cli/v2/altsrc"
15+
"golang.org/x/sync/errgroup"
1216
)
1317

1418
const (
15-
promAddr = "promAddr"
16-
ldapNet = "ldapNet"
17-
ldapAddr = "ldapAddr"
18-
ldapUser = "ldapUser"
19-
ldapPass = "ldapPass"
20-
interval = "interval"
21-
metrics = "metrPath"
22-
config = "config"
19+
promAddr = "promAddr"
20+
ldapNet = "ldapNet"
21+
ldapAddr = "ldapAddr"
22+
ldapUser = "ldapUser"
23+
ldapPass = "ldapPass"
24+
interval = "interval"
25+
metrics = "metrPath"
26+
webCfgFile = "webCfgFile"
27+
config = "config"
2328
)
2429

2530
func main() {
@@ -64,6 +69,11 @@ func main() {
6469
Usage: "Scrape interval",
6570
EnvVars: []string{"INTERVAL"},
6671
}),
72+
altsrc.NewStringFlag(&cli.StringFlag{
73+
Name: webCfgFile,
74+
Usage: "Prometheus metrics web config `FILE` (optional)",
75+
EnvVars: []string{"WEB_CFG_FILE"},
76+
}),
6777
&cli.StringFlag{
6878
Name: config,
6979
Usage: "Optional configuration from a `YAML_FILE`",
@@ -94,8 +104,7 @@ func optionalYamlSourceFunc(flagFileName string) func(context *cli.Context) (alt
94104
}
95105

96106
func runMain(c *cli.Context) error {
97-
log.Println("starting Prometheus HTTP metrics server on", c.String(promAddr))
98-
go exporter.StartMetricsServer(c.String(promAddr), c.String(metrics))
107+
server := exporter.NewMetricsServer(c.String(promAddr), c.String(metrics), c.String(webCfgFile))
99108

100109
scraper := &exporter.Scraper{
101110
Net: c.String(ldapNet),
@@ -104,7 +113,33 @@ func runMain(c *cli.Context) error {
104113
Pass: c.String(ldapPass),
105114
Tick: c.Duration(interval),
106115
}
107-
log.Println("starting OpenLDAP scraper for", scraper.Addr)
108-
scraper.Start()
109-
return nil
116+
117+
ctx, cancel := context.WithCancel(context.Background())
118+
var group errgroup.Group
119+
group.Go(func() error {
120+
defer cancel()
121+
log.Printf("starting Prometheus HTTP metrics server on %s\n", c.String(promAddr))
122+
return server.Start()
123+
})
124+
group.Go(func() error {
125+
defer cancel()
126+
log.Printf("starting OpenLDAP scraper for %s://%s\n", scraper.Net, scraper.Addr)
127+
return scraper.Start(ctx)
128+
})
129+
group.Go(func() error {
130+
defer func() {
131+
cancel()
132+
server.Stop()
133+
}()
134+
signalChan := make(chan os.Signal, 1)
135+
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
136+
select {
137+
case <-signalChan:
138+
log.Println("shutdown received")
139+
return nil
140+
case <-ctx.Done():
141+
return nil
142+
}
143+
})
144+
return group.Wait()
110145
}

go.mod

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ module github.com/tomcz/openldap_exporter
33
go 1.16
44

55
require (
6-
github.com/hashicorp/go-multierror v1.0.0
7-
github.com/prometheus/client_golang v1.2.1
6+
github.com/go-kit/kit v0.10.0
7+
github.com/prometheus/client_golang v1.7.1
8+
github.com/prometheus/exporter-toolkit v0.5.1
89
github.com/urfave/cli/v2 v2.2.0
10+
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
911
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
1012
gopkg.in/ldap.v2 v2.5.1
1113
)

go.sum

Lines changed: 347 additions & 16 deletions
Large diffs are not rendered by default.

scraper.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package openldap_exporter
22

33
import (
4+
"context"
45
"fmt"
56
"log"
67
"strconv"
78
"strings"
89
"time"
910

10-
"github.com/hashicorp/go-multierror"
1111
"github.com/prometheus/client_golang/prometheus"
1212
"gopkg.in/ldap.v2"
1313
)
@@ -113,39 +113,47 @@ type Scraper struct {
113113
Tick time.Duration
114114
}
115115

116-
func (s *Scraper) Start() {
117-
for range time.Tick(s.Tick) {
118-
s.runOnce()
116+
func (s *Scraper) Start(ctx context.Context) error {
117+
ticker := time.NewTicker(s.Tick)
118+
for {
119+
select {
120+
case <-ticker.C:
121+
s.runOnce()
122+
case <-ctx.Done():
123+
return nil
124+
}
119125
}
120126
}
121127

122128
func (s *Scraper) runOnce() {
123-
if err := s.scrape(); err != nil {
124-
scrapeCounter.WithLabelValues("fail").Inc()
125-
log.Println("scrape failed, error is:", err)
126-
} else {
129+
if s.scrape() {
127130
scrapeCounter.WithLabelValues("ok").Inc()
131+
} else {
132+
scrapeCounter.WithLabelValues("fail").Inc()
128133
}
129134
}
130135

131-
func (s *Scraper) scrape() error {
136+
func (s *Scraper) scrape() bool {
132137
l, err := ldap.Dial(s.Net, s.Addr)
133138
if err != nil {
134-
return fmt.Errorf("dial failed: %w", err)
139+
log.Printf("dial failed: %v\n", err)
140+
return false
135141
}
136142
defer l.Close()
137143

138144
if s.User != "" && s.Pass != "" {
139145
err = l.Bind(s.User, s.Pass)
140146
if err != nil {
141-
return fmt.Errorf("bind failed: %w", err)
147+
log.Printf("bind failed: %v\n", err)
148+
return false
142149
}
143150
}
144151

145-
var ret error
152+
ret := true
146153
for _, q := range queries {
147154
if err := scrapeQuery(l, q); err != nil {
148-
ret = multierror.Append(ret, err)
155+
log.Println(err.Error())
156+
ret = false
149157
}
150158
}
151159
return ret

server.go

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package openldap_exporter
22

33
import (
4+
"context"
5+
"errors"
46
"fmt"
57
"log"
68
"net/http"
9+
"strings"
10+
"time"
711

12+
kitlog "github.com/go-kit/kit/log"
813
"github.com/prometheus/client_golang/prometheus/promhttp"
14+
"github.com/prometheus/exporter-toolkit/web"
915
)
1016

1117
var commit string
@@ -15,14 +21,32 @@ func GetVersion() string {
1521
return fmt.Sprintf("%s (%s)", tag, commit)
1622
}
1723

18-
func StartMetricsServer(bindAddr, metricsPath string) {
24+
type Server struct {
25+
server *http.Server
26+
cfgPath string
27+
}
28+
29+
func (s *Server) Start() error {
30+
err := web.ListenAndServe(s.server, s.cfgPath, kitlog.LoggerFunc(logger))
31+
if errors.Is(err, http.ErrServerClosed) {
32+
return nil
33+
}
34+
return err
35+
}
36+
37+
func (s *Server) Stop() {
38+
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
39+
s.server.Shutdown(ctx)
40+
cancel()
41+
}
42+
43+
func NewMetricsServer(bindAddr, metricsPath, tlsConfigPath string) *Server {
1944
mux := http.NewServeMux()
2045
mux.Handle(metricsPath, promhttp.Handler())
2146
mux.HandleFunc("/version", showVersion)
22-
23-
err := http.ListenAndServe(bindAddr, mux)
24-
if err != nil {
25-
log.Fatalln("http listener failed, error is:", err)
47+
return &Server{
48+
server: &http.Server{Addr: bindAddr, Handler: mux},
49+
cfgPath: tlsConfigPath,
2650
}
2751
}
2852

@@ -34,3 +58,21 @@ func showVersion(w http.ResponseWriter, r *http.Request) {
3458
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
3559
fmt.Fprintln(w, GetVersion())
3660
}
61+
62+
func logger(kvs ...interface{}) error {
63+
if len(kvs) == 0 {
64+
return nil
65+
}
66+
if len(kvs)%2 != 0 {
67+
kvs = append(kvs, nil)
68+
}
69+
var buf strings.Builder
70+
for i := 0; i < len(kvs); i += 2 {
71+
if i > 0 {
72+
buf.WriteString(" ")
73+
}
74+
fmt.Fprintf(&buf, "%v=%v", kvs[i], kvs[i+1])
75+
}
76+
log.Println(buf.String())
77+
return nil
78+
}

vendor/github.com/cespare/xxhash/v2/README.md

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cespare/xxhash/v2/go.mod

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/go-kit/kit/LICENSE

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)