Skip to content

Bring Fatal Log Level to Slog Handler #8235

@mkadirtan

Description

@mkadirtan

// - [slog.LevelDebug] is transformed to [log.SeverityDebug]
// - [slog.LevelInfo] is transformed to [log.SeverityInfo]
// - [slog.LevelWarn] is transformed to [log.SeverityWarn]
// - [slog.LevelError] is transformed to [log.SeverityError]

As you already know, slog doesn't expose a level higher than LevelError. But what we can do is to define higher log levels and use them like this:

const LevelFatal = slog.LevelError + 4

logger.Log(ctx, LevelFatal, "critical log message")

Which is logged as "ERROR+4" by default in slog handler. Unless you use a custom ReplaceAttr function like this:

func replaceAttr(_ []string, attr slog.Attr) slog.Attr {
  if attr.Key != slog.LevelKey || attr.Value.String() != "ERROR+4" {
  	return attr
  }

  return slog.Attr{
	Key:   slog.LevelKey,
	Value: slog.StringValue("FATAL"),
  }
}

logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
  ReplaceAttr: replaceAttr
}))

logger.Log(ctx, LevelFatal, "critical log message")

I've noticed that the otelslog package maps the slog levels to the otel severities, but it still uses the String() value of the slog.Level instead of Severities own String() value.

Is it possible to switch from the following snippet:

record.SetSeverityText(r.Level.String())

into something like this:

severity := log.Severity(r.Level + sevOffset)
record.SetSeverity(severity)
record.SetSeverityText(severity.String())

if not, what is the rationale behind this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bridge: slogRelated to the slog bridgeenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions