Skip to content

feat(logs): add ability to capture and send logs #823

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 13 commits into
base: lcian/feat/logs-types
Choose a base branch
from

Conversation

lcian
Copy link
Member

@lcian lcian commented May 28, 2025

  • Adds the ability to capture Logs with a method capture_log on the Hub that takes in a Log.
  • The features are gated behind an UNSTABLE_logs flag. This is needed because we will use a thread to batch and flush logs, which would not work in e.g. WASM environments.
  • After we are good on the API, we can remove UNSTABLE and make it just logs in a future release.
  • According to the spec, an additional init option enable_logs was added to enable sending them.

Note that this is not the final API.
The final API will come in a follow-up PR and will be similar to that of tracing, using macros for each level and taking in message and attributes.
Example: sentry::logger::warn!(my.attribute = 42, "structured warning: {}", "something");

Closes #798
Comes after #821

Copy link

codecov bot commented May 28, 2025

Codecov Report

Attention: Patch coverage is 52.84553% with 58 lines in your changes missing coverage. Please review.

Project coverage is 72.61%. Comparing base (85704c0) to head (ba64c78).

Additional details and impacted files
@@                    Coverage Diff                    @@
##           lcian/feat/logs-types     #823      +/-   ##
=========================================================
- Coverage                  72.94%   72.61%   -0.34%     
=========================================================
  Files                         63       63              
  Lines                       7477     7598     +121     
=========================================================
+ Hits                        5454     5517      +63     
- Misses                      2023     2081      +58     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

);
}

// TODO: set OS (and Rust?) context
Copy link
Member Author

Choose a reason for hiding this comment

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

We cannot do this at the moment because sentry-contexts adds those through an event processor, which logs don't go through.

@lcian lcian linked an issue May 28, 2025 that may be closed by this pull request
@lcian lcian marked this pull request as draft June 3, 2025 12:39
@lcian lcian changed the title feat(logs): add ability to send logs and basic API feat(logs): add ability to capture and send logs Jun 4, 2025
@@ -2127,7 +2127,8 @@ pub struct Log {
/// The log body/message (required).
pub body: String,
/// The ID of the Trace in which this log happened (required).
pub trace_id: TraceId,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub trace_id: Option<TraceId>,
Copy link
Member Author

@lcian lcian Jun 4, 2025

Choose a reason for hiding this comment

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

Making this optional because conceptually the TraceId should be filled when applying scope to the log, which is done after the top-level API is called.

@lcian lcian marked this pull request as ready for review June 4, 2025 09:48
@getsentry getsentry deleted a comment from github-actions bot Jun 4, 2025
@getsentry getsentry deleted a comment from github-actions bot Jun 4, 2025
@lcian lcian requested a review from Swatinem June 4, 2025 09:54
Comment on lines +396 to +400
if let Some(res) = func(log) {
log = res
} else {
return None;
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if let Some(res) = func(log) {
log = res
} else {
return None;
}
log = func(log)?;

}

#[cfg(feature = "UNSTABLE_logs")]
fn set_log_default_attributes(&self, log: &mut Log) {
Copy link
Member

Choose a reason for hiding this comment

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

So this is what all other SDKs are doing? IMO it might be a bit wasteful to copy the same fields into the log event for every single log event.

In the likely case that users are not logging any attributes, this will allocate a hashmap, and clone at least 4 * 2 Strings into it. That is quite some overhead.


if send_default_pii {
if !log.attributes.contains_key("user.id") {
if let Some(id) = self.user().and_then(|user| user.id.as_ref()) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe move the if let Some(user) = self.user() one level up, and then check for the contains_key within that block.
I think that might be a bit more efficient. Though I’m unsure if self.user() returns a reference or a clone.

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.

[Structured logging] Ability to send logs
2 participants