Skip to content

Commit a48f8a7

Browse files
committed
chore: refactor http handler
Signed-off-by: Jan-Otto Kröpke <[email protected]> Signed-off-by: Jan-Otto Kröpke <[email protected]>
2 parents 419aca1 + 6c5b4ba commit a48f8a7

File tree

11 files changed

+389
-250
lines changed

11 files changed

+389
-250
lines changed

exporter.go

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/alecthomas/kingpin/v2"
2929
"github.com/prometheus-community/windows_exporter/pkg/collector"
3030
"github.com/prometheus-community/windows_exporter/pkg/config"
31+
"github.com/prometheus-community/windows_exporter/pkg/httphandler"
3132
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
3233
"github.com/prometheus-community/windows_exporter/pkg/log/flag"
3334
"github.com/prometheus-community/windows_exporter/pkg/types"
@@ -251,7 +252,12 @@ func main() {
251252
logger.Info("Enabled collectors: " + strings.Join(enabledCollectorList, ", "))
252253

253254
mux := http.NewServeMux()
254-
mux.HandleFunc("GET "+*metricsPath, withConcurrencyLimit(*maxRequests, collectors.BuildServeHTTP(logger, *disableExporterMetrics, *timeoutMargin)))
255+
mux.Handle("GET "+*metricsPath, httphandler.New(logger, collectors, &httphandler.Options{
256+
DisableExporterMetrics: *disableExporterMetrics,
257+
TimeoutMargin: *timeoutMargin,
258+
MaxRequests: *maxRequests,
259+
}))
260+
255261
mux.HandleFunc("GET /health", func(w http.ResponseWriter, _ *http.Request) {
256262
w.Header().Set("Content-Type", "application/json")
257263
if _, err := fmt.Fprintln(w, `{"status":"ok"}`); err != nil {
@@ -260,6 +266,7 @@ func main() {
260266
)
261267
}
262268
})
269+
263270
mux.HandleFunc("GET /version", func(w http.ResponseWriter, _ *http.Request) {
264271
// we can't use "version" directly as it is a package, and not an object that
265272
// can be serialized.
@@ -292,7 +299,7 @@ func main() {
292299
ReadHeaderTimeout: 5 * time.Second,
293300
IdleTimeout: 60 * time.Second,
294301
ReadTimeout: 5 * time.Second,
295-
WriteTimeout: 10 * time.Minute,
302+
WriteTimeout: 5 * time.Minute,
296303
Handler: mux,
297304
}
298305

@@ -322,22 +329,3 @@ func main() {
322329

323330
logger.Info("windows_exporter has shut down")
324331
}
325-
326-
func withConcurrencyLimit(n int, next http.HandlerFunc) http.HandlerFunc {
327-
if n <= 0 {
328-
return next
329-
}
330-
331-
sem := make(chan struct{}, n)
332-
return func(w http.ResponseWriter, r *http.Request) {
333-
select {
334-
case sem <- struct{}{}:
335-
defer func() { <-sem }()
336-
default:
337-
w.WriteHeader(http.StatusServiceUnavailable)
338-
_, _ = w.Write([]byte("Too many concurrent requests"))
339-
return
340-
}
341-
next(w, r)
342-
}
343-
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/prometheus/exporter-toolkit v0.12.0
1616
github.com/stretchr/testify v1.9.0
1717
github.com/yusufpapurcu/wmi v1.2.4
18+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
1819
golang.org/x/sys v0.25.0
1920
gopkg.in/yaml.v3 v3.0.1
2021
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
118118
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
119119
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
120120
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
121+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
122+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
121123
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
122124
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
123125
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=

pkg/collector/collector.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import (
6969
)
7070

7171
// NewWithFlags To be called by the exporter for collector initialization before running kingpin.Parse.
72-
func NewWithFlags(app *kingpin.Application) *Collectors {
72+
func NewWithFlags(app *kingpin.Application) *MetricCollectors {
7373
collectors := map[string]Collector{}
7474

7575
for name, builder := range BuildersWithFlags {
@@ -82,8 +82,8 @@ func NewWithFlags(app *kingpin.Application) *Collectors {
8282
// NewWithConfig To be called by the external libraries for collector initialization without running kingpin.Parse
8383
//
8484
//goland:noinspection GoUnusedExportedFunction
85-
func NewWithConfig(config Config) *Collectors {
86-
collectors := map[string]Collector{}
85+
func NewWithConfig(config Config) *MetricCollectors {
86+
collectors := Map{}
8787
collectors[ad.Name] = ad.New(&config.AD)
8888
collectors[adcs.Name] = adcs.New(&config.ADCS)
8989
collectors[adfs.Name] = adfs.New(&config.ADFS)
@@ -142,26 +142,26 @@ func NewWithConfig(config Config) *Collectors {
142142
}
143143

144144
// New To be called by the external libraries for collector initialization.
145-
func New(collectors Map) *Collectors {
146-
return &Collectors{
147-
collectors: collectors,
148-
wmiClient: &wmi.Client{
145+
func New(collectors Map) *MetricCollectors {
146+
return &MetricCollectors{
147+
Collectors: collectors,
148+
WMIClient: &wmi.Client{
149149
AllowMissingFields: true,
150150
},
151151
}
152152
}
153153

154-
func (c *Collectors) SetPerfCounterQuery(logger *slog.Logger) error {
154+
func (c *MetricCollectors) SetPerfCounterQuery(logger *slog.Logger) error {
155155
var (
156156
err error
157157

158158
perfCounterNames []string
159159
perfIndicies []string
160160
)
161161

162-
perfCounterDependencies := make([]string, 0, len(c.collectors))
162+
perfCounterDependencies := make([]string, 0, len(c.Collectors))
163163

164-
for _, collector := range c.collectors {
164+
for _, collector := range c.Collectors {
165165
perfCounterNames, err = collector.GetPerfCounter(logger)
166166
if err != nil {
167167
return err
@@ -175,31 +175,31 @@ func (c *Collectors) SetPerfCounterQuery(logger *slog.Logger) error {
175175
perfCounterDependencies = append(perfCounterDependencies, strings.Join(perfIndicies, " "))
176176
}
177177

178-
c.perfCounterQuery = strings.Join(perfCounterDependencies, " ")
178+
c.PerfCounterQuery = strings.Join(perfCounterDependencies, " ")
179179

180180
return nil
181181
}
182182

183183
// Enable removes all collectors that not enabledCollectors.
184-
func (c *Collectors) Enable(enabledCollectors []string) {
185-
for name := range c.collectors {
184+
func (c *MetricCollectors) Enable(enabledCollectors []string) {
185+
for name := range c.Collectors {
186186
if !slices.Contains(enabledCollectors, name) {
187-
delete(c.collectors, name)
187+
delete(c.Collectors, name)
188188
}
189189
}
190190
}
191191

192192
// Build To be called by the exporter for collector initialization.
193-
func (c *Collectors) Build(logger *slog.Logger) error {
193+
func (c *MetricCollectors) Build(logger *slog.Logger) error {
194194
var err error
195195

196-
c.wmiClient.SWbemServicesClient, err = wmi.InitializeSWbemServices(c.wmiClient)
196+
c.WMIClient.SWbemServicesClient, err = wmi.InitializeSWbemServices(c.WMIClient)
197197
if err != nil {
198198
return fmt.Errorf("initialize SWbemServices: %w", err)
199199
}
200200

201-
for _, collector := range c.collectors {
202-
if err = collector.Build(logger, c.wmiClient); err != nil {
201+
for _, collector := range c.Collectors {
202+
if err = collector.Build(logger, c.WMIClient); err != nil {
203203
return fmt.Errorf("error build collector %s: %w", collector.GetName(), err)
204204
}
205205
}
@@ -208,12 +208,12 @@ func (c *Collectors) Build(logger *slog.Logger) error {
208208
}
209209

210210
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape.
211-
func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
212-
if c.perfCounterQuery == "" { // if perfCounterQuery is empty, no perf counters are needed.
211+
func (c *MetricCollectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
212+
if c.PerfCounterQuery == "" { // if perfCounterQuery is empty, no perf counters are needed.
213213
return &types.ScrapeContext{}, nil
214214
}
215215

216-
objs, err := perflib.GetPerflibSnapshot(c.perfCounterQuery)
216+
objs, err := perflib.GetPerflibSnapshot(c.PerfCounterQuery)
217217
if err != nil {
218218
return nil, err
219219
}
@@ -222,17 +222,17 @@ func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
222222
}
223223

224224
// Close To be called by the exporter for collector cleanup.
225-
func (c *Collectors) Close(logger *slog.Logger) error {
226-
errs := make([]error, 0, len(c.collectors))
225+
func (c *MetricCollectors) Close(logger *slog.Logger) error {
226+
errs := make([]error, 0, len(c.Collectors))
227227

228-
for _, collector := range c.collectors {
228+
for _, collector := range c.Collectors {
229229
if err := collector.Close(logger); err != nil {
230230
errs = append(errs, err)
231231
}
232232
}
233233

234-
if c.wmiClient != nil && c.wmiClient.SWbemServicesClient != nil {
235-
if err := c.wmiClient.SWbemServicesClient.Close(); err != nil {
234+
if c.WMIClient != nil && c.WMIClient.SWbemServicesClient != nil {
235+
if err := c.WMIClient.SWbemServicesClient.Close(); err != nil {
236236
errs = append(errs, err)
237237
}
238238
}

pkg/collector/handler.go

Lines changed: 0 additions & 88 deletions
This file was deleted.

0 commit comments

Comments
 (0)