aboutsummaryrefslogtreecommitdiff
path: root/crates/tor-config-shared
diff options
context:
space:
mode:
Diffstat (limited to 'crates/tor-config-shared')
-rw-r--r--crates/tor-config-shared/Cargo.toml32
-rw-r--r--crates/tor-config-shared/README.md12
-rw-r--r--crates/tor-config-shared/src/lib.rs52
-rw-r--r--crates/tor-config-shared/src/metrics.rs33
-rw-r--r--crates/tor-config-shared/src/opentelemetry.rs95
-rw-r--r--crates/tor-config-shared/src/opentelemetry_stub.rs15
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;