sentry_core/integration.rs
1use std::any::{type_name, Any};
2
3use crate::protocol::Event;
4use crate::ClientOptions;
5
6/// Integration abstraction.
7///
8/// An Integration in sentry has two primary purposes.
9/// It can act as an *Event Source*, which will capture new events;
10/// or as an *Event Processor*, which can modify every `Event` flowing through
11/// the pipeline.
12///
13/// # Examples
14///
15/// ```
16/// use sentry::protocol::{Event, Level};
17/// use sentry::ClientOptions;
18///
19/// struct MyProcessorIntegration {
20/// override_environment: &'static str,
21/// override_level: Level,
22/// }
23///
24/// impl sentry::Integration for MyProcessorIntegration {
25/// fn setup(&self, options: &mut ClientOptions) {
26/// options.environment = Some(self.override_environment.into());
27/// }
28/// fn process_event(
29/// &self,
30/// mut event: Event<'static>,
31/// _options: &ClientOptions,
32/// ) -> Option<Event<'static>> {
33/// event.level = self.override_level;
34/// Some(event)
35/// }
36/// }
37///
38/// let options = ClientOptions::new().add_integration(MyProcessorIntegration {
39/// override_environment: "my_env",
40/// override_level: Level::Error,
41/// });
42///
43/// let events = sentry::test::with_captured_events_options(
44/// || {
45/// sentry::capture_message("some message", Level::Info);
46/// },
47/// options,
48/// );
49/// let captured_event = events.into_iter().next().unwrap();
50///
51/// assert_eq!(captured_event.level, Level::Error);
52/// assert_eq!(captured_event.environment, Some("my_env".into()));
53/// ```
54// NOTE: we need `Any` here so that the `TypeId` machinery works correctly.
55pub trait Integration: Sync + Send + Any + AsAny {
56 /// Name of this integration.
57 ///
58 /// This will be added to the SDK information sent to sentry.
59 fn name(&self) -> &'static str {
60 type_name::<Self>()
61 }
62
63 /// Called whenever the integration is attached to a Client.
64 fn setup(&self, options: &mut ClientOptions) {
65 let _ = options;
66 }
67
68 /// The Integrations Event Processor Hook.
69 ///
70 /// An integration can process, or even completely drop an `Event`.
71 /// Examples include adding or processing a backtrace, obfuscate some
72 /// personal information, or add additional information.
73 fn process_event(
74 &self,
75 event: Event<'static>,
76 options: &ClientOptions,
77 ) -> Option<Event<'static>> {
78 let _ = options;
79 Some(event)
80 }
81}
82
83// This is needed as a workaround to be able to safely downcast integrations
84#[doc(hidden)]
85pub trait AsAny {
86 fn as_any(&self) -> &dyn Any;
87}
88
89impl<T: Any> AsAny for T {
90 fn as_any(&self) -> &dyn Any {
91 self
92 }
93}