optional tracing-sentry

This commit is contained in:
Bryan Stitt 2022-10-24 21:07:29 +00:00
parent 89ecf4fe1d
commit a0056ca881
6 changed files with 266 additions and 50 deletions

233
Cargo.lock generated

@ -167,9 +167,9 @@ dependencies = [
[[package]]
name = "async-channel"
version = "1.6.1"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319"
checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
dependencies = [
"concurrent-queue",
"event-listener",
@ -192,9 +192,9 @@ dependencies = [
[[package]]
name = "async-global-executor"
version = "2.2.0"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940"
checksum = "0da5b41ee986eed3f524c380e6d64965aea573882a8907682ad100f7859305ca"
dependencies = [
"async-channel",
"async-executor",
@ -202,7 +202,6 @@ dependencies = [
"async-lock",
"blocking",
"futures-lite",
"num_cpus",
"once_cell",
"tokio",
]
@ -1215,6 +1214,16 @@ dependencies = [
"tokio",
]
[[package]]
name = "debugid"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
dependencies = [
"serde",
"uuid 1.2.1",
]
[[package]]
name = "deferred-rate-limiter"
version = "0.2.0"
@ -1352,6 +1361,12 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dotenvy"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0"
[[package]]
name = "dtoa"
version = "0.4.8"
@ -2296,6 +2311,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "hostname"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
dependencies = [
"libc",
"match_cfg",
"winapi",
]
[[package]]
name = "http"
version = "0.2.8"
@ -2671,6 +2697,12 @@ dependencies = [
"value-bag",
]
[[package]]
name = "match_cfg"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
[[package]]
name = "matchers"
version = "0.1.0"
@ -3419,9 +3451,9 @@ dependencies = [
[[package]]
name = "postgres-types"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd6e8b7189a73169290e89bd24c771071f1012d8fe6f738f5226531f0b03d89"
checksum = "73d946ec7d256b04dfadc4e6a3292324e6f417124750fc5c0950f981b703a0f1"
dependencies = [
"bytes",
"chrono",
@ -3429,7 +3461,7 @@ dependencies = [
"postgres-protocol",
"serde",
"serde_json",
"time 0.3.15",
"time 0.3.16",
"uuid 1.2.1",
]
@ -4073,7 +4105,7 @@ dependencies = [
"serde",
"serde_json",
"sqlx",
"time 0.3.15",
"time 0.3.16",
"tracing",
"url",
"uuid 1.2.1",
@ -4127,9 +4159,9 @@ dependencies = [
[[package]]
name = "sea-query"
version = "0.26.3"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a1de9d0334895f7eb51bd1603c3c9f6737413f905a134001f1e198f43bfd70"
checksum = "15e36a9680854b4e5d2ea5230f94e7ef81562260905b770fe20c3df9b3e7a536"
dependencies = [
"chrono",
"postgres-types",
@ -4137,7 +4169,7 @@ dependencies = [
"sea-query-derive",
"sea-query-driver",
"serde_json",
"time 0.3.15",
"time 0.3.16",
"uuid 1.2.1",
]
@ -4156,9 +4188,9 @@ dependencies = [
[[package]]
name = "sea-query-driver"
version = "0.2.0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbda46eb3484cae1efb7bc68bca50f553a5b42c076cf4cbfae05b27f707549d4"
checksum = "7d7f0cae2e7ebb2affc378c40bc343c8197181d601d6755c3e66f1bd18cac253"
dependencies = [
"proc-macro2",
"quote",
@ -4167,9 +4199,9 @@ dependencies = [
[[package]]
name = "sea-schema"
version = "0.9.3"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94d070aba647637b533bd669a8e430bdc8f7d5249c9b53402da34347563bbfca"
checksum = "f737a6819fcad9727207d7090ccd6a33c0b384f3794e8838f952b52d599e3a17"
dependencies = [
"futures",
"sea-query",
@ -4239,6 +4271,109 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7"
[[package]]
name = "sentry"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73642819e7fa63eb264abc818a2f65ac8764afbe4870b5ee25bcecc491be0d4c"
dependencies = [
"httpdate",
"reqwest",
"sentry-anyhow",
"sentry-backtrace",
"sentry-contexts",
"sentry-core",
"sentry-panic",
"tokio",
]
[[package]]
name = "sentry-anyhow"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d3479158a7396b4dfd346a1944d523427a225ff3c39102e8e985bc21cdfea8"
dependencies = [
"anyhow",
"sentry-backtrace",
"sentry-core",
]
[[package]]
name = "sentry-backtrace"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49bafa55eefc6dbc04c7dac91e8c8ab9e89e9414f3193c105cabd991bbc75134"
dependencies = [
"backtrace",
"once_cell",
"regex",
"sentry-core",
]
[[package]]
name = "sentry-contexts"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c63317c4051889e73f0b00ce4024cae3e6a225f2e18a27d2c1522eb9ce2743da"
dependencies = [
"hostname",
"libc",
"rustc_version",
"sentry-core",
"uname",
]
[[package]]
name = "sentry-core"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a4591a2d128af73b1b819ab95f143bc6a2fbe48cd23a4c45e1ee32177e66ae6"
dependencies = [
"once_cell",
"rand 0.8.5",
"sentry-types",
"serde",
"serde_json",
]
[[package]]
name = "sentry-panic"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "696c74c5882d5a0d5b4a31d0ff3989b04da49be7983b7f52a52c667da5b480bf"
dependencies = [
"sentry-backtrace",
"sentry-core",
]
[[package]]
name = "sentry-tracing"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea50bcf843510179a7ba41c9fe4d83a8958e9f8adf707ec731ff999297536344"
dependencies = [
"sentry-core",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "sentry-types"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "823923ae5f54a729159d720aa12181673044ee5c79cbda3be09e56f885e5468f"
dependencies = [
"debugid",
"getrandom",
"hex",
"serde",
"serde_json",
"thiserror",
"time 0.3.16",
"url",
"uuid 1.2.1",
]
[[package]]
name = "serde"
version = "1.0.147"
@ -4422,7 +4557,7 @@ dependencies = [
"rand 0.8.5",
"sha3",
"thiserror",
"time 0.3.15",
"time 0.3.16",
]
[[package]]
@ -4536,9 +4671,9 @@ dependencies = [
[[package]]
name = "sqlformat"
version = "0.1.8"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4"
checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a"
dependencies = [
"itertools",
"nom",
@ -4547,9 +4682,9 @@ dependencies = [
[[package]]
name = "sqlx"
version = "0.6.0"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f82cbe94f41641d6c410ded25bbf5097c240cefdf8e3b06d04198d0a96af6a4"
checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428"
dependencies = [
"sqlx-core",
"sqlx-macros",
@ -4557,9 +4692,9 @@ dependencies = [
[[package]]
name = "sqlx-core"
version = "0.6.0"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b69bf218860335ddda60d6ce85ee39f6cf6e5630e300e19757d1de15886a093"
checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105"
dependencies = [
"ahash",
"atoi",
@ -4570,6 +4705,7 @@ dependencies = [
"crc",
"crossbeam-queue",
"digest 0.10.3",
"dotenvy",
"either",
"event-listener",
"futures-channel",
@ -4595,14 +4731,14 @@ dependencies = [
"rustls-pemfile",
"serde",
"serde_json",
"sha-1",
"sha1",
"sha2 0.10.2",
"smallvec",
"sqlformat",
"sqlx-rt",
"stringprep",
"thiserror",
"time 0.3.15",
"time 0.3.16",
"tokio-stream",
"url",
"uuid 1.2.1",
@ -4611,11 +4747,11 @@ dependencies = [
[[package]]
name = "sqlx-macros"
version = "0.6.0"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40c63177cf23d356b159b60acd27c54af7423f1736988502e36bae9a712118f"
checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9"
dependencies = [
"dotenv",
"dotenvy",
"either",
"heck 0.4.0",
"once_cell",
@ -4631,9 +4767,9 @@ dependencies = [
[[package]]
name = "sqlx-rt"
version = "0.6.0"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "874e93a365a598dc3dadb197565952cb143ae4aa716f7bcc933a8d836f6bf89f"
checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396"
dependencies = [
"once_cell",
"tokio",
@ -4882,21 +5018,32 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.15"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c"
checksum = "0fab5c8b9980850e06d92ddbe3ab839c062c801f3927c0fb8abd6fc8e918fbca"
dependencies = [
"itoa 1.0.2",
"libc",
"num_threads",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-macros"
version = "0.2.4"
name = "time-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
[[package]]
name = "time-macros"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bb801831d812c562ae7d2bfb531f26e66e4e1f6b17307ba4149c5064710e5b"
dependencies = [
"time-core",
]
[[package]]
name = "tiny-keccak"
@ -5242,6 +5389,15 @@ dependencies = [
"serde",
]
[[package]]
name = "uname"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
dependencies = [
"libc",
]
[[package]]
name = "unicase"
version = "2.6.0"
@ -5311,6 +5467,7 @@ dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
]
[[package]]
@ -5531,11 +5688,13 @@ dependencies = [
"reqwest",
"rustc-hash",
"sea-orm",
"sentry",
"sentry-tracing",
"serde",
"serde_json",
"serde_prometheus",
"siwe",
"time 0.3.15",
"time 0.3.16",
"tokio",
"tokio-stream",
"toml",
@ -5709,7 +5868,7 @@ dependencies = [
"hmac",
"pbkdf2 0.10.1",
"sha1",
"time 0.3.15",
"time 0.3.16",
"zstd",
]

@ -7,8 +7,10 @@ members = [
"web3_proxy",
]
[profile.release]
# we leave debug = true on so that sentry can give us line numbers
debug = true
# TODO: enable lto (and maybe other things proven with benchmarks) once rapid development is done
# TODO: we can't do panic = abort because the websockets disconnect by panicking sometimes
#[profile.release]
#debug = true
#lto = true
# TODO: we can't do panic = abort because the websockets disconnect by panicking sometimes

@ -192,6 +192,7 @@ These are roughly in order of completition
- need an flume::watch on unflushed stats that we can subscribe to. wait for it to flip to true
- [x] don't use unix timestamps for response_millis since leap seconds will confuse it
- [x] config to allow origins even on the anonymous endpoints
- [ ] log errors to sentry
- [-] ability to domain lock or ip lock said key
- the code to check the database and use these entries already exists, but users don't have a way to set them
- [-] new endpoints for users (not totally sure about the exact paths, but these features are all needed):

@ -55,11 +55,13 @@ handlebars = "4.3.5"
rustc-hash = "1.1.0"
siwe = "0.5.0"
sea-orm = { version = "0.9.3", features = ["macros"] }
sentry = { version = "0.27.0", default-features = false, features = ["backtrace", "contexts", "panic", "anyhow", "reqwest", "rustls"] }
sentry-tracing = "0.27.0"
serde = { version = "1.0.147", features = [] }
serde_json = { version = "1.0.87", default-features = false, features = ["alloc", "raw_value"] }
serde_prometheus = "0.1.6"
# TODO: make sure this time version matches siwe. PR to put this in their prelude
time = "0.3.15"
time = "0.3.16"
tokio = { version = "1.21.2", features = ["full", "tracing"] }
# TODO: make sure this uuid version matches sea-orm. PR to put this in their prelude
tokio-stream = { version = "0.1.11", features = ["sync"] }
@ -74,3 +76,4 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter", "parking_lo
ulid = { version = "1.0.0", features = ["serde"] }
url = "2.3.1"
uuid = "1.2.1"

@ -17,6 +17,7 @@ use tokio::runtime;
use tokio::sync::broadcast;
use tokio::time::Duration;
use tracing::{debug, info, warn};
use tracing_subscriber::prelude::*;
use tracing_subscriber::EnvFilter;
use web3_proxy::app::{flatten_handle, flatten_handles, Web3ProxyApp};
use web3_proxy::config::{CliConfig, TopConfig};
@ -147,12 +148,6 @@ fn main() -> anyhow::Result<()> {
);
}
// install global collector configured based on RUST_LOG env var.
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.compact()
.init();
// this probably won't matter for us in docker, but better safe than sorry
fdlimit::raise_fd_limit();
@ -160,13 +155,50 @@ fn main() -> anyhow::Result<()> {
let cli_config: CliConfig = argh::from_env();
// advanced configuration is on disk
info!("Loading config @ {}", cli_config.config);
let top_config: String = fs::read_to_string(cli_config.config.clone())?;
let top_config: TopConfig = toml::from_str(&top_config)?;
// TODO: this doesn't seem to do anything
proctitle::set_title(format!("web3_proxy-{}", top_config.app.chain_id));
// connect to sentry for error reporting
// if no sentry, only log to stdout
let _sentry_guard = if let Some(sentry_url) = top_config.app.sentry_url.clone() {
let guard = sentry::init((
sentry_url,
sentry::ClientOptions {
release: sentry::release_name!(),
// TODO: Set this a to lower value (from config) in production
traces_sample_rate: 1.0,
..Default::default()
},
));
// TODO: how do we put the EnvFilter on this?
tracing_subscriber::registry()
.with(
tracing_subscriber::fmt::layer()
.compact()
.with_filter(EnvFilter::from_default_env()),
)
.with(sentry_tracing::layer())
.init();
Some(guard)
} else {
// install global collector configured based on RUST_LOG env var.
// TODO: attach sentry here
tracing_subscriber::fmt()
.compact()
.with_env_filter(EnvFilter::from_default_env())
.init();
None
};
// we used to do this earlier, but now we attach sentry
debug!("CLI config @ {:#?}", cli_config.config);
// tokio has code for catching ctrl+c so we use that
// this shutdown sender is currently only used in tests, but we might make a /shutdown endpoint or something
let (shutdown_sender, _shutdown_receiver) = broadcast::channel(1);
@ -198,6 +230,7 @@ mod tests {
// TODO: option for super verbose logs
std::env::set_var("RUST_LOG", "info,web3_proxy=debug");
// install global collector configured based on RUST_LOG env var.
// TODO: sentry is needed here!
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.compact()

@ -50,55 +50,73 @@ pub struct TopConfig {
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AppConfig {
/// Request limit for allowed origins for anonymous users.
pub allowed_origin_requests_per_minute: HashMap<String, u64>,
/// EVM chain id. 1 for ETH
/// TODO: better type for chain_id? max of `u64::MAX / 2 - 36` https://github.com/ethereum/EIPs/issues/2294
pub chain_id: u64,
/// Database is used for user data.
/// Currently supports mysql or compatible backend.
pub db_url: Option<String>,
/// minimum size of the connection pool for the database.
/// If none, the number of workers are used.
pub db_min_connections: Option<u32>,
/// maximum size of the connection pool for the database.
/// If none, the minimum * 2 is used.
pub db_max_connections: Option<u32>,
/// Default request limit for registered users.
/// 0 = block all requests
/// None = allow all requests
pub default_user_requests_per_minute: Option<u64>,
/// Restrict user registration.
/// None = no code needed
pub invite_code: Option<String>,
/// The soft limit prevents thundering herds as new blocks are seen.
#[serde(default = "default_min_sum_soft_limit")]
pub min_sum_soft_limit: u32,
/// Another knob for preventing thundering herds as new blocks are seen.
#[serde(default = "default_min_synced_rpcs")]
pub min_synced_rpcs: usize,
/// Request limit for anonymous users.
/// Some(0) = block all requests
/// None = allow all requests
#[serde(default = "default_public_requests_per_minute")]
pub public_requests_per_minute: Option<u64>,
/// Request limit for allowed origins for anonymous users.
pub allowed_origin_requests_per_minute: HashMap<String, u64>,
/// Rate limit for the login entrypoint.
/// This is separate from the rpc limits.
#[serde(default = "default_login_rate_limit_per_minute")]
pub login_rate_limit_per_minute: u64,
/// Track rate limits in a redis (or compatible backend)
/// It is okay if this data is lost.
pub volatile_redis_url: Option<String>,
/// maximum size of the connection pool for the cache
/// If none, the minimum * 2 is used
pub volatile_redis_max_connections: Option<usize>,
/// RPC responses are cached locally
#[serde(default = "default_response_cache_max_bytes")]
pub response_cache_max_bytes: usize,
/// the stats page url for an anonymous user.
pub redirect_public_url: Option<String>,
/// the stats page url for a logged in user. if set, must contain "{user_id}"
pub redirect_user_url: Option<String>,
/// https://sentry.io
pub sentry_url: Option<String>,
}
/// This might cause a thundering herd!