diff options
Diffstat (limited to 'crates/tor-config-shared')
| -rw-r--r-- | crates/tor-config-shared/Cargo.toml | 32 | ||||
| -rw-r--r-- | crates/tor-config-shared/README.md | 12 | ||||
| -rw-r--r-- | crates/tor-config-shared/src/lib.rs | 52 | ||||
| -rw-r--r-- | crates/tor-config-shared/src/metrics.rs | 33 | ||||
| -rw-r--r-- | crates/tor-config-shared/src/opentelemetry.rs | 95 | ||||
| -rw-r--r-- | crates/tor-config-shared/src/opentelemetry_stub.rs | 15 |
6 files changed, 239 insertions, 0 deletions
diff --git a/crates/tor-config-shared/Cargo.toml b/crates/tor-config-shared/Cargo.toml new file mode 100644 index 000000000..88cff4b64 --- /dev/null +++ b/crates/tor-config-shared/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "tor-config-shared" +version = "0.45.0" +authors = ["The Tor Project, Inc.", "Wesley Aptekar-Cassels <[email protected]>"] +edition = "2024" +rust-version = "1.91" +license = "MIT OR Apache-2.0" +homepage = "https://gitlab.torproject.org/tpo/core/arti/-/wikis/home" +description = "Configuration information that is shared between arti, arti-relay, and other Arti projects." +keywords = ["tor", "arti"] +categories = ["config"] +repository = "https://gitlab.torproject.org/tpo/core/arti.git/" + +[features] +default = [] +experimental = ["opentelemetry"] +opentelemetry = ["dep:opentelemetry_sdk", "dep:opentelemetry-otlp", "__is_experimental"] + +__is_experimental = [] + +[dependencies] +amplify = { version = "4", default-features = false, features = ["derive"] } +derive-deftly = { version = "~1.11.3", features = ["full", "beta"] } +opentelemetry-otlp = { version = "0.32.0", optional = true } +# TODO: Figure out why this feature is needed, and how it interacts with non-tokio runtimes. +opentelemetry_sdk = { version = "0.32.1", features = ["rt-tokio"], optional = true } +serde = { version = "1.0.103", features = ["derive"] } +tor-config = { path = "../tor-config", version = "0.45.0" } +tor-config-path = { path = "../tor-config-path", version = "0.45.0" } + +[package.metadata.docs.rs] +all-features = true diff --git a/crates/tor-config-shared/README.md b/crates/tor-config-shared/README.md new file mode 100644 index 000000000..127c8681a --- /dev/null +++ b/crates/tor-config-shared/README.md @@ -0,0 +1,12 @@ +# tor-config-shared + +Shared configuration between `arti` client and `arti` relay. + +## Overview + +This crate is part of +[Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to +implement [Tor](https://www.torproject.org/) in Rust. + +--- +License: MIT OR Apache-2.0 diff --git a/crates/tor-config-shared/src/lib.rs b/crates/tor-config-shared/src/lib.rs new file mode 100644 index 000000000..1bdbac837 --- /dev/null +++ b/crates/tor-config-shared/src/lib.rs @@ -0,0 +1,52 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc = include_str!("../README.md")] +// @@ begin lint list maintained by maint/add_warning @@ +#![allow(renamed_and_removed_lints)] // @@REMOVE_WHEN(ci_arti_stable) +#![allow(unknown_lints)] // @@REMOVE_WHEN(ci_arti_nightly) +#![warn(missing_docs)] +#![warn(noop_method_call)] +#![warn(unreachable_pub)] +#![warn(clippy::all)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::cargo_common_metadata)] +#![deny(clippy::cast_lossless)] +#![deny(clippy::checked_conversions)] +#![allow(clippy::cognitive_complexity)] // See arti#2556 +#![deny(clippy::debug_assert_with_mut_call)] +#![deny(clippy::exhaustive_enums)] +#![deny(clippy::exhaustive_structs)] +#![deny(clippy::expl_impl_clone_on_copy)] +#![deny(clippy::fallible_impl_from)] +#![deny(clippy::implicit_clone)] +#![deny(clippy::large_stack_arrays)] +#![warn(clippy::manual_ok_or)] +#![deny(clippy::missing_docs_in_private_items)] +#![warn(clippy::needless_borrow)] +#![warn(clippy::needless_pass_by_value)] +#![warn(clippy::option_option)] +#![deny(clippy::print_stderr)] +#![deny(clippy::print_stdout)] +#![warn(clippy::rc_buffer)] +#![deny(clippy::ref_option_ref)] +#![warn(clippy::semicolon_if_nothing_returned)] +#![warn(clippy::trait_duplication_in_bounds)] +#![deny(clippy::unchecked_time_subtraction)] +#![deny(clippy::unnecessary_wraps)] +#![warn(clippy::unseparated_literal_suffix)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::mod_module_files)] +#![allow(clippy::let_unit_value)] // This can reasonably be done for explicitness +#![allow(clippy::uninlined_format_args)] +#![allow(clippy::significant_drop_in_scrutinee)] // arti/-/merge_requests/588/#note_2812945 +#![allow(clippy::result_large_err)] // temporary workaround for arti#587 +#![allow(clippy::needless_raw_string_hashes)] // complained-about code is fine, often best +#![allow(clippy::needless_lifetimes)] // See arti#1765 +#![allow(mismatched_lifetime_syntaxes)] // temporary workaround for arti#2060 +#![allow(clippy::collapsible_if)] // See arti#2342 +#![deny(clippy::unused_async)] +#![deny(clippy::string_slice)] // See arti#2571 +//! <!-- @@ end lint list maintained by maint/add_warning @@ --> + +pub mod metrics; +#[cfg_attr(not(feature = "opentelemetry"), path = "opentelemetry_stub.rs")] +pub mod opentelemetry; diff --git a/crates/tor-config-shared/src/metrics.rs b/crates/tor-config-shared/src/metrics.rs new file mode 100644 index 000000000..f8d05c7ab --- /dev/null +++ b/crates/tor-config-shared/src/metrics.rs @@ -0,0 +1,33 @@ +//! Configuration for metrics reporting via Prometheus / etc + +use derive_deftly::Deftly; + +use tor_config::Listen; +use tor_config::derive::prelude::*; + +/// Configuration for exporting metrics (eg, perf data) +#[derive(Debug, Clone, Deftly, Eq, PartialEq)] +#[derive_deftly(TorConfig)] +#[non_exhaustive] +pub struct MetricsConfig { + /// Where to listen for incoming HTTP connections. + #[deftly(tor_config(sub_builder))] + pub prometheus: PrometheusConfig, +} + +/// Configuration for one or more proxy listeners. +#[derive(Debug, Clone, Deftly, Eq, PartialEq)] +#[derive_deftly(TorConfig)] +#[non_exhaustive] +pub struct PrometheusConfig { + /// Port on which to establish a Prometheus scrape endpoint + /// + /// We listen here for incoming HTTP connections. + /// + /// If just a port is provided, we don't support IPv6. + /// Alternatively, (only) a single address and port can be specified. + /// These restrictions are due to upstream limitations: + /// <https://github.com/metrics-rs/metrics/issues/567>. + #[deftly(tor_config(default))] + pub listen: Listen, +} diff --git a/crates/tor-config-shared/src/opentelemetry.rs b/crates/tor-config-shared/src/opentelemetry.rs new file mode 100644 index 000000000..c3b2a9992 --- /dev/null +++ b/crates/tor-config-shared/src/opentelemetry.rs @@ -0,0 +1,95 @@ +//! Configuration for OpenTelemetry exporter + +use amplify::Getters; +use derive_deftly::Deftly; +use serde::{Deserialize, Serialize}; +use std::time::Duration; +use tor_config::derive::prelude::*; +use tor_config_path::CfgPath; + +/// Configuration for exporting spans with OpenTelemetry. +#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)] +#[derive_deftly(TorConfig)] +pub struct OpentelemetryConfig { + /// Write spans to a file in OTLP JSON format. + #[deftly(tor_config(default))] + file: Option<OpentelemetryFileExporterConfig>, + /// Export spans via HTTP. + #[deftly(tor_config(default))] + http: Option<OpentelemetryHttpExporterConfig>, +} + +/// Configuration for the OpenTelemetry HTTP exporter. +#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)] +#[derive_deftly(TorConfig)] +#[deftly(tor_config(no_default_trait))] +pub struct OpentelemetryHttpExporterConfig { + /// HTTP(S) endpoint to send spans to. + /// + /// For Jaeger, this should be something like: `http://localhost:4318/v1/traces` + #[deftly(tor_config(no_default))] + endpoint: String, + /// Configuration for how to batch exports. + #[deftly(tor_config(sub_builder))] + batch: OpentelemetryBatchConfig, + // TODO: A different approach to this may be better, as getting the default in this way + // prevents the use of environment variables to override this, and also is inconsistent with + // other aspects of configuration. + /// Timeout for sending data. + #[deftly(tor_config(default = "opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT"))] + timeout: Duration, + // TODO: Once opentelemetry-otlp supports more than one protocol over HTTP, add a config option + // to choose protocol here. +} + +/// Configuration for the OpenTelemetry File exporter. +#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)] +#[derive_deftly(TorConfig)] +#[deftly(tor_config(no_default_trait))] +pub struct OpentelemetryFileExporterConfig { + /// The path to write the JSON file to. + #[deftly(tor_config(no_default))] + path: CfgPath, + /// Configuration for how to batch writes. + #[deftly(tor_config(sub_builder))] + batch: OpentelemetryBatchConfig, +} + +/// Configuration for the Opentelemetry batch exporting. +/// +/// This is a copy of [`opentelemetry_sdk::trace::BatchConfig`]. +#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)] +#[derive_deftly(TorConfig)] +pub struct OpentelemetryBatchConfig { + /// Maximum queue size. See [`opentelemetry_sdk::trace::BatchConfig::max_queue_size`]. + #[deftly(tor_config(default))] + max_queue_size: Option<usize>, + /// Maximum export batch size. See [`opentelemetry_sdk::trace::BatchConfig::max_export_batch_size`]. + #[deftly(tor_config(default))] + max_export_batch_size: Option<usize>, + /// Scheduled delay. See [`opentelemetry_sdk::trace::BatchConfig::scheduled_delay`]. + #[deftly(tor_config(default = "Duration::from_secs(5)"))] + scheduled_delay: Duration, +} + +impl From<OpentelemetryBatchConfig> for opentelemetry_sdk::trace::BatchConfig { + fn from(config: OpentelemetryBatchConfig) -> opentelemetry_sdk::trace::BatchConfig { + let batch_config = opentelemetry_sdk::trace::BatchConfigBuilder::default(); + + let batch_config = if let Some(max_queue_size) = config.max_queue_size { + batch_config.with_max_queue_size(max_queue_size) + } else { + batch_config + }; + + let batch_config = if let Some(max_export_batch_size) = config.max_export_batch_size { + batch_config.with_max_export_batch_size(max_export_batch_size) + } else { + batch_config + }; + + let batch_config = batch_config.with_scheduled_delay(config.scheduled_delay); + + batch_config.build() + } +} diff --git a/crates/tor-config-shared/src/opentelemetry_stub.rs b/crates/tor-config-shared/src/opentelemetry_stub.rs new file mode 100644 index 000000000..d8e86aa4b --- /dev/null +++ b/crates/tor-config-shared/src/opentelemetry_stub.rs @@ -0,0 +1,15 @@ +//! Stub for configuration for OpenTelemetry exporter + +use derive_deftly::Deftly; +use serde::{Deserialize, Serialize}; +use tor_config::derive::prelude::*; + +#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize)] +#[derive_deftly(TorConfig)] +/// Stub configuration for exporting spans with OpenTelemetry. +pub struct OpentelemetryConfig; + +#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize)] +#[derive_deftly(TorConfig)] +/// Stub configuration for the OpenTelemetry HTTP exporter. +pub struct OpentelemetryFileExporterConfig; |
