Feature #20864
openAllow `Kernel#warn` to accept `**options` and pass these to `Warning.warn`.
Description
Background¶
Structured logging is a practice that organizes log data in a consistent, easily parseable format. Unlike traditional unstructured logs, which often consist of plain text entries, structured logs format information in key-value pairs or structured data formats such as JSON. This allows for better automation, searchability, and analysis of log data.
In Ruby, Kernel#warn
is extremely useful, especially because there is a mechanism for loggers to redirect warnings using the Warning
module. However, it is difficult to generate structured logs with Kernel#warn
as all the positional arguments are converted to a single string, and arbitrary keyword options are rejected.
As a consequence, code like this is not possible:
begin
...
rescue => error
warn "Something went wrong!", exception: error
end
It is very desirable to have a standard interface in Ruby for emitting structured warnings.
Proposal¶
I'd like to extend the current implementation to allow all options to be forwarded to Warning.warn
. This would allow us to add more details to warnings and emit structured logs using Warning.warn
.
A simple example of the proposed interface:
module Kernel
def warn(*arguments, uplevel: ..., **options)
# Existing processing of arguments -> message
::Warning.warn(message, **options)
end
end
Current behaviour rejects any unknown options:
warn("Oops", exception: error)
# => <internal:warning>:50:in `warn': unknown keyword: :exception (ArgumentError)
I don't have an opinion about the implementation, but I wanted to get feedback on the interface.
Regarding the default behaviour, I propose no changes.