This PR adds the ability to store metadata globally, which will then be attached to any future events. The API matches the new event metadata API added in https://github.com/bugsnag/bugsnag-ruby/pull/694, for example:
Metadata can also be added/cleared outside of a configure block with Bugsnag.add_metadata and Bugsnag.clear_metadata
Global metadata is deeply cloned when attached to an event, which means mutating the event's metadata won't affect the global metadata:
Bugsnag.add_metadata(:abc, { x: 1, y: 2, z: 3 })
Bugsnag.notify(RuntimeError.new("example")) do |event|
event.add_metadata(:abc, :x, "changed")
event.clear_metadata(:abc, :z)
# event metadata is: { x: "changed", y: 2 }
# global metadata is: { x: 1, y: 2, z: 3 }
end
Design
The deep cloning is handled by a new Bugsnag::Utility::Duplicator class. The existing Gems I found were either unmaintained, monkey patched core objects or didn't support all of our supported Ruby versions
While this should be pretty thorough, it's possible for some values not to be duplicated. I think this is unlikely to be a problem given that types of values that will realistically be used in metadata, since it has to serialise to JSON in the end
The alternative to adding this class is using the Marshal.load(Marshal.dump(object)) trick, but this has a few drawbacks:
it doesn't work for every object and will fail entirely if given an unsupported value
there's a potential security risk to loading untrusted data, e.g. if user input is provided as metadata
Goal
This PR adds the ability to store metadata globally, which will then be attached to any future events. The API matches the new event metadata API added in https://github.com/bugsnag/bugsnag-ruby/pull/694, for example:
Metadata can also be added/cleared outside of a
configure
block withBugsnag.add_metadata
andBugsnag.clear_metadata
Global metadata is deeply cloned when attached to an event, which means mutating the event's metadata won't affect the global metadata:
Design
The deep cloning is handled by a new
Bugsnag::Utility::Duplicator
class. The existing Gems I found were either unmaintained, monkey patched core objects or didn't support all of our supported Ruby versionsWhile this should be pretty thorough, it's possible for some values not to be duplicated. I think this is unlikely to be a problem given that types of values that will realistically be used in metadata, since it has to serialise to JSON in the end
The alternative to adding this class is using the
Marshal.load(Marshal.dump(object))
trick, but this has a few drawbacks: