Skip to content

Commit

Permalink
feat(commands): add send-metric command
Browse files Browse the repository at this point in the history
Add CLI command that can emit metrics.

Fixes GH-2001
  • Loading branch information
Elias Ram committed May 16, 2024
1 parent 554f4fc commit d205688
Show file tree
Hide file tree
Showing 68 changed files with 1,608 additions and 30 deletions.
114 changes: 90 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ bytecount = "0.6.3"
chardet = "0.2.4"
chrono = { version = "0.4.31", features = ["serde"] }
clap = { version = "4.1.6", default-features = false, features = [
"derive",
"std",
"suggestions",
"wrap_help",
Expand All @@ -26,6 +27,7 @@ clap = { version = "4.1.6", default-features = false, features = [
] }
clap_complete = "4.4.3"
console = "0.15.5"
crc32fast = "1.4.0"
curl = { version = "0.4.44", features = ["static-curl", "static-ssl"] }
dirs = "4.0.0"
dotenv = "0.15.0"
Expand Down Expand Up @@ -58,17 +60,19 @@ regex = "1.7.3"
runas = "1.0.0"
rust-ini = "0.18.0"
semver = "1.0.16"
sentry = { version = "0.32.2", default-features = false, features = [
sentry = { version = "0.32.3", default-features = false, features = [
"anyhow",
"curl",
"contexts",
"UNSTABLE_metrics",
] }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
sha1_smol = { version = "1.0.0", features = ["serde"] }
sourcemap = { version = "7.0.1", features = ["ram_bundle"] }
symbolic = { version = "12.4.1", features = ["debuginfo-serde", "il2cpp"] }
thiserror = "1.0.38"
unicode-segmentation = "1.11.0"
url = "2.3.1"
username = "0.2.0"
uuid = { version = "1.3.0", features = ["v4", "serde"] }
Expand Down
45 changes: 45 additions & 0 deletions src/api/envelopes_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use super::{
errors::{ApiErrorKind, ApiResult},
Api, ApiResponse, Method,
};
use crate::constants::USER_AGENT;
use log::debug;
use sentry::{protocol::EnvelopeItem, types::Dsn, Envelope};
use std::sync::Arc;

pub struct EnvelopesApi {
api: Arc<Api>,
dsn: Dsn,
}

impl EnvelopesApi {
pub fn try_new() -> ApiResult<EnvelopesApi> {
let api = Api::current();
api.config
.get_dsn()
.map(|dsn| EnvelopesApi { api, dsn })
.map_err(|_| ApiErrorKind::DsnMissing.into())
}

pub fn send_item(&self, item: EnvelopeItem) -> ApiResult<ApiResponse> {
let mut envelope = Envelope::new();
envelope.add_item(item);
self.send_envelope(envelope)
}

pub fn send_envelope(&self, envelope: Envelope) -> ApiResult<ApiResponse> {
let mut body = vec![];
envelope
.to_writer(&mut body)
.map_err(|_| ApiErrorKind::CannotSerializeEnvelope)?;
debug!("Sending envelope:\n{}", String::from_utf8_lossy(&body));
let url = self.dsn.envelope_api_url();
let auth = self.dsn.to_auth(Some(USER_AGENT));
self.api
.request(Method::Post, url.as_str(), None)?
.with_header("X-Sentry-Auth", &auth.to_string())?
.with_body(body)?
.send()?
.into_result()
}
}
6 changes: 6 additions & 0 deletions src/api/errors/api_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub struct ApiError {
pub(in crate::api) enum ApiErrorKind {
#[error("could not serialize value as JSON")]
CannotSerializeAsJson,
#[error("could not serialize envelope")]
CannotSerializeEnvelope,
#[error("could not parse JSON response")]
BadJson,
#[error("not a JSON response")]
Expand All @@ -38,6 +40,10 @@ pub(in crate::api) enum ApiErrorKind {
"Auth token is required for this request. Please run `sentry-cli login` and try again!"
)]
AuthMissing,
#[error(
"DSN missing. Please set the environment variable `SENTRY_DSN` to your project's DSN."
)]
DsnMissing,
}

impl fmt::Display for ApiError {
Expand Down
7 changes: 7 additions & 0 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
//! to the GitHub API to figure out if there are new releases of the
//! sentry-cli tool.
pub mod envelopes_api;

mod connection_manager;
mod encoding;
mod errors;
Expand Down Expand Up @@ -1746,6 +1748,11 @@ impl ApiRequest {
Ok(self)
}

pub fn with_body(mut self, body: Vec<u8>) -> ApiResult<Self> {
self.body = Some(body);
Ok(self)
}

/// attaches some form data to the request.
pub fn with_form_data(mut self, form: curl::easy::Form) -> ApiResult<Self> {
debug!("sending form data");
Expand Down
Loading

0 comments on commit d205688

Please sign in to comment.