Skip to content

Logger improvements #1423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Logger improvements #1423

wants to merge 5 commits into from

Conversation

unflxw
Copy link
Contributor

@unflxw unflxw commented Jun 18, 2025

Have #<< and #info use the same implementation

The #<< method is meant to use the INFO log level. Since we do
some extra transformations on add_with_attributes when the #info
method is called, we can use the same code path and make it easier
to understand that it's just an alias.

Log default attributes when #add is used

When the #add method is used instead of the level-specific helper
methods, log the default attributes as well.

Call #to_s on the message

Before refusing to log a message because it is not a string, attempt
to call #to_s on the message.

Fixes #1418.

Broadcast log messages regardless of level

When broadcasting log messages, do so regardless of the log level
of the AppSignal broadcaster. This allows loggers with less strict
levels to log messages according to their own level thresholds.

To avoid executing the block passed as a message several times, which
would run into the same issues as ActiveSupport::BroadcastLogger,
wrap the given message block with an object that can be cast into a
proc and be called more than once, but that only call the underlying
block once, with the same return value each time. This also ensures
that we don't call the underlying block if the message is not logged
by any of the broadcasted loggers.

When the logger is silenced, however, do not broadcast any logs over
the silenced log threshold. This makes sense because silencing is
about the application code that performs the logging, not about its
destination.

Move the Exception formatting to the #add method so that all
error levels, not just #error, can format exceptions.

Fixes #1422.

Improve readability of logger method tests

Name the members of the permutations.

unflxw added 5 commits June 17, 2025 15:52
The `#<<` method is meant to use the `INFO` log level. Since we do
some extra transformations on `add_with_attributes` when the `#info`
method is called, we can use the same code path and make it easier
to understand that it's just an alias.
When the `#add` method is used instead of the level-specific helper
methods, log the default attributes as well.
Before refusing to log a message because it is not a string, attempt
to call `#to_s` on the message.

Fixes #1418.
When broadcasting log messages, do so regardless of the log level
of the AppSignal broadcaster. This allows loggers with less strict
levels to log messages according to their own level thresholds.

To avoid executing the block passed as a message several times, which
would run into the same issues as `ActiveSupport::BroadcastLogger`,
wrap the given message block with an object that can be cast into a
proc and be called more than once, but that only call the underlying
block once, with the same return value each time. This also ensures
that we don't call the underlying block if the message is not logged
by any of the broadcasted loggers.

When the logger is silenced, however, do not broadcast any logs over
the silenced log threshold. This makes sense because silencing is
about the application code that performs the logging, not about its
destination.

Move the `Exception` formatting to the `#add` method so that all
error levels, not just `#error`, can format exceptions.

Fixes #1422.
Name the members of the permutations.
@unflxw unflxw requested a review from tombruijn June 18, 2025 08:08
@unflxw unflxw self-assigned this Jun 18, 2025
@backlog-helper
Copy link

Hi @unflxw,

We've found some issues with your Pull Request.

  • This Pull Request does not include a changeset. Add a changeset if the change impacts users and should be included in the changelog upon release. Read more about changesets.
    Ignore this rule by adding [skip changeset] to your Pull Request body. - (More info)

New issue guide | Backlog management | Rules | Feedback

@@ -73,6 +73,8 @@ def add(severity, message = nil, group = nil)
nil
end

message = message.to_s if message.respond_to?(:to_s)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most, if not all, objects respond to to_s, it's implemented on Object. It might cause us to log things like this:

>> Object.new.to_s
=> "#<Object:0x0000000128de9940>"

Is that what we want? How do other loggers handle this?

Copy link
Contributor Author

@unflxw unflxw Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, to_s is too blunt of a tool. It's likely we should leave it up to the formatter, as mentioned in #1418 (comment) (and in the issue itself, which I misunderstood)


return if message.nil?

message = "#{message.class}: #{message.message}" if message.is_a?(Exception)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Could be useful to include the first backtrace line if we're logging exceptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing implementation explicitly chose not to do that (like, there's a test for it and everything!) but I agree that makes sense.

@unflxw
Copy link
Contributor Author

unflxw commented Jun 18, 2025

In addition to the comments above, address #1418 (comment) before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AppSignal logger level determines which messages are broadcasted Logs passed as non-String and formatted into a String are ignored
2 participants