Add documentation, change config format

This commit is contained in:
Lou Knauer 2022-02-04 08:46:14 +01:00
parent 8fb2557f97
commit 83d1cb2a98
5 changed files with 44 additions and 23 deletions

View File

@ -74,15 +74,17 @@ All durations are specified as string that will be parsed [like this](https://pk
- `"sum"` means that values from the child levels are summed up for the parent level - `"sum"` means that values from the child levels are summed up for the parent level
- `"avg"` means that values from the child levels are averaged for the parent level - `"avg"` means that values from the child levels are averaged for the parent level
- `scope`: Unused at the moment, should be something like `"node"`, `"socket"` or `"hwthread"` - `scope`: Unused at the moment, should be something like `"node"`, `"socket"` or `"hwthread"`
- `nats`: Url of NATS.io server (The `updates` channel will be subscribed for metrics), example: "nats://localhost:4222" - `nats`:
- `http-api-address`: Where to listen via HTTP, example: ":8080" - `address`: Url of NATS.io server, example: "nats://localhost:4222"
- `http-api`:
- `address`: Address to bind to, for example `0.0.0.0:8080`
- `https-cert-file` and `https-key-file`: Optional, if provided enable HTTPS using those files as certificate/key.
- `jwt-public-key`: Base64 encoded string, use this to verify requests to the HTTP API - `jwt-public-key`: Base64 encoded string, use this to verify requests to the HTTP API
- `retention-on-memory`: Keep all values in memory for at least that amount of time - `retention-on-memory`: Keep all values in memory for at least that amount of time
- `checkpoints`: - `checkpoints`:
- `interval`: Do checkpoints every X seconds/minutes/hours - `interval`: Do checkpoints every X seconds/minutes/hours
- `directory`: Path to a directory - `directory`: Path to a directory
- `restore`: After a restart, load the last X seconds/minutes/hours of data back into memory - `restore`: After a restart, load the last X seconds/minutes/hours of data back into memory
- `archive`: - `archive`:
- `interval`: Move and compress all checkpoints not needed anymore every X seconds/minutes/hours - `interval`: Move and compress all checkpoints not needed anymore every X seconds/minutes/hours
- `directory`: Path to a directory - `directory`: Path to a directory

12
api.go
View File

@ -307,7 +307,7 @@ func authentication(next http.Handler, publicKey ed25519.PublicKey) http.Handler
}) })
} }
func StartApiServer(ctx context.Context, address string, httpsConfig *HttpsConfig) error { func StartApiServer(ctx context.Context, httpConfig *HttpConfig) error {
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/api/free", handleFree) r.HandleFunc("/api/free", handleFree)
@ -322,7 +322,7 @@ func StartApiServer(ctx context.Context, address string, httpsConfig *HttpsConfi
server := &http.Server{ server := &http.Server{
Handler: r, Handler: r,
Addr: address, Addr: httpConfig.Address,
WriteTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second,
} }
@ -337,14 +337,14 @@ func StartApiServer(ctx context.Context, address string, httpsConfig *HttpsConfi
} }
go func() { go func() {
if httpsConfig != nil { if httpConfig.CertFile != "" && httpConfig.KeyFile != "" {
log.Printf("API https endpoint listening on '%s'\n", address) log.Printf("API https endpoint listening on '%s'\n", httpConfig.Address)
err := server.ListenAndServeTLS(httpsConfig.CertFile, httpsConfig.KeyFile) err := server.ListenAndServeTLS(httpConfig.CertFile, httpConfig.KeyFile)
if err != nil && err != http.ErrServerClosed { if err != nil && err != http.ErrServerClosed {
log.Println(err) log.Println(err)
} }
} else { } else {
log.Printf("API http endpoint listening on '%s'\n", address) log.Printf("API http endpoint listening on '%s'\n", httpConfig.Address)
err := server.ListenAndServe() err := server.ListenAndServe()
if err != nil && err != http.ErrServerClosed { if err != nil && err != http.ErrServerClosed {
log.Println(err) log.Println(err)

View File

@ -15,8 +15,12 @@
"interval": "168h", "interval": "168h",
"directory": "./var/archive" "directory": "./var/archive"
}, },
"http-api": {
"address": "0.0.0.0:8081",
"https-cert-file": null,
"https-key-file": null
},
"retention-in-memory": "48h", "retention-in-memory": "48h",
"http-api-address": "0.0.0.0:8081",
"nats": null, "nats": null,
"jwt-public-key": "kzfYrYy+TzpanWZHJ5qSdMj5uKUWgq74BWhQG6copP0=" "jwt-public-key": "kzfYrYy+TzpanWZHJ5qSdMj5uKUWgq74BWhQG6copP0="
} }

View File

@ -20,8 +20,8 @@ type Metric struct {
// Connect to a nats server and subscribe to "updates". This is a blocking // Connect to a nats server and subscribe to "updates". This is a blocking
// function. handleLine will be called for each line recieved via nats. // function. handleLine will be called for each line recieved via nats.
// Send `true` through the done channel for gracefull termination. // Send `true` through the done channel for gracefull termination.
func ReceiveNats(address string, handleLine func(dec *lineprotocol.Decoder) error, workers int, ctx context.Context) error { func ReceiveNats(conf *NatsConfig, handleLine func(dec *lineprotocol.Decoder) error, workers int, ctx context.Context) error {
nc, err := nats.Connect(address) nc, err := nats.Connect(conf.Address)
if err != nil { if err != nil {
return err return err
} }
@ -64,7 +64,7 @@ func ReceiveNats(address string, handleLine func(dec *lineprotocol.Decoder) erro
return err return err
} }
log.Printf("NATS subscription to 'updates' on '%s' established\n", address) log.Printf("NATS subscription to 'updates' on '%s' established\n", conf.Address)
<-ctx.Done() <-ctx.Done()
err = sub.Unsubscribe() err = sub.Unsubscribe()

View File

@ -15,23 +15,38 @@ import (
) )
type MetricConfig struct { type MetricConfig struct {
// Interval in seconds at which measurements will arive.
Frequency int64 `json:"frequency"` Frequency int64 `json:"frequency"`
// Can be 'sum', 'avg' or null. Describes how to aggregate metrics from the same timestep over the hierarchy.
Aggregation string `json:"aggregation"` Aggregation string `json:"aggregation"`
// Unused for now.
Scope string `json:"scope"` Scope string `json:"scope"`
} }
type HttpsConfig struct { type HttpConfig struct {
CertFile string `json:"cert"` // Address to bind to, for example "0.0.0.0:8081"
KeyFile string `json:"key"` Address string `json:"address"`
// If not the empty string, use https with this as the certificate file
CertFile string `json:"https-cert-file"`
// If not the empty string, use https with this as the key file
KeyFile string `json:"https-key-file"`
}
type NatsConfig struct {
// Address of the nats server
Address string `json:"address"`
} }
type Config struct { type Config struct {
Metrics map[string]MetricConfig `json:"metrics"` Metrics map[string]MetricConfig `json:"metrics"`
RetentionInMemory string `json:"retention-in-memory"` RetentionInMemory string `json:"retention-in-memory"`
Nats string `json:"nats"` Nats *NatsConfig `json:"nats"`
JwtPublicKey string `json:"jwt-public-key"` JwtPublicKey string `json:"jwt-public-key"`
HttpApiAddress string `json:"http-api-address"` HttpConfig *HttpConfig `json:"http-api"`
HttpsConfig *HttpsConfig `json:"https"`
Checkpoints struct { Checkpoints struct {
Interval string `json:"interval"` Interval string `json:"interval"`
RootDir string `json:"directory"` RootDir string `json:"directory"`
@ -195,14 +210,14 @@ func main() {
wg.Add(1) wg.Add(1)
go func() { go func() {
err := StartApiServer(ctx, conf.HttpApiAddress, conf.HttpsConfig) err := StartApiServer(ctx, conf.HttpConfig)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
wg.Done() wg.Done()
}() }()
if len(conf.Nats) != 0 { if conf.Nats != nil {
wg.Add(1) wg.Add(1)
go func() { go func() {