138 lines
3.7 KiB
Go
138 lines
3.7 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"os"
|
||
|
"os/signal"
|
||
|
"syscall"
|
||
|
|
||
|
"github.com/prometheus/client_golang/prometheus"
|
||
|
)
|
||
|
|
||
|
// Basic application info.
|
||
|
const (
|
||
|
serviceName = "freeipa-health-metrics"
|
||
|
serviceDescription = "Provides metrics of FreeIPA's health"
|
||
|
serviceVersion = "0.1"
|
||
|
namespace = "freeipa"
|
||
|
)
|
||
|
|
||
|
// The standard prometheus metric info structure which includes the description, type,
|
||
|
// and a sub function to collect the value.
|
||
|
type metricInfo struct {
|
||
|
Desc *prometheus.Desc
|
||
|
Type prometheus.ValueType
|
||
|
Value func() (float64, error)
|
||
|
}
|
||
|
|
||
|
// The global application structure used to access diffent state structures and configuration.
|
||
|
type App struct {
|
||
|
flags *Flags
|
||
|
config *Config
|
||
|
registry *prometheus.Registry
|
||
|
ldapExporter *LDAPExporter
|
||
|
freeIPAExporter *FreeIPAExporter
|
||
|
httpOutput *HTTPOutput
|
||
|
influxOutput *InfluxOutput
|
||
|
}
|
||
|
|
||
|
// Global variable for the app structure to make it easy to get the active state.
|
||
|
var app *App
|
||
|
|
||
|
// The main program function/run loop.
|
||
|
func main() {
|
||
|
// Setup the app structure.
|
||
|
app = new(App)
|
||
|
app.ParseFlags()
|
||
|
app.ReadConfig()
|
||
|
|
||
|
// Load exporters.
|
||
|
app.ldapExporter = NewLDAPExporter()
|
||
|
app.freeIPAExporter = NewFreeIPAExporter()
|
||
|
|
||
|
// Add exporters to registry.
|
||
|
reg := prometheus.NewPedanticRegistry()
|
||
|
reg.Register(app.ldapExporter)
|
||
|
reg.Register(app.freeIPAExporter)
|
||
|
app.registry = reg
|
||
|
|
||
|
// Load outputs.
|
||
|
app.httpOutput = NewHTTPOutput()
|
||
|
app.influxOutput = NewInfluxOutput()
|
||
|
|
||
|
// If requested telegraf output.
|
||
|
if app.flags.TelegrafOutput {
|
||
|
// Get metrics in influx line protocol format.
|
||
|
data, err := app.influxOutput.CollectAndLineprotocolFormat()
|
||
|
if err != nil {
|
||
|
log.Fatalln("Error collecting metrics for telegraf:", err)
|
||
|
}
|
||
|
// Print the encoded data.
|
||
|
fmt.Println(string(data))
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Setup context with cancellation function to allow background services to gracefully stop.
|
||
|
ctx, ctxCancel := context.WithCancel(context.Background())
|
||
|
|
||
|
// Start http output server.
|
||
|
go app.httpOutput.Start(ctx)
|
||
|
|
||
|
// Start the influx output schedule.
|
||
|
go app.influxOutput.Start(ctx)
|
||
|
|
||
|
// Monitor common signals.
|
||
|
c := make(chan os.Signal, 1)
|
||
|
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||
|
|
||
|
// Run program until cancelled.
|
||
|
for sig := range c {
|
||
|
switch sig {
|
||
|
// If hangup signal receivied, reload the configurations.
|
||
|
case syscall.SIGHUP:
|
||
|
log.Println("Reloading configurations")
|
||
|
// Capture old config for checks.
|
||
|
oldConfig := app.config
|
||
|
// Get prior state of influx output.
|
||
|
influxOutputWasEnabled := app.influxOutput.OutputEnabled()
|
||
|
|
||
|
// Read new config.
|
||
|
app.ReadConfig()
|
||
|
|
||
|
// Reload config on each exporter and output.
|
||
|
app.ldapExporter.Reload()
|
||
|
app.freeIPAExporter.Reload()
|
||
|
app.httpOutput.Reload()
|
||
|
app.influxOutput.Reload()
|
||
|
|
||
|
// Check if httpd server config changes require restart.
|
||
|
httpNeedsRestart := oldConfig.HTTP.BindAddr != app.config.HTTP.BindAddr || oldConfig.HTTP.Port != app.config.HTTP.Port || oldConfig.HTTP.Enabled != app.config.HTTP.Enabled
|
||
|
// Check if influx output config changes require restart.
|
||
|
influxNeedsRestart := app.influxOutput.OutputEnabled() != influxOutputWasEnabled || oldConfig.Influx.Frequency != app.config.Influx.Frequency
|
||
|
|
||
|
// If either output service requires restart, restart both.
|
||
|
if httpNeedsRestart || influxNeedsRestart {
|
||
|
// Cancel prior background context.
|
||
|
ctxCancel()
|
||
|
|
||
|
// Setup new background context.
|
||
|
ctx, ctxCancel = context.WithCancel(context.Background())
|
||
|
|
||
|
// Start http output server.
|
||
|
go app.httpOutput.Start(ctx)
|
||
|
|
||
|
// Start the influx output schedule.
|
||
|
go app.influxOutput.Start(ctx)
|
||
|
}
|
||
|
|
||
|
// The default signal is either termination or interruption, so cancel the
|
||
|
// background context and exit this program.
|
||
|
default:
|
||
|
ctxCancel()
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|