Skip to content
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

Add the ability to store metadata globally #699

Merged
merged 4 commits into from Sep 28, 2021
Merged

Conversation

imjoehaines
Copy link
Member

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 #694, for example:

Bugsnag.configure do |config|
  config.add_metadata(:abc, { x: 1, y: 2, z: 3 })
  config.add_metadata(:abc, :a, 9)

  config.clear_metadata(:abc, :x)

  # metadata is: { abc: { y: 2, z: 3, a: 9 } }
end

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

This performs a deep clone of the given object. This will allow
global metadata to be copied into an Event and remain unchanged
even if the Event's metadata is mutated
This can be added by calling 'Bugsnag.add_metadata' and removed with
'Bugsnag.clear_metadata' (or in a configure block). The global
metadata will then be added as the initial metadata for all future
events

Global metadata is deeply cloned per-event, so mutating an event's
metadata won't mutate the global metadata
@imjoehaines imjoehaines merged commit d52a274 into next Sep 28, 2021
@imjoehaines imjoehaines deleted the add-global-metadata branch September 28, 2021 16:57
@imjoehaines imjoehaines mentioned this pull request Oct 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants