diff --git a/cmd/menshen/main.go b/cmd/menshen/main.go index 2e1a6e7e2b17326d459eda92ef565392d18835a8..b920ce5aa17ccfe82ae4b2c68791bbd4ff6131a7 100644 --- a/cmd/menshen/main.go +++ b/cmd/menshen/main.go @@ -6,8 +6,8 @@ import ( "os" "strings" - "github.com/apex/log" - cliHandler "github.com/apex/log/handlers/cli" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -89,9 +89,16 @@ func main() { pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.Parse() + + consoleWriter := zerolog.ConsoleWriter{ + Out: os.Stdout, + TimeFormat: "2006-01-02T15:04:05.999Z07:00", + } + log.Logger = zerolog.New(consoleWriter).With().Timestamp().Logger() + err := viper.BindPFlags(pflag.CommandLine) if err != nil { - log.WithError(err).Fatal("Failed to BindPFlags") + log.Fatal().Msgf("Failed to BindPFlags: %s", err) } viper.AddConfigPath(".") @@ -99,7 +106,7 @@ func main() { viper.SetConfigType("yaml") err = viper.ReadInConfig() if err != nil { - log.WithError(err).Warn("Failed to ReadInConfig") + log.Debug().Msgf("Not using optional menshen.yaml: %s", err) } // allow to specify flags from environment variables too @@ -134,7 +141,7 @@ func main() { err = viper.BindEnv(verbose, "MENSHEN_VERBOSE") } if err != nil { - log.WithError(err).Fatal("Failed to BindEnv") + log.Fatal().Msgf("Failed to BindEnv: %s", err) } // for the few single-word flags at least @@ -144,9 +151,8 @@ func main() { verbose := viper.GetBool(verbose) if verbose { - log.SetLevel(log.DebugLevel) + zerolog.SetGlobalLevel(zerolog.DebugLevel) } - log.SetHandler(cliHandler.New(os.Stdout)) lbAddr := viper.GetString(addrLoadBalancer) @@ -178,70 +184,68 @@ func main() { } if cfg.EIPURL != "" { - log.Infof("Getting EIP File from: %s", cfg.EIPURL) + log.Info().Msgf("Getting EIP File from %s", cfg.EIPURL) } if cfg.EIP != "" { - log.Infof("Getting EIP File from: %s", cfg.EIP) + log.Info().Msgf("Getting EIP File from %s", cfg.EIP) } if cfg.ProviderJson == "" { - log.Errorf("Error: parameter --%s is required.", fromProviderJsonFile) - log.Errorf("File path to provider.json is missing. Please specify a source by using --%s", fromProviderJsonFile) + log.Error().Msgf("Error: parameter --%s is required.", fromProviderJsonFile) + log.Error().Msgf("File path to provider.json is missing. Please specify a source by using --%s", fromProviderJsonFile) os.Exit(1) } if cfg.EIPURL == "" && cfg.EIP == "" { - log.Errorf("Error: No gateways loaded. Please specify a " + - fmt.Sprintf("gateway source by using --%s or --%s", fromEIPURL, fromEIPFile)) + log.Error().Msgf("No gateways loaded. Please specify a gateway source by using --%s or --%s", fromEIPURL, fromEIPFile) os.Exit(1) } if cfg.CaFile == "" { - log.Errorf("Error: parameter %s is required", caFile) + log.Error().Msgf("parameter %s is required", caFile) os.Exit(1) } else if _, err := os.Stat(cfg.CaFile); err != nil { - log.Errorf("Error: Could not load CaFile. %s", err) + log.Error().Msgf("Could not load CaFile. %s", err) os.Exit(1) } else { - log.Debugf("Using %s as CaFile", cfg.CaFile) + log.Debug().Msgf("Using CaFile %s", cfg.CaFile) } // either clientcertURL or else cfg.OvpnCaCrt, cfg.OvpnCaKey, cfg.Algo are required for local cert generation if cfg.ClientCertURL != "" { - log.Infof("Configuring menshen to fetch certs form remote URL: %s", cfg.ClientCertURL) + log.Info().Msgf("Configuring menshen to fetch certs form remote URL: %s", cfg.ClientCertURL) } else { if cfg.OvpnCaCrt == "" { - log.Errorf("Error: parameter --%s is required.", ovpnCaCrt) - log.Errorf("Please specify a file containing the CA certificate required for generating openvpn client certificate.") + log.Error().Msgf("Error: parameter --%s is required.", ovpnCaCrt) + log.Error().Msg("Please specify a file containing the CA certificate required for generating openvpn client certificate.") os.Exit(1) } else if _, err := os.Stat(cfg.OvpnCaCrt); err != nil { - log.Errorf("Error: Could not load %s. %s", ovpnCaCrt, err) + log.Error().Msgf("Error: Could not load %s. %s", ovpnCaCrt, err) os.Exit(1) } else { - log.Debug(fmt.Sprintf("Using %s as %s", cfg.OvpnCaCrt, ovpnCaCrt)) + log.Debug().Msgf("Using %s as %s", cfg.OvpnCaCrt, ovpnCaCrt) } if cfg.OvpnCaKey == "" { - log.Errorf("Error: parameter --%s is required.", ovpnCaKey) - log.Errorf("Please specify a file containing the CA key required for signing openvpn client certificate.") + log.Error().Msgf("parameter --%s is required.", ovpnCaKey) + log.Error().Msg("Please specify a file containing the CA key required for signing openvpn client certificate.") os.Exit(1) } else if _, err := os.Stat(cfg.OvpnCaKey); err != nil { - log.Errorf("Error: Could not load %s. %s", ovpnCaKey, err) + log.Error().Msgf("Could not load %s. %s", ovpnCaKey, err) os.Exit(1) } else { - log.Debugf("Using %s as %s", cfg.OvpnCaKey, ovpnCaKey) + log.Debug().Msgf("Using %s as %s", cfg.OvpnCaKey, ovpnCaKey) } if cfg.Algo != "ed25519" && cfg.Algo != "ecdsa" && cfg.Algo != "rsa" { - log.Errorf("Error: parameter --%s %s is not supported.", algo, cfg.Algo) - log.Errorf("Please specify a supported algo for cert generation. Currently supported algorithms are: ed25519, ecdsa, rsa.") + log.Error().Msgf("Error: parameter --%s %s is not supported.", algo, cfg.Algo) + log.Error().Msg("Please specify a supported algo for cert generation. Currently supported algorithms are: ed25519, ecdsa, rsa.") os.Exit(1) } } echoMetrics := api.InitMetricsServer() go func() { - msg := fmt.Sprintf("Starting /metrics server on :%d", cfg.PortMetrics) - log.Infof(msg) + log.Info().Msgf("Starting /metrics server on :%d", cfg.PortMetrics) echoMetrics.Logger.Fatal(echoMetrics.Start( fmt.Sprintf(":%d", cfg.PortMetrics))) }() @@ -254,7 +258,7 @@ func main() { if cfg.AutoTLS { e.Logger.Fatal(e.StartAutoTLS(portStr)) } else { - fmt.Println("starting:", portStr) + log.Info().Msgf("Starting backend: %s", portStr) e.Logger.Fatal(e.Start(portStr)) } } diff --git a/pkg/api/agent.go b/pkg/api/agent.go index ad05e6382d4dd0d4613049a1c8bda6b9d5ff980a..230ca379877c355e4d9f89d44081bf1a2a3447d5 100644 --- a/pkg/api/agent.go +++ b/pkg/api/agent.go @@ -6,8 +6,8 @@ import ( "time" "0xacab.org/leap/menshen/pkg/models" - "github.com/apex/log" "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" ) func bridgesMatch(bridge1, bridge2 models.Bridge) bool { @@ -16,12 +16,12 @@ func bridgesMatch(bridge1, bridge2 models.Bridge) bool { if len(bridge1.Options) > 0 { bridge1OptionsBytes, err := json.Marshal(bridge1.Options) if err != nil { - log.Errorf("Could not marshal bridge1 options. Bridge1: %#v, err: %v", err) + log.Warn().Msgf("Could not marshal bridge1 options. Bridge1: %#v, err: %v", bridge1, err) return false } bridge2OptionsBytes, err := json.Marshal(bridge2.Options) if err != nil { - log.Errorf("Could not marshal bridge2 options. Bridge2: %#v, err: %v", err) + log.Warn().Msgf("Could not marshal bridge2 options. Bridge2: %#v, err: %v", bridge2, err) return false } @@ -73,7 +73,7 @@ func (r *registry) RegisterBridge(c echo.Context) error { // TODO: consider validation? err := c.Bind(&bridgeRequest) if err != nil { - log.Errorf("failed to bind request body: %v", err) + log.Warn().Msgf("failed to bind request body: %v", err) return c.JSON(http.StatusBadRequest, "bad request") } @@ -125,7 +125,7 @@ func (r *registry) RegisterGateway(c echo.Context) error { // TODO: consider validation? err := c.Bind(&gatewayRequest) if err != nil { - log.Errorf("failed to bind request body: %v", err) + log.Warn().Msgf("failed to bind request body: %v", err) return c.JSON(http.StatusBadRequest, "bad request") } diff --git a/pkg/api/api.go b/pkg/api/api.go index 27699b744e5923622d830d9d5e4078f28b0893f2..89e231f96af33bbfe1fd2b9da04624a78f9d26c7 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -4,10 +4,10 @@ import ( "fmt" "net/http" - "github.com/apex/log" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/rs/zerolog/log" echoSwagger "github.com/swaggo/echo-swagger" "golang.org/x/crypto/acme/autocert" @@ -25,7 +25,7 @@ func InitMetricsServer() *echo.Echo { } func InitServer(cfg *Config) *echo.Echo { - log.Info("Initializing server...") + log.Info().Msg("Initializing server...") if cfg.AutoTLS { sw.SwaggerInfo.Host = cfg.ServerName @@ -43,7 +43,7 @@ func InitServer(cfg *Config) *echo.Echo { db, err := storage.OpenDatabase(cfg.DBFile) if err != nil { - log.Fatalf("Error opening database: %v", err) + log.Fatal().Msgf("Error opening database: %v", err) } e.Use(storageMiddleware(db)) @@ -52,21 +52,34 @@ func InitServer(cfg *Config) *echo.Echo { // We don't want no panics in production //e.Use(middleware.Recover()) - e.Use(middleware.Logger()) + e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ + LogStatus: true, + LogURI: true, + LogMethod: true, + LogError: true, + LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { + if v.Error != nil { + log.Error().Msgf("Request: %s %s %d %s", v.Method, v.URI, v.Status, v.Error) + } else { + log.Info().Msgf("Request: %s %s %d", v.Method, v.URI, v.Status) + } + return nil + }, + })) if cfg.HasLegacyEIPFile() { - log.Info("Loading EIP file") + log.Info().Msg("Loading EIP file") } r, err := newRegistry(cfg) if err != nil { - log.Fatal(err.Error()) + log.Fatal().Msgf("Could not create registry: %s", err) } - log.Infof("Starting load balancer on: %s", cfg.LoadBalancerAddr) + log.Info().Msgf("Starting load balancer on %s", cfg.LoadBalancerAddr) lb, err := loadbalancer.StartLoadBalancer(cfg.LoadBalancerAddr) if err != nil { - log.Fatal(err.Error()) + log.Fatal().Msgf("Could not start load balancer: %s", err) } r.lb = lb diff --git a/pkg/api/auth.go b/pkg/api/auth.go index 9c783d376ee2a3de21ffc7ce0d36e424fbd5c917..672c593f26b3f57b91c78af215db5e2755d7d797 100644 --- a/pkg/api/auth.go +++ b/pkg/api/auth.go @@ -11,15 +11,15 @@ import ( "net/http" "strings" - "github.com/apex/log" "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" ) func authTokenMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { db, err := getDBFromContext(c) if err != nil { - log.Errorf("Error getting database from context") + log.Warn().Msgf("Error getting database from context: %s", err) return next(c) } @@ -34,7 +34,7 @@ func authTokenMiddleware(next echo.HandlerFunc) echo.HandlerFunc { var buckets string if err := db.QueryRow("SELECT buckets FROM tokens WHERE key = ?", authTokenHashString).Scan(&buckets); err != nil { - log.Errorf("Error querying for access token: %v", err) + log.Warn().Msgf("Could not find invite toke in database: %v", err) } else { bucketsSlice := strings.Split(buckets, ",") c.Set("buckets", bucketsSlice) @@ -53,7 +53,7 @@ func agentRegistrationMiddleware(sharedSecret string) func(echo.HandlerFunc) ech hmacHeaderBytes := make([]byte, hex.DecodedLen(len(hmacHeader))) _, err := hex.Decode(hmacHeaderBytes, []byte(hmacHeader)) if err != nil { - log.Errorf("Error decoding hmac auth bytes: %v", err) + log.Warn().Msgf("Error decoding hmac auth bytes: %v", err) return echo.NewHTTPError(http.StatusUnauthorized, "Please provide valid credentials") } @@ -67,7 +67,7 @@ func agentRegistrationMiddleware(sharedSecret string) func(echo.HandlerFunc) ech calculatedHMAC := []byte(computed.Sum(nil)) if subtle.ConstantTimeCompare(hmacHeaderBytes, calculatedHMAC) == 0 { - log.Errorf("HMAC provided invalid. Provided: %v, expected: %v", hmacHeader, hex.EncodeToString(calculatedHMAC)) + log.Warn().Msgf("HMAC provided invalid. Provided: %v, expected: %v", hmacHeader, hex.EncodeToString(calculatedHMAC)) return echo.NewHTTPError(http.StatusUnauthorized, "Please provide valid credentials") } diff --git a/pkg/api/cert.go b/pkg/api/cert.go index 7bdacdbd866e706a4a00df03cb8a406dd24984ab..ecfbe84d3316b848331edd14c583cdc55af6c321 100644 --- a/pkg/api/cert.go +++ b/pkg/api/cert.go @@ -13,12 +13,13 @@ import ( "encoding/pem" "fmt" "io" - "log" "math/big" "net/http" "strings" "time" + "github.com/rs/zerolog/log" + "github.com/labstack/echo/v4" ) @@ -246,7 +247,7 @@ func writePEMFormattedString(addEnvelope bool, buf io.Writer, pemString, tag str func (r *registry) CertProxy(c echo.Context, addRootCA bool) error { req, err := http.NewRequest(http.MethodGet, r.clientCertURL, nil) if err != nil { - log.Printf("client: could not create request: %s\n", err) + log.Warn().Msgf("client: could not create request: %s", err) return err } res, err := r.client.Do(req) @@ -255,10 +256,9 @@ func (r *registry) CertProxy(c echo.Context, addRootCA bool) error { } resBody, err := io.ReadAll(res.Body) if err != nil { - log.Printf("client: could not read response body: %s\n", err) + log.Warn().Msgf("client: could not read response body: %s", err) return err } - // log.Printf("client: response body: %s\n", resBody) if !addRootCA { return c.String(http.StatusOK, string(resBody)) } diff --git a/pkg/api/gateway.go b/pkg/api/gateway.go index a8bfca83ec56905a61d8e1a7d9cab7da2e962b91..7027777e3ba9bca3da5193e5a88c4ff6f2fa30ce 100644 --- a/pkg/api/gateway.go +++ b/pkg/api/gateway.go @@ -1,7 +1,6 @@ package api import ( - "log" "math" "math/rand" "net/http" @@ -10,6 +9,8 @@ import ( "strings" "time" + "github.com/rs/zerolog/log" + "github.com/labstack/echo/v4" "golang.org/x/exp/slices" @@ -51,14 +52,16 @@ func (r *registry) GatewayPicker(c echo.Context) error { keys = append(keys, k) } if !slices.Contains(keys, location) { - log.Println("[Debug]: specified location not in r.locations") + log.Debug(). + Str("location", location). + Msg("specified location not in r.locations") return c.JSON(http.StatusBadRequest, "Location not supported") } selectedLocation = location - log.Println("[Debug]: returning gateway for requested location", selectedLocation) + log.Debug().Msgf("returning gateway for requested location %s", selectedLocation) } else if countryCode != "" { // find nearest location for the given countryCode - log.Println("[Debug]: finding best gateway for Countrycode =", countryCode) + log.Debug().Msgf("finding best gateway for Countrycode = %s", countryCode) clientCentroid, err := geolocate.GetCentroidForCountry(countryCode) if err != nil { return c.JSON(http.StatusBadRequest, "CountryCode not supported") @@ -69,11 +72,11 @@ func (r *registry) GatewayPicker(c echo.Context) error { gatewayLat, err1 := strconv.ParseFloat(loc.Lat, 64) gatewayLon, err2 := strconv.ParseFloat(loc.Lon, 64) if err1 != nil || err2 != nil { - log.Printf("invalid latitude or longitude for location: %s", loc.DisplayName) + log.Debug().Msgf("invalid latitude or longitude for location: %s", loc.DisplayName) } - //log.Println(">>", loc.CountryCode, gatewayLat, gatewayLon) + log.Debug().Msgf(">> %s %f %f", loc.CountryCode, gatewayLat, gatewayLon) distance := euclideanDistance(clientCentroid.Lat, clientCentroid.Lon, gatewayLat, gatewayLon) - log.Println("[Debug]: distance to", loc.Label, "::", distance) + log.Debug().Msgf("distance to %s :: %f", loc.Label, distance) if distance < minDistance { minDistance = distance @@ -82,15 +85,15 @@ func (r *registry) GatewayPicker(c echo.Context) error { } } else { // choose random location - log.Println("[Debug]: request without countrycode") + log.Debug().Msg("request without countrycode") keys := make([]string, 0, len(r.locations)) for k := range r.locations { keys = append(keys, k) } - log.Println("[Debug]: returning gateway for random location") + log.Debug().Msg("returning gateway for random location") selectedLocation = keys[rand.Intn(len(keys))] - log.Println("[Debug]: returning gateway for randomly chosen location", selectedLocation) + log.Debug().Msgf("returning gateway for randomly chosen location %s", selectedLocation) } gateways := r.gateways[selectedLocation] @@ -163,7 +166,7 @@ func (r *registry) ListAllGateways(c echo.Context) error { selectedLocationLabels = getLabelsForLocations( geolocate.PickBestLocations(r.lm, cc, r.AllLocations())) } - log.Printf("Selecting gateways from locations: %v", selectedLocationLabels) + log.Info().Msgf("Selecting gateways from locations: %v", selectedLocationLabels) // Step 2a. We pass the pre-filter location selection to load balancer. // If load filtering is not enabled, we just apply a filter for the selected locations. @@ -174,7 +177,7 @@ func (r *registry) ListAllGateways(c echo.Context) error { // We pass only a subset of the gateways to the geolocation picker gatewaysByLoad, err := r.lb.SortGateways(selectedLocationLabels, gateways) if err != nil { - log.Printf("Load lookup error: %v", err) + log.Warn().Msgf("Load lookup error: %v", err) // we didn't succeed, so need to fallback to location-bucket selection. // this usually means that the load balancer is not receiving updates // from the agents matching the labels we've passed. diff --git a/pkg/api/genconfig.go b/pkg/api/genconfig.go index 4bc252bd97807bc2a0dc552833dd19b6f7c66605..d80bebeef8dfe514519f22f50ca7d1df3707d19b 100644 --- a/pkg/api/genconfig.go +++ b/pkg/api/genconfig.go @@ -3,10 +3,11 @@ package api import ( "fmt" "io" - "log" "net/http" "os" + "github.com/rs/zerolog/log" + "0xacab.org/leap/menshen/pkg/genconfig" "github.com/labstack/echo/v4" ) @@ -93,19 +94,19 @@ func (r *registry) getOpenVPNConfig(cfg *Config) (string, error) { if r.clientCertURL == "" { rawCert, err = r.CertWriter(cfg.OvpnCaCrt, cfg.OvpnCaKey, cfg.Algo, cfg.OvpnClientCrtExpiry, true) if err != nil { - log.Printf("getOpenvpnConfig: cert generation error: %s\n", err) + log.Warn().Msgf("getOpenvpnConfig: cert generation error: %v", err) return rawCert, err } ca, err := os.ReadFile(cfg.OvpnCaCrt) if err != nil { - log.Fatalf("getOpenvpnConfig: Could not read CA file '%s': %s", cfg.OvpnCaCrt, err) + log.Fatal().Msgf("getOpenvpnConfig: Could not read CA file '%s': %s", cfg.OvpnCaCrt, err) } CaCrt = string(ca) } else { req, err := http.NewRequest(http.MethodGet, r.clientCertURL, nil) if err != nil { - log.Printf("genconfig get cert error: %s\n", err) + log.Warn().Msgf("genconfig get cert error: %s", err) return "", err } @@ -123,7 +124,7 @@ func (r *registry) getOpenVPNConfig(cfg *Config) (string, error) { resBody, err := io.ReadAll(res.Body) if err != nil { - log.Printf("client: could not read response body: %s\n", err) + log.Warn().Msgf("client: could not read response body: %s", err) return "", err } @@ -132,14 +133,14 @@ func (r *registry) getOpenVPNConfig(cfg *Config) (string, error) { ca, err := os.ReadFile(cfg.CaFile) if err != nil { - log.Fatalf("getOpenvpnConfig: Could not read CA file '%s': %s", cfg.CaFile, err) + log.Fatal().Msgf("getOpenvpnConfig: Could not read CA file '%s': %s", cfg.CaFile, err) } CaCrt = string(ca) } conf, err := genconfig.SerializeConfig(rawCert, CaCrt, gw) if err != nil { - log.Printf("genconfig serialize error: %s\n", err) + log.Warn().Msgf("genconfig serialize error: %s", err) return "", err } return conf, nil diff --git a/pkg/api/registry.go b/pkg/api/registry.go index a51036e3b4f004a478a45be74f0b029ec0ac97b0..932435be8f95d2b60ea1da106051e5a5946753b2 100644 --- a/pkg/api/registry.go +++ b/pkg/api/registry.go @@ -4,13 +4,14 @@ import ( "encoding/json" "fmt" "io" - "log" "net/http" "os" "strconv" "strings" "time" + "github.com/rs/zerolog/log" + "0xacab.org/leap/menshen/pkg/geolocate" "0xacab.org/leap/menshen/pkg/latency" "0xacab.org/leap/menshen/pkg/loadbalancer" @@ -63,7 +64,7 @@ func newRegistry(cfg *Config) (*registry, error) { locations := make(locationMap, 0) if cfg.ProviderJson == "" { - log.Fatal("File path to provider.json is missing.") + log.Fatal().Msg("File path to provider.json is missing.") } provider, err := ParseProviderJsonFile(cfg.ProviderJson) if err != nil { @@ -71,12 +72,12 @@ func newRegistry(cfg *Config) (*registry, error) { } if cfg.CaFile == "" { - log.Fatal("File path to root CA is missing.") + log.Fatal().Msg("File path to root CA is missing.") } var httpClient http.Client ca, err := os.ReadFile(cfg.CaFile) if err != nil { - log.Fatalf(fmt.Sprintf("Could not read CA file '%s': %s", cfg.CaFile, err)) + log.Fatal().Msgf("Could not read CA file '%s': %s", cfg.CaFile, err) } httpClient = initTLSProxy(ca) @@ -85,7 +86,7 @@ func newRegistry(cfg *Config) (*registry, error) { // eip-service JSON format served as of version 3. // TODO: this should be moved into its own parsing function. if cfg.EIPURL != "" && cfg.EIP != "" { - log.Fatal("Both eip-url and eip-file cannot be set at the same time.") + log.Fatal().Msg("Both eip-url and eip-file cannot be set at the same time.") } var eipFile string @@ -95,7 +96,7 @@ func newRegistry(cfg *Config) (*registry, error) { } else { // It must be that we have a URL, because HasLegacyEIPFile returns either or. if err := downloadToFile(httpClient, cfg.EIPURL, tmpEIPFilePath); err != nil { - log.Fatalf("Could not fetch external EIP File: %s", err) + log.Fatal().Msgf("Could not fetch external EIP File: %s", err) } eipFile = tmpEIPFilePath defer os.Remove(tmpEIPFilePath) @@ -169,7 +170,7 @@ func newRegistry(cfg *Config) (*registry, error) { if _, exists := locations[loc]; exists { locations[loc].HasBridges = true } else { - log.Fatalf("Could not find matching loation %s in locations list", loc) + log.Fatal().Msgf("Could not find matching loation %s in locations list", loc) } } } @@ -194,50 +195,50 @@ func newRegistry(cfg *Config) (*registry, error) { // TODO move to a different map (for private bridges). time.Sleep(time.Second) // just to make sure all nodes are up. - log.Printf("Bridges: %v", cfg.LocalBridges) + log.Info().Msgf("Bridges: %v", cfg.LocalBridges) for _, controlBridge := range cfg.LocalBridges { _parts := strings.Split(controlBridge, ":") host := _parts[0] url := fmt.Sprintf("http://%s/bridge", controlBridge) - log.Printf("Fetching bridge info from %s", url) + log.Info().Msgf("Fetching bridge info from %s", url) resp, err := http.Get(url) if err != nil { - log.Printf("error: %v", err) + log.Warn().Msgf("error: %v", err) continue } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - log.Printf("status code: %v", resp.StatusCode) + log.Warn().Msgf("status code: %v", resp.StatusCode) continue } body, err := io.ReadAll(resp.Body) if err != nil { - log.Printf("error reading: %v", err) + log.Warn().Msgf("error reading: %v", err) continue } var bridge m.Bridge if err := json.Unmarshal(body, &bridge); err != nil { - log.Printf("error unmarshal: %v", err) + log.Warn().Msgf("error unmarshal: %v", err) } bridge.Host = host if bridge.Type == "obfs4" { bridge.Transport = "tcp" } bridges[bridge.Location] = []*m.Bridge{&bridge} - log.Println("Parsed bridge status ok") + log.Info().Msg("Parsed bridge status ok") } - log.Printf("%d locations", len(locations)) - log.Printf("%d locations with gateways\n", len(gateways)) - log.Printf("%d locations with bridges\n", len(bridges)) - log.Println("openvpn_config:", openvpnConfig) + log.Info().Msgf("%d locations", len(locations)) + log.Info().Msgf("%d locations with gateways", len(gateways)) + log.Info().Msgf("%d locations with bridges", len(bridges)) + log.Info().Msgf("openvpn_config: %s", openvpnConfig) lm, err := latency.NewMetric() if err != nil { - log.Println("Error initializing latency metric", err) + log.Warn().Msgf("Error initializing latency metric: %s", err) } r := ®istry{ diff --git a/pkg/geolocate/distance.go b/pkg/geolocate/distance.go index 1e9dce62fc292dff933b45b1b75f5d8259473ba8..fbcb1ccfe2d8207f7c8b8a7b09da5d44d97eed55 100644 --- a/pkg/geolocate/distance.go +++ b/pkg/geolocate/distance.go @@ -7,8 +7,8 @@ import ( "strconv" "strings" - "github.com/apex/log" g "github.com/kellydunn/golang-geo" + "github.com/rs/zerolog/log" "golang.org/x/exp/slices" "gonum.org/v1/gonum/floats" @@ -43,12 +43,12 @@ func PickBestLocations(lm *latency.Metric, cc string, locations []*models.Locati byLat = byLat[:min(len(byLat), maxLocations)] for _, el := range byDist { - fmt.Println(">>> by distance", el.Label) + log.Info().Msgf(">>> by distance %s", el.Label) set[el.Label] = el } for _, el := range byLat { - fmt.Println(">>> by latency", el.Label) + log.Info().Msgf(">>> by latency %s", el.Label) set[el.Label] = el } @@ -204,9 +204,7 @@ func GetEstimatedLatencyBetweenCountries(lm *latency.Metric, from, to string) fl return math.Inf(1) } - //log.Debugf("nearest is: %s", nearest) - fmt.Printf("nearest is: %s\n", nearest) - + log.Debug().Msgf("nearest is: %s", nearest) // The long leg is a known latency metric (ms) long := lm.Distance(to, nearest) @@ -216,7 +214,7 @@ func GetEstimatedLatencyBetweenCountries(lm *latency.Metric, from, to string) fl return math.Inf(1) } - log.Debugf("short is: %.3f km apart", short) + log.Debug().Msgf("short is: %.3f km apart", short) // ... so we just have to add a correction that takes the theoretical speed of light into account. return long + getSpeedOfLightDelay(short) diff --git a/pkg/geolocate/lookup.go b/pkg/geolocate/lookup.go index 6296993c0c5512ad048cd37aec2b7a175346b83c..3b4fb2c7a553422a8a0754ec098361a2689c0a3f 100644 --- a/pkg/geolocate/lookup.go +++ b/pkg/geolocate/lookup.go @@ -3,6 +3,8 @@ package geolocate import ( "fmt" "strings" + + "github.com/rs/zerolog/log" ) var ErrUnknownCountry = "unknown country code" @@ -78,7 +80,7 @@ func ContinentCodeToLabel(i int) string { func GetContinentForCountryCode(cc string) int { country := regions[strings.ToUpper(cc)] - fmt.Println("cc", country) + log.Debug().Msgf("cc %s", country) if country == nil || country.Continent == "" { return XX } diff --git a/pkg/latency/latency.go b/pkg/latency/latency.go index 1619724a7e82286c45a493e12c9bcf44255ce537..50378655f9237d93c0cfaec923061a264f7bba73 100644 --- a/pkg/latency/latency.go +++ b/pkg/latency/latency.go @@ -3,10 +3,11 @@ package latency import ( "embed" "encoding/csv" - "log" "math" "strconv" + "github.com/rs/zerolog/log" + "golang.org/x/exp/slices" "gonum.org/v1/gonum/mat" ) @@ -23,7 +24,9 @@ func NewMetric() (*Metric, error) { // Open the embedded latency source file file, err := f.Open("distance.csv") if err != nil { - log.Println("Error:", err) + log.Warn(). + Err(err). + Msg("Could not open distance.csv in NewMetric") return nil, err } defer file.Close() @@ -34,7 +37,9 @@ func NewMetric() (*Metric, error) { // Read all the records records, err := reader.ReadAll() if err != nil { - log.Println("Error:", err) + log.Warn(). + Err(err). + Msg("Could not read from file") return nil, err } diff --git a/pkg/loadbalancer/lb.go b/pkg/loadbalancer/lb.go index c6283b2e3d56f11c0f1a13d49671b85574a7fa6e..f151b627ff9ec0a4461f968d10b94cec580ee157 100644 --- a/pkg/loadbalancer/lb.go +++ b/pkg/loadbalancer/lb.go @@ -25,7 +25,7 @@ import ( "0xacab.org/leap/menshen/pkg/models" "git.autistici.org/ale/lb" lbpb "git.autistici.org/ale/lb/proto" - "github.com/apex/log" + "github.com/rs/zerolog/log" "google.golang.org/grpc" ) @@ -93,7 +93,9 @@ func StartLoadBalancer(bindAddr string) (*LoadBalancer, error) { go func() { err := server.Serve(listener) if err != nil { - log.WithError(err).Error("grpc server Serve() failed") + log.Warn(). + Err(err). + Msg("grpc server Serve() failed") } }()