diff --git a/logging/config.go b/logging/config.go index bed0ba167d..b6100c2dc5 100644 --- a/logging/config.go +++ b/logging/config.go @@ -33,6 +33,8 @@ import ( const ConfigMapNameEnv = "CONFIG_LOGGING_NAME" +var zapLoggerConfig = "zap-logger-config" + // NewLogger creates a logger with the supplied configuration. // In addition to the logger, it returns AtomicLevel that can // be used to change the logging level at runtime. @@ -196,3 +198,41 @@ func ConfigMapName() string { } return cm } + +// JsonToLoggingConfig converts a json string of a Config. +// Returns a non-nil Config always. +func JsonToLoggingConfig(jsonCfg string) (*Config, error) { + if jsonCfg == "" { + return nil, errors.New("json logging string is empty") + } + + var configMap map[string]string + if err := json.Unmarshal([]byte(jsonCfg), &configMap); err != nil { + return nil, err + } + + cfg, err := NewConfigFromMap(configMap) + if err != nil { + // Get the default config from logging package. + if cfg, err = NewConfigFromMap(map[string]string{}); err != nil { + return nil, err + } + } + return cfg, nil +} + +// LoggingConfigToJson converts a Config to a json string. +func LoggingConfigToJson(cfg *Config) (string, error) { + if cfg == nil || cfg.LoggingConfig == "" { + return "", nil + } + + jsonCfg, err := json.Marshal(map[string]string{ + zapLoggerConfig: cfg.LoggingConfig, + }) + if err != nil { + return "", err + } + + return string(jsonCfg), nil +} diff --git a/logging/config_test.go b/logging/config_test.go index 6458694761..5f73175ccb 100644 --- a/logging/config_test.go +++ b/logging/config_test.go @@ -17,6 +17,7 @@ limitations under the License. package logging import ( + "github.com/google/go-cmp/cmp" "testing" "go.uber.org/zap" @@ -288,3 +289,59 @@ func TestUpdateLevelFromConfigMap(t *testing.T) { } } } + +func TestLoggingConfig(t *testing.T) { + testCases := map[string]struct { + cfg *Config + want string + wantErr string + }{ + "nil": { + cfg: nil, + want: "", + wantErr: "json logging string is empty", + }, + "happy": { + cfg: &Config{ + LoggingConfig: "{}", + LoggingLevel: map[string]zapcore.Level{}, + }, + want: `{"zap-logger-config":"{}"}`, + }, + } + for n, tc := range testCases { + t.Run(n, func(t *testing.T) { + json, err := LoggingConfigToJson(tc.cfg) + if err != nil { + t.Errorf("error while converting logging config to json: %v", err) + } + // Test to json. + { + want := tc.want + got := json + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected (-want, +got) = %v", diff) + t.Log(got) + } + } + // Test to config. + if tc.cfg != nil { + want := tc.cfg + got, gotErr := JsonToLoggingConfig(json) + + if gotErr != nil { + if diff := cmp.Diff(tc.wantErr, gotErr.Error()); diff != "" { + t.Errorf("unexpected err (-want, +got) = %v", diff) + } + } else if tc.wantErr != "" { + t.Errorf("expected err %v", tc.wantErr) + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected (-want, +got) = %v", diff) + t.Log(got) + } + } + }) + } +} diff --git a/metrics/config.go b/metrics/config.go index 627e064a34..c74d8f1c83 100644 --- a/metrics/config.go +++ b/metrics/config.go @@ -17,6 +17,7 @@ limitations under the License. package metrics import ( + "encoding/json" "errors" "fmt" "os" @@ -291,3 +292,32 @@ import ( _ "knative.dev/pkg/metrics/testing" )`, DomainEnv, DomainEnv)) } + +// JsonToMetricsOptions converts a json string of a +// ExporterOptions. Returns a non-nil ExporterOptions always. +func JsonToMetricsOptions(jsonOpts string) (*ExporterOptions, error) { + var opts ExporterOptions + if jsonOpts == "" { + return nil, errors.New("json options string is empty") + } + + if err := json.Unmarshal([]byte(jsonOpts), &opts); err != nil { + return nil, err + } + + return &opts, nil +} + +// MetricsOptionsToJson converts a ExporterOptions to a json string. +func MetricsOptionsToJson(opts *ExporterOptions) (string, error) { + if opts == nil { + return "", nil + } + + jsonOpts, err := json.Marshal(opts) + if err != nil { + return "", err + } + + return string(jsonOpts), nil +} diff --git a/metrics/config_test.go b/metrics/config_test.go index 42caed562c..798ef84be7 100644 --- a/metrics/config_test.go +++ b/metrics/config_test.go @@ -1,9 +1,12 @@ /* -Copyright 2018 The Knative Authors. +Copyright 2018 The Knative Authors + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -13,6 +16,7 @@ limitations under the License. package metrics import ( + "github.com/google/go-cmp/cmp" "os" "path" "reflect" @@ -522,3 +526,64 @@ func TestUpdateExporter_doesNotCreateExporter(t *testing.T) { }) } } + +func TestMetricsOptions(t *testing.T) { + testCases := map[string]struct { + opts *ExporterOptions + want string + wantErr string + }{ + "nil": { + opts: nil, + want: "", + wantErr: "json options string is empty", + }, + "happy": { + opts: &ExporterOptions{ + Domain: "domain", + Component: "component", + PrometheusPort: 9090, + ConfigMap: map[string]string{ + "foo": "bar", + "boosh": "kakow", + }, + }, + want: `{"Domain":"domain","Component":"component","PrometheusPort":9090,"ConfigMap":{"boosh":"kakow","foo":"bar"}}`, + }, + } + for n, tc := range testCases { + t.Run(n, func(t *testing.T) { + jsonOpts, err := MetricsOptionsToJson(tc.opts) + if err != nil { + t.Errorf("error while converting metrics config to json: %v", err) + } + // Test to json. + { + want := tc.want + got := jsonOpts + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected (-want, +got) = %v", diff) + t.Log(got) + } + } + // Test to options. + { + want := tc.opts + got, gotErr := JsonToMetricsOptions(jsonOpts) + + if gotErr != nil { + if diff := cmp.Diff(tc.wantErr, gotErr.Error()); diff != "" { + t.Errorf("unexpected err (-want, +got) = %v", diff) + } + } else if tc.wantErr != "" { + t.Errorf("expected err %v", tc.wantErr) + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected (-want, +got) = %v", diff) + t.Log(got) + } + } + }) + } +}