diff --git a/Cargo.lock b/Cargo.lock index 87c7f8b84f..08dc3b8c18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2159,9 +2159,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.29.3" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f8ce69326daef9d845c3fd17149bd3dbd7caf5dc65dbbad9f5441a40ee407f" +checksum = "6c3d7f8bf7373e75222452fcdd9347d857452a92d0eec738f941bc4656c5b5df" dependencies = [ "curl", "httpdate", @@ -2172,9 +2172,9 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.29.3" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80510663e6b711de2eed521a95dc38435a0e5858397d1acec79185e4a44215b" +checksum = "9ef7f47c57a1146d553b4976f20e8bba370195a88858bdf6945a63c529549236" dependencies = [ "anyhow", "sentry-backtrace", @@ -2183,9 +2183,9 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.29.3" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed6c0254d4cce319800609aa0d41b486ee57326494802045ff27434fc9a2030" +checksum = "03b7cdefbdca51f1146f0f24a3cb4ecb6428951f030ff5c720cfb5c60bd174c0" dependencies = [ "backtrace", "once_cell", @@ -2265,9 +2265,9 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.29.3" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3277dc5d2812562026f2095c7841f3d61bbe6789159b7da54f41d540787f818" +checksum = "6af4cb29066e0e8df0cc3111211eb93543ccb09e1ccbe71de6d88b4bb459a2b1" dependencies = [ "hostname", "libc", @@ -2279,9 +2279,9 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.29.3" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5acbd3da4255938cf0384b6b140e6c07ff65919c26e4d7a989d8d90ee88fa91" +checksum = "5e781b55761e47a60d1ff326ae8059de22b0e6b0cee68eab1c5912e4fb199a76" dependencies = [ "once_cell", "rand", @@ -2292,9 +2292,9 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.29.3" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d8587b12c0b8211bb3066979ee57af6e8657e23cf439dc6c8581fd86de24e8" +checksum = "d642a04657cc77d8de52ae7c6d93a15cb02284eb219344a89c1e2b26bbaf578c" dependencies = [ "debugid", "getrandom", diff --git a/Cargo.toml b/Cargo.toml index 3db4572d5e..b903e1648d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ regex = "1.7.1" runas = "1.0.0" rust-ini = "0.18.0" semver = "1.0.16" -sentry = { version = "0.29.3", default-features = false, features = [ +sentry = { version = "0.31.0", default-features = false, features = [ "anyhow", "curl", "contexts", diff --git a/src/commands/send_envelope.rs b/src/commands/send_envelope.rs index 6ff1556a28..c42b3015a1 100644 --- a/src/commands/send_envelope.rs +++ b/src/commands/send_envelope.rs @@ -34,7 +34,7 @@ pub fn make_command(command: Command) -> Command { ) } -fn send_raw_envelope(envelope: Envelope, dsn: Dsn) { +pub fn send_raw_envelope(envelope: Envelope, dsn: Dsn) { debug!("{:?}", envelope); with_sentry_client(dsn, |c| c.send_envelope(envelope)); } diff --git a/src/commands/send_event.rs b/src/commands/send_event.rs index 4921b933c7..9883296285 100644 --- a/src/commands/send_event.rs +++ b/src/commands/send_event.rs @@ -1,7 +1,5 @@ use std::borrow::Cow; use std::env; -use std::fs::File; -use std::io::BufReader; use std::path::PathBuf; use std::time::SystemTime; @@ -13,9 +11,11 @@ use itertools::Itertools; use log::{debug, warn}; use sentry::protocol::{Event, Level, LogEntry, User}; use sentry::types::{Dsn, Uuid}; +use sentry::Envelope; use serde_json::Value; use username::get_user_name; +use crate::commands::send_envelope::send_raw_envelope; use crate::config::Config; use crate::utils::args::{get_timestamp, validate_distribution}; use crate::utils::event::{attach_logfile, get_sdk_info, with_sentry_client}; @@ -36,6 +36,12 @@ pub fn make_command(command: Command) -> Command { .required(false) .help("The path or glob to the file(s) in JSON format to send as event(s). When provided, all other arguments are ignored."), ) + .arg( + Arg::new("raw") + .long("raw") + .action(ArgAction::SetTrue) + .help("Send events using an envelope without attempting to parse their contents."), + ) .arg( Arg::new("level") .value_name("LEVEL") @@ -161,6 +167,7 @@ fn send_raw_event(event: Event<'static>, dsn: Dsn) -> Uuid { pub fn execute(matches: &ArgMatches) -> Result<()> { let config = Config::current(); let dsn = config.get_dsn()?; + let raw = matches.get_flag("raw"); if let Some(path) = matches.get_one::("path") { let collected_paths: Vec = glob_with(path, MatchOptions::new()) @@ -174,12 +181,33 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { } for path in collected_paths { - let p = path.as_path(); - let file = File::open(p)?; - let reader = BufReader::new(file); - let event: Event = serde_json::from_reader(reader)?; - let id = send_raw_event(event, dsn.clone()); - println!("Event from file {} dispatched: {}", p.display(), id); + let raw_event = std::fs::read(&path)?; + + let id = if raw { + use std::io::Write; + + // Its a bit unfortunate that we still need to parse the whole JSON, + // but envelopes need an `event_id`, which we also want to report. + let json: Value = serde_json::from_slice(&raw_event)?; + let id = json + .as_object() + .and_then(|event| event.get("event_id")) + .and_then(|val| val.as_str()) + .and_then(|id| Uuid::parse_str(id).ok()) + .unwrap_or_default(); + let mut buf = Vec::new(); + writeln!(buf, r#"{{"event_id":"{id}"}}"#)?; + writeln!(buf, r#"{{"type":"event","length":{}}}"#, raw_event.len())?; + buf.extend(raw_event); + let envelope = Envelope::from_bytes_raw(buf)?; + send_raw_envelope(envelope, dsn.clone()); + id + } else { + let event: Event = serde_json::from_slice(&raw_event)?; + send_raw_event(event, dsn.clone()) + }; + + println!("Event from file {} dispatched: {}", path.display(), id); } return Ok(()); diff --git a/tests/integration/_cases/send_event/send_event-help.trycmd b/tests/integration/_cases/send_event/send_event-help.trycmd index d2ce9f4ac3..a08576e7f8 100644 --- a/tests/integration/_cases/send_event/send_event-help.trycmd +++ b/tests/integration/_cases/send_event/send_event-help.trycmd @@ -15,35 +15,35 @@ Arguments: other arguments are ignored. Options: - -l, --level - Optional event severity/log level. (debug|info|warning|error|fatal) [defaults to 'error'] + --raw + Send events using an envelope without attempting to parse their contents. --header Custom headers that should be attached to all requests in key:value format. - --timestamp - Optional event timestamp in one of supported formats: unix timestamp, RFC2822 or RFC3339. + -l, --level + Optional event severity/log level. (debug|info|warning|error|fatal) [defaults to 'error'] --auth-token Use the given Sentry auth token. + --timestamp + Optional event timestamp in one of supported formats: unix timestamp, RFC2822 or RFC3339. + -r, --release Optional identifier of the release. -d, --dist Set the distribution. - -E, --env - Send with a specific environment. - --log-level Set the log output verbosity. [possible values: trace, debug, info, warn, error] - --no-environ - Do not send environment variables along + -E, --env + Send with a specific environment. --quiet Do not print any output while preserving correct exit code. This flag is currently @@ -51,6 +51,9 @@ Options: [aliases: silent] + --no-environ + Do not send environment variables along + -m, --message The event message.