feat: support advanced zap configuration

Signed-off-by: Maxime Leroy <19607336+maxime1907@users.noreply.github.com>
This commit is contained in:
Maxime Leroy
2022-10-05 14:42:34 +02:00
parent 2f54105404
commit a913318ae3
5 changed files with 67 additions and 29 deletions

View File

@@ -23,6 +23,7 @@ RUN go mod vendor
FROM scratch as simple
COPY --from=builder /w/bin/goldpinger /goldpinger
COPY ./static /static
COPY ./config /config
ENTRYPOINT ["/goldpinger", "--static-file-path", "/static"]
# For vendor builds, use the simple build and add the vendor'd files

View File

@@ -1,5 +1,5 @@
name ?= goldpinger
version ?= v3.4.0
version ?= v3.7.0
bin ?= goldpinger
pkg ?= "github.com/bloomberg/goldpinger"
tag = $(name):$(version)

View File

@@ -15,8 +15,11 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"time"
"github.com/go-openapi/loads"
@@ -37,37 +40,32 @@ var (
Version, Build string
)
func getLogger() *zap.Logger {
func getLogger(zapconfigpath string) (*zap.Logger, error) {
var logger *zap.Logger
var err error
// We haven't parsed flags at this stage and that might be error prone
// so just use an envvar
if debug, err := strconv.ParseBool(os.Getenv("DEBUG")); err == nil && debug {
logger, err = zap.NewDevelopment()
} else {
logger, err = zap.NewProduction()
}
zapconfigJSON, err := ioutil.ReadFile(zapconfigpath)
if err != nil {
panic(err)
return nil, fmt.Errorf("Could not read zap config file: %w", err)
}
zap.ReplaceGlobals(logger)
return logger
var cfg zap.Config
if err := json.Unmarshal(zapconfigJSON, &cfg); err != nil {
return nil, fmt.Errorf("Could not read zap config as json: %w", err)
}
logger, err = cfg.Build()
if err != nil {
return nil, fmt.Errorf("Could not build zap config: %w", err)
}
return logger, nil
}
func main() {
logger := getLogger()
defer logger.Sync()
undo := zap.RedirectStdLog(logger)
defer undo()
logger.Info("Goldpinger", zap.String("version", Version), zap.String("build", Build))
// load embedded swagger file
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
logger.Error("Coud not parse swagger", zap.Error(err))
log.Fatalf("Could not parse swagger: %v", err)
}
// create new service API
@@ -84,7 +82,7 @@ func main() {
for _, optsGroup := range api.CommandLineOptionsGroups {
_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
if err != nil {
logger.Error("Coud not add flag group", zap.Error(err))
log.Fatalf("Could not add flag group: %v", err)
}
}
@@ -98,6 +96,23 @@ func main() {
os.Exit(code)
}
// Configure logger
logger, err := getLogger(goldpinger.GoldpingerConfig.ZapConfigPath)
if err != nil {
var errDev error
logger, errDev = zap.NewDevelopment()
if errDev != nil {
log.Fatalf("Could not build a development logger: %v", errDev)
}
logger.Warn("Logger could not be built, defaulting to development settings", zap.String("error", fmt.Sprintf("%v", err)))
}
defer logger.Sync()
undo := zap.RedirectStdLog(logger)
defer undo()
logger.Info("Goldpinger", zap.String("version", Version), zap.String("build", Build))
if goldpinger.GoldpingerConfig.Namespace == nil {
goldpinger.GoldpingerConfig.Namespace = &goldpinger.PodNamespace
} else {

21
config/zap.json Normal file
View File

@@ -0,0 +1,21 @@
{
"level": "info",
"encoding": "json",
"outputPaths": [
"stdout"
],
"errorOutputPaths": [
"stderr"
],
"initialFields": {
},
"encoderConfig": {
"messageKey": "message",
"levelKey": "level",
"levelEncoder": "lowercase",
"timeKey": "ts",
"timeEncoder": "ISO8601",
"callerKey": "caller",
"callerEncoder": "Short"
}
}

View File

@@ -23,6 +23,7 @@ import (
// GoldpingerConfig represents the configuration for goldpinger
var GoldpingerConfig = struct {
StaticFilePath string `long:"static-file-path" description:"Folder for serving static files" env:"STATIC_FILE_PATH"`
ZapConfigPath string `long:"zap-config" description:"Path to zap config file" env:"ZAP_CONFIG" default:"/config/zap.json"`
KubeConfigPath string `long:"kubeconfig" description:"Path to kubeconfig file" env:"KUBECONFIG"`
RefreshInterval int `long:"refresh-interval" description:"If > 0, will create a thread and collect stats every n seconds" env:"REFRESH_INTERVAL" default:"30"`
JitterFactor float64 `long:"jitter-factor" description:"The amount of jitter to add while pinging clients" env:"JITTER_FACTOR" default:"0.05"`
@@ -47,10 +48,10 @@ var GoldpingerConfig = struct {
PingTimeoutMs int64 `long:"ping-timeout-ms" description:"The timeout in milliseconds for a ping call to other goldpinger pods(deprecated)" env:"PING_TIMEOUT_MS" default:"300"`
CheckTimeoutMs int64 `long:"check-timeout-ms" description:"The timeout in milliseconds for a check call to other goldpinger pods(deprecated)" env:"CHECK_TIMEOUT_MS" default:"1000"`
CheckAllTimeoutMs int64 `long:"check-all-timeout-ms" description:"The timeout in milliseconds for a check-all call to other goldpinger pods(deprecated)" env:"CHECK_ALL_TIMEOUT_MS" default:"5000"`
PingTimeout time.Duration `long:"ping-timeout" description:"The timeout for a ping call to other goldpinger pods" env:"PING_TIMEOUT" default:"300ms"`
CheckTimeout time.Duration `long:"check-timeout" description:"The timeout for a check call to other goldpinger pods" env:"CHECK_TIMEOUT" default:"1000ms"`
CheckAllTimeout time.Duration `long:"check-all-timeout" description:"The timeout for a check-all call to other goldpinger pods" env:"CHECK_ALL_TIMEOUT" default:"5000ms"`
TCPCheckTimeout time.Duration `long:"tcp-targets-timeout" description:"The timeout for a tcp check on the provided tcp-targets" env:"TCP_TARGETS_TIMEOUT" default:"500ms"`
DnsCheckTimeout time.Duration `long:"dns-targets-timeout" description:"The timeout for a dns check on the provided dns-targets" env:"DNS_TARGETS_TIMEOUT" default:"500ms"`
HTTPCheckTimeout time.Duration `long:"http-targets-timeout" description:"The timeout for a http check on the provided http-targets" env:"HTTP_TARGETS_TIMEOUT" default:"500ms"`
PingTimeout time.Duration `long:"ping-timeout" description:"The timeout for a ping call to other goldpinger pods" env:"PING_TIMEOUT" default:"300ms"`
CheckTimeout time.Duration `long:"check-timeout" description:"The timeout for a check call to other goldpinger pods" env:"CHECK_TIMEOUT" default:"1000ms"`
CheckAllTimeout time.Duration `long:"check-all-timeout" description:"The timeout for a check-all call to other goldpinger pods" env:"CHECK_ALL_TIMEOUT" default:"5000ms"`
TCPCheckTimeout time.Duration `long:"tcp-targets-timeout" description:"The timeout for a tcp check on the provided tcp-targets" env:"TCP_TARGETS_TIMEOUT" default:"500ms"`
DnsCheckTimeout time.Duration `long:"dns-targets-timeout" description:"The timeout for a dns check on the provided dns-targets" env:"DNS_TARGETS_TIMEOUT" default:"500ms"`
HTTPCheckTimeout time.Duration `long:"http-targets-timeout" description:"The timeout for a http check on the provided http-targets" env:"HTTP_TARGETS_TIMEOUT" default:"500ms"`
}{}