Merge pull request #1047 from jammiemil/master
fix Windows Service timeout during high CPU (eg. post Windows Update)
This commit is contained in:
commit
4b226cde40
56
exporter.go
56
exporter.go
|
@ -4,6 +4,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
//Its important that we do these first so that we can register with the windows service control ASAP to avoid timeouts
|
||||
"github.com/prometheus-community/windows_exporter/initiate"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -16,12 +20,10 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/collector"
|
||||
"github.com/prometheus-community/windows_exporter/config"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
@ -50,7 +52,6 @@ type prometheusVersion struct {
|
|||
const (
|
||||
defaultCollectors = "cpu,cs,logical_disk,net,os,service,system,textfile"
|
||||
defaultCollectorsPlaceholder = "[defaults]"
|
||||
serviceName = "windows_exporter"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -289,7 +290,6 @@ func main() {
|
|||
"Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads.",
|
||||
).Default("0.5").Float64()
|
||||
)
|
||||
|
||||
log.AddFlags(kingpin.CommandLine)
|
||||
kingpin.Version(version.Print("windows_exporter"))
|
||||
kingpin.HelpFlag.Short('h')
|
||||
|
@ -297,7 +297,7 @@ func main() {
|
|||
// Load values from configuration file(s). Executable flags must first be parsed, in order
|
||||
// to load the specified file(s).
|
||||
kingpin.Parse()
|
||||
|
||||
log.Debug("Logging has Started")
|
||||
if *configFile != "" {
|
||||
resolver, err := config.NewResolver(*configFile)
|
||||
if err != nil {
|
||||
|
@ -327,21 +327,6 @@ func main() {
|
|||
|
||||
initWbem()
|
||||
|
||||
isService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
stopCh := make(chan bool)
|
||||
if isService {
|
||||
go func() {
|
||||
err = svc.Run(serviceName, &windowsExporterService{stopCh: stopCh})
|
||||
if err != nil {
|
||||
log.Errorf("Failed to start service: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
collectors, err := loadCollectors(*enabledCollectors)
|
||||
if err != nil {
|
||||
log.Fatalf("Couldn't load collectors: %s", err)
|
||||
|
@ -421,7 +406,7 @@ func main() {
|
|||
}()
|
||||
|
||||
for {
|
||||
if <-stopCh {
|
||||
if <-initiate.StopCh {
|
||||
log.Info("Shutting down windows_exporter")
|
||||
break
|
||||
}
|
||||
|
@ -463,33 +448,6 @@ func withConcurrencyLimit(n int, next http.HandlerFunc) http.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
type windowsExporterService struct {
|
||||
stopCh chan<- bool
|
||||
}
|
||||
|
||||
func (s *windowsExporterService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
|
||||
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
|
||||
changes <- svc.Status{State: svc.StartPending}
|
||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case c := <-r:
|
||||
switch c.Cmd {
|
||||
case svc.Interrogate:
|
||||
changes <- c.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
s.stopCh <- true
|
||||
break loop
|
||||
default:
|
||||
log.Error(fmt.Sprintf("unexpected control request #%d", c))
|
||||
}
|
||||
}
|
||||
}
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
return
|
||||
}
|
||||
|
||||
type metricsHandler struct {
|
||||
timeoutMargin float64
|
||||
collectorFactory func(timeout time.Duration, requestedCollectors []string) (error, *windowsCollector)
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
//This package allows us to initiate Time Sensitive components (Like registering the windows service) as early as possible in the startup process
|
||||
package initiate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
const (
|
||||
serviceName = "windows_exporter"
|
||||
)
|
||||
|
||||
type windowsExporterService struct {
|
||||
stopCh chan<- bool
|
||||
}
|
||||
|
||||
func (s *windowsExporterService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
|
||||
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
|
||||
changes <- svc.Status{State: svc.StartPending}
|
||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case c := <-r:
|
||||
switch c.Cmd {
|
||||
case svc.Interrogate:
|
||||
changes <- c.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
log.Debug("Service Stop Received")
|
||||
s.stopCh <- true
|
||||
break loop
|
||||
default:
|
||||
log.Error(fmt.Sprintf("unexpected control request #%d", c))
|
||||
}
|
||||
}
|
||||
}
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
return
|
||||
}
|
||||
|
||||
var StopCh = make(chan bool)
|
||||
|
||||
func init() {
|
||||
log.Debug("Checking if We are a service")
|
||||
isService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Debug("Attempting to start exporter service")
|
||||
if isService {
|
||||
go func() {
|
||||
err = svc.Run(serviceName, &windowsExporterService{stopCh: StopCh})
|
||||
if err != nil {
|
||||
log.Errorf("Failed to start service: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue