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.