all good
This commit is contained in:
parent
47d89f6fad
commit
017902b8e6
82 changed files with 331466 additions and 54841 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
mod aggregation;
|
||||
mod auth;
|
||||
mod bugsink;
|
||||
mod checkout_sessions;
|
||||
mod consts;
|
||||
mod data;
|
||||
|
|
@ -29,6 +30,7 @@ use axum::Router;
|
|||
use clap::Parser;
|
||||
use consts::SERVICE_CALL_TIMEOUT;
|
||||
use tower::limit::ConcurrencyLimitLayer;
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::compression::CompressionLayer;
|
||||
|
||||
use tower_http::cors::{AllowHeaders, AllowMethods, CorsLayer};
|
||||
|
|
@ -223,10 +225,87 @@ struct Cli {
|
|||
/// Google OAuth client secret for PocketBase SSO
|
||||
#[arg(long, env = "GOOGLE_OAUTH_CLIENT_SECRET")]
|
||||
google_oauth_client_secret: String,
|
||||
|
||||
/// Bugsink DSN for backend error reporting
|
||||
#[arg(long, env = "BUGSINK_DSN", hide_env_values = true)]
|
||||
bugsink_dsn: Option<String>,
|
||||
|
||||
/// Bugsink DSN injected into the browser app; falls back to BUGSINK_DSN when omitted
|
||||
#[arg(long, env = "FRONTEND_BUGSINK_DSN", hide_env_values = true)]
|
||||
frontend_bugsink_dsn: Option<String>,
|
||||
|
||||
/// Bugsink/Sentry environment name
|
||||
#[arg(long, env = "BUGSINK_ENVIRONMENT")]
|
||||
bugsink_environment: Option<String>,
|
||||
|
||||
/// Bugsink/Sentry release name
|
||||
#[arg(long, env = "BUGSINK_RELEASE")]
|
||||
bugsink_release: Option<String>,
|
||||
|
||||
/// Include default PII in Bugsink events
|
||||
#[arg(long, env = "BUGSINK_SEND_DEFAULT_PII", default_value_t = false)]
|
||||
bugsink_send_default_pii: bool,
|
||||
}
|
||||
|
||||
async fn capture_server_error_responses(
|
||||
request: axum::extract::Request,
|
||||
next: middleware::Next,
|
||||
) -> axum::response::Response {
|
||||
let method = request.method().clone();
|
||||
let path = request.uri().path().to_owned();
|
||||
let response = next.run(request).await;
|
||||
let status = response.status();
|
||||
|
||||
if status.is_server_error() {
|
||||
sentry::with_scope(
|
||||
|scope| {
|
||||
scope.set_tag("http.status_code", status.as_u16().to_string());
|
||||
scope.set_tag("http.method", method.to_string());
|
||||
scope.set_tag("http.route", path.clone());
|
||||
},
|
||||
|| {
|
||||
sentry::capture_message(
|
||||
&format!("HTTP {status} response from {method} {path}"),
|
||||
sentry::Level::Error,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let cli = Cli::parse();
|
||||
let bugsink_environment = cli
|
||||
.bugsink_environment
|
||||
.clone()
|
||||
.or_else(|| bugsink::env_nonempty("SENTRY_ENVIRONMENT"));
|
||||
let bugsink_release = cli
|
||||
.bugsink_release
|
||||
.clone()
|
||||
.or_else(|| bugsink::env_nonempty("SENTRY_RELEASE"));
|
||||
let backend_bugsink_dsn = cli
|
||||
.bugsink_dsn
|
||||
.clone()
|
||||
.or_else(|| bugsink::env_nonempty("SENTRY_DSN"));
|
||||
let _bugsink_guard = bugsink::init_backend(&bugsink::BackendConfig {
|
||||
dsn: backend_bugsink_dsn.clone(),
|
||||
environment: bugsink_environment.clone(),
|
||||
release: bugsink_release.clone(),
|
||||
send_default_pii: cli.bugsink_send_default_pii,
|
||||
});
|
||||
let bugsink_frontend_config = bugsink::frontend_config(
|
||||
cli.frontend_bugsink_dsn
|
||||
.clone()
|
||||
.or_else(|| bugsink::env_nonempty("PUBLIC_BUGSINK_DSN"))
|
||||
.or(backend_bugsink_dsn),
|
||||
bugsink_environment.clone(),
|
||||
bugsink_release.clone(),
|
||||
cli.bugsink_send_default_pii,
|
||||
);
|
||||
|
||||
let file_appender = tracing_appender::rolling::daily("logs", "server.log");
|
||||
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
|
||||
|
||||
|
|
@ -234,6 +313,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
tracing_subscriber::registry()
|
||||
.with(env_filter)
|
||||
.with(sentry::integrations::tracing::layer())
|
||||
.with(tracing_subscriber::fmt::layer().with_ansi(true))
|
||||
.with(
|
||||
tracing_subscriber::fmt::layer()
|
||||
|
|
@ -245,8 +325,9 @@ async fn main() -> anyhow::Result<()> {
|
|||
// Initialize Prometheus metrics
|
||||
let metrics_handle = metrics::init_metrics();
|
||||
info!("Prometheus metrics initialized");
|
||||
|
||||
let cli = Cli::parse();
|
||||
if bugsink_frontend_config.is_some() || _bugsink_guard.is_some() {
|
||||
info!("Bugsink error reporting configured");
|
||||
}
|
||||
|
||||
for (label, path) in [
|
||||
("Properties", &cli.properties),
|
||||
|
|
@ -483,6 +564,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
stripe_secret_key: cli.stripe_secret_key,
|
||||
stripe_webhook_secret: cli.stripe_webhook_secret,
|
||||
stripe_referral_coupon_id: cli.stripe_referral_coupon_id,
|
||||
bugsink_frontend_config,
|
||||
};
|
||||
|
||||
let shared = Arc::new(SharedState::new(app_state));
|
||||
|
|
@ -670,9 +752,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
.route("/health", get(|| async { "ok" }))
|
||||
.route(
|
||||
"/metrics",
|
||||
get(move |connect_info| {
|
||||
metrics::metrics_handler(metrics_handle.clone(), connect_info)
|
||||
}),
|
||||
get(move |connect_info| metrics::metrics_handler(metrics_handle.clone(), connect_info)),
|
||||
)
|
||||
.with_state(shared.clone());
|
||||
|
||||
|
|
@ -696,9 +776,17 @@ async fn main() -> anyhow::Result<()> {
|
|||
},
|
||||
))
|
||||
.layer(middleware::from_fn(static_cache_headers))
|
||||
.layer(middleware::from_fn(capture_server_error_responses))
|
||||
.layer(cors)
|
||||
.layer(CompressionLayer::new().zstd(true).gzip(true))
|
||||
.layer(TraceLayer::new_for_http());
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(sentry::integrations::tower::NewSentryLayer::<
|
||||
axum::extract::Request,
|
||||
>::new_from_top())
|
||||
.layer(sentry::integrations::tower::SentryHttpLayer::new()),
|
||||
);
|
||||
|
||||
// Lock all current and future memory pages to prevent swapping
|
||||
unsafe {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue