diff --git a/setup.go b/setup.go index 9820cf0..2832b16 100644 --- a/setup.go +++ b/setup.go @@ -33,6 +33,7 @@ const ( envLoggingURL = "GOLOG_URL" // url that will be processed by sink in the zap envLoggingOutput = "GOLOG_OUTPUT" // possible values: stdout|stderr|file combine multiple values with '+' + envLoggingLabels = "GOLOG_LOG_LABELS" // comma-separated key-value pairs, i.e. "app=example_app,dc=sjc-1" ) type LogFormat int @@ -61,6 +62,9 @@ type Config struct { // URL with schema supported by zap. Use zap.RegisterSink URL string + + // Labels is a set of key-values to apply to all loggers + Labels map[string]string } // ErrNoSuchLogger is returned when the util pkg is asked for a non existant logger @@ -122,6 +126,11 @@ func SetupLogging(cfg Config) { } newPrimaryCore := newCore(primaryFormat, ws, LevelDebug) // the main core needs to log everything. + + for k, v := range cfg.Labels { + newPrimaryCore = newPrimaryCore.With([]zap.Field{zap.String(k, v)}) + } + if primaryCore != nil { loggerCore.ReplaceCore(primaryCore, newPrimaryCore) } else { @@ -240,6 +249,7 @@ func configFromEnv() Config { Format: ColorizedOutput, Stderr: true, Level: LevelError, + Labels: map[string]string{}, } format := os.Getenv(envLoggingFmt) @@ -293,5 +303,14 @@ func configFromEnv() Config { } } + labels := os.Getenv(envLoggingLabels) + if labels != "" { + labelKVs := strings.Split(labels, ",") + for _, label := range labelKVs { + kv := strings.Split(label, "=") + cfg.Labels[kv[0]] = kv[1] + } + } + return cfg } diff --git a/setup_test.go b/setup_test.go index 549e089..3dc2137 100644 --- a/setup_test.go +++ b/setup_test.go @@ -121,4 +121,36 @@ func TestLogToFile(t *testing.T) { t.Logf("want: '%s', got: '%s'", want, string(content)) t.Fail() } -} \ No newline at end of file +} + +func TestLogLabels(t *testing.T) { + r, w, err := os.Pipe() + if err != nil { + t.Fatalf("failed to open pipe: %v", err) + } + + stderr := os.Stderr + os.Stderr = w + defer func() { + os.Stderr = stderr + }() + + // set the go-log labels env var + os.Setenv(envLoggingLabels, "app=example_app,dc=sjc-1") + SetupLogging(configFromEnv()) + + log := getLogger("test") + + log.Error("scooby") + w.Close() + + buf := &bytes.Buffer{} + if _, err := io.Copy(buf, r); err != nil && err != io.ErrClosedPipe { + t.Fatalf("unexpected error: %v", err) + } + + t.Log(buf.String()) + if !strings.Contains(buf.String(), "{\"app\": \"example_app\", \"dc\": \"sjc-1\"}") { + t.Errorf("got %q, wanted it to contain log output", buf.String()) + } +}