From 2403c0e1981d6cd3ca60a88c3fc38be7e3e84810 Mon Sep 17 00:00:00 2001 From: Igor Perepilitsyn Date: Sat, 18 Jun 2022 15:00:47 +0300 Subject: [PATCH 1/5] toggle json logging via config --- cmd/headscale/cli/root.go | 4 ++++ config-example.yaml | 1 + config.go | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/cmd/headscale/cli/root.go b/cmd/headscale/cli/root.go index 459a99f..659358f 100644 --- a/cmd/headscale/cli/root.go +++ b/cmd/headscale/cli/root.go @@ -55,6 +55,10 @@ func initConfig() { zerolog.SetGlobalLevel(zerolog.Disabled) } + if cfg.JSONLogs { + log.Logger = log.Output(os.Stdout) + } + if !cfg.DisableUpdateCheck && !machineOutput { if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && Version != "dev" { diff --git a/config-example.yaml b/config-example.yaml index 2019a13..883d81f 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -173,6 +173,7 @@ tls_cert_path: "" tls_key_path: "" log_level: info +json_logs: false # Path to a file containg ACL policies. # ACLs can be defined as YAML or HUJSON. diff --git a/config.go b/config.go index 0024731..83cfc62 100644 --- a/config.go +++ b/config.go @@ -37,6 +37,7 @@ type Config struct { NoisePrivateKeyPath string BaseDomain string LogLevel zerolog.Level + JSONLogs bool DisableUpdateCheck bool DERP DERPConfig @@ -147,6 +148,7 @@ func LoadConfig(path string, isFile bool) error { viper.SetDefault("tls_client_auth_mode", "relaxed") viper.SetDefault("log_level", "info") + viper.SetDefault("json_logs", false) viper.SetDefault("dns_config", nil) @@ -434,6 +436,7 @@ func GetHeadscaleConfig() (*Config, error) { if err != nil { logLevel = zerolog.DebugLevel } + jsonLogs := viper.GetBool("json_logs") legacyPrefixField := viper.GetString("ip_prefix") if len(legacyPrefixField) > 0 { @@ -488,6 +491,7 @@ func GetHeadscaleConfig() (*Config, error) { GRPCAllowInsecure: viper.GetBool("grpc_allow_insecure"), DisableUpdateCheck: viper.GetBool("disable_check_updates"), LogLevel: logLevel, + JSONLogs: jsonLogs, IPPrefixes: prefixes, PrivateKeyPath: AbsolutePathFromConfigPath( From bb6b07dedcb15b9f84138ece6dac503b1065bcd4 Mon Sep 17 00:00:00 2001 From: Igor Perepilitsyn Date: Fri, 26 Aug 2022 13:43:25 +0200 Subject: [PATCH 2/5] FIXES #768 add new config entry to the old itegration tests --- integration_test/etc/alt-config.dump.gold.yaml | 1 + integration_test/etc/alt-env-config.dump.gold.yaml | 1 + integration_test/etc/config.dump.gold.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/integration_test/etc/alt-config.dump.gold.yaml b/integration_test/etc/alt-config.dump.gold.yaml index 3d38b12..07544d4 100644 --- a/integration_test/etc/alt-config.dump.gold.yaml +++ b/integration_test/etc/alt-config.dump.gold.yaml @@ -29,6 +29,7 @@ ip_prefixes: - 100.64.0.0/10 listen_addr: 0.0.0.0:18080 log_level: disabled +json_logs: false logtail: enabled: false metrics_listen_addr: 127.0.0.1:19090 diff --git a/integration_test/etc/alt-env-config.dump.gold.yaml b/integration_test/etc/alt-env-config.dump.gold.yaml index f3ebd08..805c25a 100644 --- a/integration_test/etc/alt-env-config.dump.gold.yaml +++ b/integration_test/etc/alt-env-config.dump.gold.yaml @@ -28,6 +28,7 @@ ip_prefixes: - 100.64.0.0/10 listen_addr: 0.0.0.0:18080 log_level: disabled +json_logs: false logtail: enabled: false metrics_listen_addr: 127.0.0.1:19090 diff --git a/integration_test/etc/config.dump.gold.yaml b/integration_test/etc/config.dump.gold.yaml index 91ca5b9..ff61c6f 100644 --- a/integration_test/etc/config.dump.gold.yaml +++ b/integration_test/etc/config.dump.gold.yaml @@ -29,6 +29,7 @@ ip_prefixes: - 100.64.0.0/10 listen_addr: 0.0.0.0:8080 log_level: disabled +json_logs: false logtail: enabled: false metrics_listen_addr: 127.0.0.1:9090 From dd155dca97809d72a2ac6e031608b23f4d37a1fd Mon Sep 17 00:00:00 2001 From: Igor Perepilitsyn Date: Sun, 11 Sep 2022 21:37:23 +0200 Subject: [PATCH 3/5] Create a distinct log section in config --- cmd/headscale/cli/root.go | 4 +- config-example.yaml | 6 ++- config.go | 54 ++++++++++++++----- .../etc/alt-config.dump.gold.yaml | 5 +- integration_test/etc/alt-config.yaml | 3 +- .../etc/alt-env-config.dump.gold.yaml | 5 +- integration_test/etc/alt-env-config.yaml | 3 +- integration_test/etc/config.dump.gold.yaml | 5 +- integration_test/etc/config.yaml | 3 +- 9 files changed, 62 insertions(+), 26 deletions(-) diff --git a/cmd/headscale/cli/root.go b/cmd/headscale/cli/root.go index 659358f..60186b5 100644 --- a/cmd/headscale/cli/root.go +++ b/cmd/headscale/cli/root.go @@ -47,7 +47,7 @@ func initConfig() { machineOutput := HasMachineOutputFlag() - zerolog.SetGlobalLevel(cfg.LogLevel) + zerolog.SetGlobalLevel(cfg.Log.Level) // If the user has requested a "machine" readable format, // then disable login so the output remains valid. @@ -55,7 +55,7 @@ func initConfig() { zerolog.SetGlobalLevel(zerolog.Disabled) } - if cfg.JSONLogs { + if cfg.Log.Format == headscale.JSONLogFormat { log.Logger = log.Output(os.Stdout) } diff --git a/config-example.yaml b/config-example.yaml index 883d81f..69672b2 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -172,8 +172,10 @@ tls_letsencrypt_listen: ":http" tls_cert_path: "" tls_key_path: "" -log_level: info -json_logs: false +log: + # Output formatting for logs: text or json + format: text + level: info # Path to a file containg ACL policies. # ACLs can be defined as YAML or HUJSON. diff --git a/config.go b/config.go index ed007c1..b000c56 100644 --- a/config.go +++ b/config.go @@ -22,6 +22,9 @@ import ( const ( tlsALPN01ChallengeType = "TLS-ALPN-01" http01ChallengeType = "HTTP-01" + + JSONLogFormat = "json" + TextLogFormat = "text" ) // Config contains the initial Headscale configuration. @@ -37,8 +40,7 @@ type Config struct { PrivateKeyPath string NoisePrivateKeyPath string BaseDomain string - LogLevel zerolog.Level - JSONLogs bool + Log LogConfig DisableUpdateCheck bool DERP DERPConfig @@ -125,6 +127,11 @@ type ACLConfig struct { PolicyPath string } +type LogConfig struct { + Format string + Level zerolog.Level +} + func LoadConfig(path string, isFile bool) error { if isFile { viper.SetConfigFile(path) @@ -148,8 +155,8 @@ func LoadConfig(path string, isFile bool) error { viper.SetDefault("tls_letsencrypt_challenge_type", http01ChallengeType) viper.SetDefault("tls_client_auth_mode", "relaxed") - viper.SetDefault("log_level", "info") - viper.SetDefault("json_logs", false) + viper.SetDefault("log.level", "info") + viper.SetDefault("log.format", TextLogFormat) viper.SetDefault("dns_config", nil) @@ -336,6 +343,34 @@ func GetACLConfig() ACLConfig { } } +func GetLogConfig() LogConfig { + logLevelStr := viper.GetString("log.level") + logLevel, err := zerolog.ParseLevel(logLevelStr) + if err != nil { + logLevel = zerolog.DebugLevel + } + + logFormatOpt := viper.GetString("log.format") + var logFormat string + switch logFormatOpt { + case "json": + logFormat = JSONLogFormat + case "text": + logFormat = TextLogFormat + case "": + logFormat = TextLogFormat + default: + log.Error(). + Str("func", "GetLogConfig"). + Msgf("Could not parse log format: %s. Valid choices are 'json' or 'text'", logFormatOpt) + } + + return LogConfig{ + Format: logFormat, + Level: logLevel, + } +} + func GetDNSConfig() (*tailcfg.DNSConfig, string) { if viper.IsSet("dns_config") { dnsConfig := &tailcfg.DNSConfig{} @@ -432,13 +467,6 @@ func GetHeadscaleConfig() (*Config, error) { configuredPrefixes := viper.GetStringSlice("ip_prefixes") parsedPrefixes := make([]netip.Prefix, 0, len(configuredPrefixes)+1) - logLevelStr := viper.GetString("log_level") - logLevel, err := zerolog.ParseLevel(logLevelStr) - if err != nil { - logLevel = zerolog.DebugLevel - } - jsonLogs := viper.GetBool("json_logs") - legacyPrefixField := viper.GetString("ip_prefix") if len(legacyPrefixField) > 0 { log. @@ -491,8 +519,6 @@ func GetHeadscaleConfig() (*Config, error) { GRPCAddr: viper.GetString("grpc_listen_addr"), GRPCAllowInsecure: viper.GetBool("grpc_allow_insecure"), DisableUpdateCheck: viper.GetBool("disable_check_updates"), - LogLevel: logLevel, - JSONLogs: jsonLogs, IPPrefixes: prefixes, PrivateKeyPath: AbsolutePathFromConfigPath( @@ -554,5 +580,7 @@ func GetHeadscaleConfig() (*Config, error) { }, ACL: GetACLConfig(), + + Log: GetLogConfig(), }, nil } diff --git a/integration_test/etc/alt-config.dump.gold.yaml b/integration_test/etc/alt-config.dump.gold.yaml index 07544d4..c9bd39b 100644 --- a/integration_test/etc/alt-config.dump.gold.yaml +++ b/integration_test/etc/alt-config.dump.gold.yaml @@ -28,8 +28,9 @@ ip_prefixes: - fd7a:115c:a1e0::/48 - 100.64.0.0/10 listen_addr: 0.0.0.0:18080 -log_level: disabled -json_logs: false +log: + level: disabled + format: text logtail: enabled: false metrics_listen_addr: 127.0.0.1:19090 diff --git a/integration_test/etc/alt-config.yaml b/integration_test/etc/alt-config.yaml index 179fdcd..837ba6c 100644 --- a/integration_test/etc/alt-config.yaml +++ b/integration_test/etc/alt-config.yaml @@ -1,4 +1,5 @@ -log_level: trace +log: + level: trace acl_policy_path: "" db_type: sqlite3 ephemeral_node_inactivity_timeout: 30m diff --git a/integration_test/etc/alt-env-config.dump.gold.yaml b/integration_test/etc/alt-env-config.dump.gold.yaml index 805c25a..4df4bf4 100644 --- a/integration_test/etc/alt-env-config.dump.gold.yaml +++ b/integration_test/etc/alt-env-config.dump.gold.yaml @@ -27,8 +27,9 @@ ip_prefixes: - fd7a:115c:a1e0::/48 - 100.64.0.0/10 listen_addr: 0.0.0.0:18080 -log_level: disabled -json_logs: false +log: + level: disabled + format: text logtail: enabled: false metrics_listen_addr: 127.0.0.1:19090 diff --git a/integration_test/etc/alt-env-config.yaml b/integration_test/etc/alt-env-config.yaml index 4f19526..3856048 100644 --- a/integration_test/etc/alt-env-config.yaml +++ b/integration_test/etc/alt-env-config.yaml @@ -1,4 +1,5 @@ -log_level: trace +log: + level: trace acl_policy_path: "" db_type: sqlite3 ephemeral_node_inactivity_timeout: 30m diff --git a/integration_test/etc/config.dump.gold.yaml b/integration_test/etc/config.dump.gold.yaml index ff61c6f..158a195 100644 --- a/integration_test/etc/config.dump.gold.yaml +++ b/integration_test/etc/config.dump.gold.yaml @@ -28,8 +28,9 @@ ip_prefixes: - fd7a:115c:a1e0::/48 - 100.64.0.0/10 listen_addr: 0.0.0.0:8080 -log_level: disabled -json_logs: false +log: + format: text + level: disabled logtail: enabled: false metrics_listen_addr: 127.0.0.1:9090 diff --git a/integration_test/etc/config.yaml b/integration_test/etc/config.yaml index da842cc..8b4d7db 100644 --- a/integration_test/etc/config.yaml +++ b/integration_test/etc/config.yaml @@ -1,4 +1,5 @@ -log_level: trace +log: + level: trace acl_policy_path: "" db_type: sqlite3 ephemeral_node_inactivity_timeout: 30m From ae4f2cc4b520a560752c6a458527ee6fe3600f44 Mon Sep 17 00:00:00 2001 From: Igor Perepilitsyn Date: Sun, 11 Sep 2022 21:37:38 +0200 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf0afb7..a829f12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,17 @@ ## 0.17.0 (2022-XX-XX) +### BREAKING + +- Log level option `log_level` was moved to a distinct `log` config section and renamed to `level` [#768](https://github.com/juanfont/headscale/pull/768) +### Changes + - Added support for Tailscale TS2021 protocol [#738](https://github.com/juanfont/headscale/pull/738) - Add ability to specify config location via env var `HEADSCALE_CONFIG` [#674](https://github.com/juanfont/headscale/issues/674) - Target Go 1.19 for Headscale [#778](https://github.com/juanfont/headscale/pull/778) - Target Tailscale v1.30.0 to build Headscale [#780](https://github.com/juanfont/headscale/pull/780) - Give a warning when running Headscale with reverse proxy improperly configured for WebSockets [#788](https://github.com/juanfont/headscale/pull/788) +- Added support for JSON logs [#653](https://github.com/juanfont/headscale/issues/653) ## 0.16.4 (2022-08-21) From 874d6aaf6b9ce8563e09d3d4da8a3b100c4f04b5 Mon Sep 17 00:00:00 2001 From: Igor Perepilitsyn Date: Sun, 11 Sep 2022 21:44:28 +0200 Subject: [PATCH 5/5] Make styling fixes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a829f12..0d251a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### BREAKING - Log level option `log_level` was moved to a distinct `log` config section and renamed to `level` [#768](https://github.com/juanfont/headscale/pull/768) + ### Changes - Added support for Tailscale TS2021 protocol [#738](https://github.com/juanfont/headscale/pull/738)