sentry_slog/
lib.rs

1//! Sentry `slog` Integration.
2//!
3//! This mainly provides the [`SentryDrain`], which wraps another [`slog::Drain`]
4//! and can be configured to forward [`slog::Record`]s to Sentry.
5//! The [`SentryDrain`] can be used to create a `slog::Logger`.
6//!
7//! The integration also supports [`slog::KV`] pairs. They will be added to the
8//! breadcrumb `data` or the event `extra` properties respectively.
9//!
10//! # Examples
11//!
12//! ```
13//! use sentry_slog::SentryDrain;
14//!
15//! let _sentry = sentry::init(());
16//!
17//! let drain = SentryDrain::new(slog::Discard);
18//! let root = slog::Logger::root(drain, slog::o!("global_kv" => 1234));
19//!
20//! # let events = sentry::test::with_captured_events(|| {
21//! slog::info!(root, "recorded as breadcrumb"; "breadcrumb_kv" => Some("breadcrumb"));
22//! slog::warn!(root, "recorded as regular event"; "event_kv" => "event");
23//! # });
24//! # let captured_event = events.into_iter().next().unwrap();
25//!
26//! let breadcrumb = &captured_event.breadcrumbs.as_ref()[0];
27//! assert_eq!(
28//!     breadcrumb.message.as_deref(),
29//!     Some("recorded as breadcrumb")
30//! );
31//! assert_eq!(breadcrumb.data["breadcrumb_kv"], "breadcrumb");
32//! assert_eq!(breadcrumb.data["global_kv"], 1234);
33//!
34//! assert_eq!(
35//!     captured_event.message.as_deref(),
36//!     Some("recorded as regular event")
37//! );
38//! assert_eq!(captured_event.extra["event_kv"], "event");
39//! assert_eq!(captured_event.extra["global_kv"], 1234);
40//!
41//! # let events = sentry::test::with_captured_events(|| {
42//! slog::crit!(root, "recorded as exception event");
43//! # });
44//! # let captured_event = events.into_iter().next().unwrap();
45//!
46//! assert_eq!(
47//!     captured_event.message.as_deref(),
48//!     Some("recorded as exception event")
49//! );
50//! ```
51//!
52//! The Drain can also be customized with a `filter`, and a `mapper`:
53//!
54//! ```
55//! use sentry_slog::{exception_from_record, LevelFilter, RecordMapping, SentryDrain};
56//!
57//! let drain = SentryDrain::new(slog::Discard)
58//!     .filter(|level| match level {
59//!         slog::Level::Critical | slog::Level::Error => LevelFilter::Event,
60//!         _ => LevelFilter::Ignore,
61//!     })
62//!     .mapper(|record, kv| match record.level() {
63//!         slog::Level::Critical | slog::Level::Error => {
64//!             RecordMapping::Event(exception_from_record(record, kv))
65//!         }
66//!         _ => RecordMapping::Ignore,
67//!     });
68//! ```
69//!
70//! When a `mapper` is specified, a corresponding `filter` should also be
71//! provided.
72
73#![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")]
74#![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")]
75#![warn(missing_docs)]
76#![deny(unsafe_code)]
77
78mod converters;
79mod drain;
80
81pub use converters::*;
82pub use drain::{default_filter, LevelFilter, RecordMapping, SentryDrain};