feat(gateway): add error reporting via Sentry (#7103)

Similar to the GUI and headless clients, adding error reporting via
Sentry should give us much better insight into how well gateways are
performing.

Resolves: #7099.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
This commit is contained in:
Thomas Eizinger
2024-10-23 07:40:28 +11:00
committed by GitHub
parent 2e51274ab0
commit b7b7626cfa
6 changed files with 38 additions and 3 deletions

1
rust/Cargo.lock generated
View File

@@ -1865,6 +1865,7 @@ dependencies = [
"either",
"firezone-bin-shared",
"firezone-logging",
"firezone-telemetry",
"firezone-tunnel",
"futures",
"futures-bounded",

View File

@@ -18,6 +18,7 @@ domain = { workspace = true }
either = "1"
firezone-bin-shared = { workspace = true }
firezone-logging = { workspace = true }
firezone-telemetry = { workspace = true }
firezone-tunnel = { workspace = true }
futures = "0.3.29"
futures-bounded = { workspace = true }

View File

@@ -8,6 +8,7 @@ use firezone_bin_shared::{
TunDeviceManager,
};
use firezone_logging::anyhow_dyn_err;
use firezone_telemetry::Telemetry;
use firezone_tunnel::messages::Interface;
use firezone_tunnel::{GatewayTunnel, IPV4_PEERS, IPV6_PEERS};
use phoenix_channel::get_user_agent;
@@ -37,19 +38,29 @@ async fn main() {
.install_default()
.expect("Calling `install_default` only once per process should always succeed");
let cli = Cli::parse();
let telemetry = Telemetry::default();
if cli.is_telemetry_allowed() {
telemetry.start(
cli.api_url.as_str(),
firezone_bin_shared::git_version!("gateway-*"),
firezone_telemetry::GATEWAY_DSN,
);
}
// Enforce errors only being printed on a single line using the technique recommended in the anyhow docs:
// https://docs.rs/anyhow/latest/anyhow/struct.Error.html#display-representations
//
// By default, `anyhow` prints a stacktrace when it exits.
// That looks like a "crash" but we "just" exit with a fatal error.
if let Err(e) = try_main().await {
if let Err(e) = try_main(cli).await {
tracing::error!(error = anyhow_dyn_err(&e));
firezone_telemetry::capture_anyhow(&e);
std::process::exit(1);
}
}
async fn try_main() -> Result<()> {
let cli = Cli::parse();
async fn try_main(cli: Cli) -> Result<()> {
firezone_logging::setup_global_subscriber(layer::Identity::new());
let firezone_id = get_firezone_id(cli.firezone_id).await
@@ -174,6 +185,10 @@ struct Cli {
#[arg(short = 'n', long, env = "FIREZONE_NAME")]
firezone_name: Option<String>,
/// Friendly name to display in the UI
#[arg(long, env = "FIREZONE_NO_TELEMETRY", default_value_t = false)]
no_telemetry: bool,
#[command(flatten)]
health_check: http_health_check::HealthCheckArgs,
@@ -181,3 +196,9 @@ struct Cli {
#[arg(short = 'i', long, env = "FIREZONE_ID")]
pub firezone_id: Option<String>,
}
impl Cli {
fn is_telemetry_allowed(&self) -> bool {
!self.no_telemetry
}
}

View File

@@ -15,6 +15,7 @@ pub struct Dsn(&'static str);
// > DSNs are safe to keep public because they only allow submission of new events and related event data; they do not allow read access to any information.
// <https://docs.sentry.io/concepts/key-terms/dsn-explainer/#dsn-utilization>
pub const GATEWAY_DSN: Dsn = Dsn("https://f763102cc3937199ec483fbdae63dfdc@o4507971108339712.ingest.us.sentry.io/4508162914451456");
pub const GUI_DSN: Dsn = Dsn("https://2e17bf5ed24a78c0ac9e84a5de2bd6fc@o4507971108339712.ingest.us.sentry.io/4508008945549312");
pub const HEADLESS_DSN: Dsn = Dsn("https://bc27dca8bb37be0142c48c4f89647c13@o4507971108339712.ingest.us.sentry.io/4508010028728320");
pub const IPC_SERVICE_DSN: Dsn = Dsn("https://0590b89fd4479494a1e7ffa4dc705001@o4507971108339712.ingest.us.sentry.io/4508008896069632");

View File

@@ -61,6 +61,7 @@ you'll need to make sure the following outbound traffic is allowed:
| N/A | See [relay-ips.json](/relay-ips.json) | `3478` | STUN | STUN protocol signaling |
| N/A | See [relay-ips.json](/relay-ips.json) | `49152-65535` | TURN | TURN protocol channel data |
| github.com, www.firezone.dev | Varies | `443` | HTTPS | Only required for [Gateway upgrades](/kb/administer/upgrading). |
| sentry.io | Varies | `443` | HTTPS | Crash-reporting, see [Telemetry](#telemetry) |
## Where to deploy Gateways
@@ -156,6 +157,12 @@ It's a good idea to keep your Gateways up to date with the latest version
available. See [upgrading Gateways](/kb/administer/upgrading) for ways to
automate this.
## Telemetry
By default, Gateways will run a https://sentry.io crash-reporting agent. If
you'd like to opt-out of this, set the environment variable
`FIREZONE_NO_TELEMETRY=1`.
<NextStep href="/kb/deploy/resources">Next: Create Resources</NextStep>
<SupportOptions />

View File

@@ -19,6 +19,10 @@ export default function Gateway() {
Implements support for the new control protocol; delivering faster
and more robust connection establishment.
</ChangeItem>
<ChangeItem pull="7103">
Adds on-by-default error reporting using sentry.io.
Disable by setting `FIREZONE_NO_TELEMETRY=1`.
</ChangeItem>
</Unreleased>
<Entry version="1.3.2" date={new Date("2024-10-02")}>
<ChangeItem pull="6733">