Bump open-telemetry to 0.29, tokio to 1.45

This commit is contained in:
mdecimus
2025-05-21 15:49:26 +02:00
parent 8511de8a4d
commit 699fca25e0
26 changed files with 1488 additions and 280 deletions

1399
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ resolver = "2"
jmap-client = { version = "0.3", features = ["async"] }
mail-parser = { version = "0.11", features = ["full_encoding", "serde"] }
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-webpki-roots", "http2"]}
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
num_cpus = "1.13.1"
clap = { version = "4.1.6", features = ["derive"] }
prettytable-rs = "0.10.0"

View File

@@ -29,7 +29,7 @@ rustls = { version = "0.23.5", default-features = false, features = ["std", "rin
rustls-pemfile = "2.0"
rustls-pki-types = { version = "1" }
ring = { version = "0.17" }
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
futures = "0.3"
rcgen = "0.12"
@@ -41,11 +41,11 @@ x509-parser = "0.17.0"
pem = "3.0"
chrono = { version = "0.4", features = ["serde"] }
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }
opentelemetry = { version = "0.25" }
opentelemetry_sdk = { version = "0.25" }
opentelemetry-otlp = { version = "0.25", features = ["http-proto", "reqwest-client"] }
opentelemetry-semantic-conventions = { version = "0.25.0" }
prometheus = { version = "0.13.4", default-features = false }
opentelemetry = { version = "0.29" }
opentelemetry_sdk = { version = "0.29" }
opentelemetry-otlp = { version = "0.29", default-features = false, features = ["http-proto", "trace", "metrics", "logs", "internal-logs", "grpc-tonic", "tls-webpki-roots", "reqwest-rustls-webpki-roots"] }
opentelemetry-semantic-conventions = { version = "0.29.0" }
prometheus = { version = "0.14", default-features = false }
imagesize = "0.14"
sha1 = "0.10"
sha2 = "0.10.6"
@@ -57,7 +57,7 @@ unicode-security = "0.1.0"
infer = "0.19"
bincode = { version = "2.0", features = ["serde"] }
hostname = "0.4.0"
zip = "2.1"
zip = "3.0"
pwhash = "1.0.0"
xxhash-rust = { version = "0.8.5", features = ["xxh3"] }
psl = "2"
@@ -83,4 +83,4 @@ enterprise = []
foundation = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -4,28 +4,25 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use std::{collections::HashMap, str::FromStr, sync::Arc, time::Duration};
use super::parse_http_headers;
use ahash::{AHashMap, AHashSet};
use base64::{Engine, engine::general_purpose::STANDARD};
use hyper::{HeaderMap, header::CONTENT_TYPE};
use opentelemetry::{InstrumentationLibrary, KeyValue};
use opentelemetry_otlp::WithExportConfig;
use opentelemetry::{InstrumentationScope, KeyValue, logs::LoggerProvider};
use opentelemetry_otlp::{
LogExporter, MetricExporter, SpanExporter, WithExportConfig, WithHttpConfig,
};
use opentelemetry_sdk::{
Resource,
export::{logs::LogExporter, trace::SpanExporter},
metrics::{
exporter::PushMetricsExporter,
reader::{DefaultAggregationSelector, DefaultTemporalitySelector},
},
logs::{SdkLogger, SdkLoggerProvider},
metrics::Temporality,
};
use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION};
use opentelemetry_semantic_conventions::resource::SERVICE_VERSION;
use std::{collections::HashMap, str::FromStr, sync::Arc, time::Duration};
use store::Stores;
use trc::{EventType, Level, TelemetryEvent, ipc::subscriber::Interests};
use utils::config::{Config, utils::ParseValue};
use super::parse_http_headers;
#[derive(Debug)]
pub struct TelemetrySubscriber {
pub id: String,
@@ -34,6 +31,7 @@ pub struct TelemetrySubscriber {
pub lossy: bool,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum TelemetrySubscriberType {
ConsoleTracer(ConsoleTracer),
@@ -48,17 +46,18 @@ pub enum TelemetrySubscriberType {
#[derive(Debug)]
pub struct OtelTracer {
pub span_exporter: Box<dyn SpanExporter>,
pub span_exporter: SpanExporter,
pub span_exporter_enable: bool,
pub log_exporter: Box<dyn LogExporter>,
pub log_exporter: LogExporter,
pub log_provider: SdkLogger,
pub log_exporter_enable: bool,
pub throttle: Duration,
}
pub struct OtelMetrics {
pub resource: Resource,
pub instrumentation: InstrumentationLibrary,
pub exporter: Box<dyn PushMetricsExporter>,
pub instrumentation: InstrumentationScope,
pub exporter: MetricExporter,
pub interval: Duration,
}
@@ -259,9 +258,7 @@ impl Tracers {
"otel" | "open-telemetry" => {
let timeout = config
.property::<Duration>(("tracer", id, "timeout"))
.unwrap_or(Duration::from_secs(
opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT,
));
.unwrap_or(opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT);
let throttle = config
.property_or_default(("tracer", id, "throttle"), "1s")
.unwrap_or_else(|| Duration::from_secs(1));
@@ -277,12 +274,12 @@ impl Tracers {
.unwrap_or_default()
{
"grpc" => {
let mut span_exporter = opentelemetry_otlp::new_exporter()
.tonic()
let mut span_exporter = SpanExporter::builder()
.with_tonic()
.with_protocol(opentelemetry_otlp::Protocol::Grpc)
.with_timeout(timeout);
let mut log_exporter = opentelemetry_otlp::new_exporter()
.tonic()
let mut log_exporter = LogExporter::builder()
.with_tonic()
.with_protocol(opentelemetry_otlp::Protocol::Grpc)
.with_timeout(timeout);
if let Some(endpoint) = config.value(("tracer", id, "endpoint")) {
@@ -290,17 +287,17 @@ impl Tracers {
log_exporter = log_exporter.with_endpoint(endpoint);
}
match (
span_exporter.build_span_exporter(),
log_exporter.build_log_exporter(),
) {
match (span_exporter.build(), log_exporter.build()) {
(Ok(span_exporter), Ok(log_exporter)) => {
TelemetrySubscriberType::OtelTracer(OtelTracer {
span_exporter: Box::new(span_exporter),
log_exporter: Box::new(log_exporter),
span_exporter,
log_exporter,
throttle,
span_exporter_enable,
log_exporter_enable,
log_provider: SdkLoggerProvider::builder()
.build()
.logger("stalwart"),
})
}
(Err(err), _) => {
@@ -346,12 +343,12 @@ impl Tracers {
config.new_parse_error(("tracer", id, "headers"), err);
}
let mut span_exporter = opentelemetry_otlp::new_exporter()
.http()
let mut span_exporter = SpanExporter::builder()
.with_http()
.with_endpoint(&endpoint)
.with_timeout(timeout);
let mut log_exporter = opentelemetry_otlp::new_exporter()
.http()
let mut log_exporter = LogExporter::builder()
.with_http()
.with_endpoint(&endpoint)
.with_timeout(timeout);
if !headers.is_empty() {
@@ -359,17 +356,17 @@ impl Tracers {
log_exporter = log_exporter.with_headers(headers);
}
match (
span_exporter.build_span_exporter(),
log_exporter.build_log_exporter(),
) {
match (span_exporter.build(), log_exporter.build()) {
(Ok(span_exporter), Ok(log_exporter)) => {
TelemetrySubscriberType::OtelTracer(OtelTracer {
span_exporter: Box::new(span_exporter),
log_exporter: Box::new(log_exporter),
span_exporter,
log_exporter,
throttle,
span_exporter_enable,
log_exporter_enable,
log_provider: SdkLoggerProvider::builder()
.build()
.logger("stalwart"),
})
}
(Err(err), _) => {
@@ -653,36 +650,32 @@ impl Metrics {
if let Some(is_grpc) = otel_enabled {
let timeout = config
.property::<Duration>("metrics.open-telemetry.timeout")
.unwrap_or(Duration::from_secs(
opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT,
));
.unwrap_or(opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT);
let interval = config
.property_or_default("metrics.open-telemetry.interval", "1m")
.unwrap_or_else(|| Duration::from_secs(60));
let resource = Resource::new([
KeyValue::new(SERVICE_NAME, "stalwart"),
KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")),
]);
let instrumentation = InstrumentationLibrary::builder("stalwart")
let resource = Resource::builder()
.with_service_name("stalwart")
.with_attribute(KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")))
.build();
let instrumentation = InstrumentationScope::builder("stalwart")
.with_version(env!("CARGO_PKG_VERSION"))
.build();
if is_grpc {
let mut exporter = opentelemetry_otlp::new_exporter()
.tonic()
let mut exporter = MetricExporter::builder()
.with_temporality(Temporality::Delta)
.with_tonic()
.with_protocol(opentelemetry_otlp::Protocol::Grpc)
.with_timeout(timeout);
if let Some(endpoint) = config.value("metrics.open-telemetry.endpoint") {
exporter = exporter.with_endpoint(endpoint);
}
match exporter.build_metrics_exporter(
Box::new(DefaultAggregationSelector::new()),
Box::new(DefaultTemporalitySelector::new()),
) {
match exporter.build() {
Ok(exporter) => {
metrics.otel = Some(Arc::new(OtelMetrics {
exporter: Box::new(exporter),
exporter,
interval,
resource,
instrumentation,
@@ -713,21 +706,19 @@ impl Metrics {
config.new_parse_error("metrics.open-telemetry.headers", err);
}
let mut exporter = opentelemetry_otlp::new_exporter()
.http()
let mut exporter = MetricExporter::builder()
.with_temporality(Temporality::Delta)
.with_http()
.with_endpoint(&endpoint)
.with_timeout(timeout);
if !headers.is_empty() {
exporter = exporter.with_headers(headers);
}
match exporter.build_metrics_exporter(
Box::new(DefaultAggregationSelector::new()),
Box::new(DefaultTemporalitySelector::new()),
) {
match exporter.build() {
Ok(exporter) => {
metrics.otel = Some(Arc::new(OtelMetrics {
exporter: Box::new(exporter),
exporter,
interval,
resource,
instrumentation,

View File

@@ -4,21 +4,22 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use std::time::SystemTime;
use opentelemetry::global::set_error_handler;
use opentelemetry_sdk::metrics::data::{
DataPoint, Gauge, Histogram, HistogramDataPoint, Metric, ResourceMetrics, ScopeMetrics, Sum,
Temporality,
};
use trc::{Collector, TelemetryEvent};
use crate::config::telemetry::OtelMetrics;
use opentelemetry_sdk::metrics::{
Temporality,
data::{
Gauge, GaugeDataPoint, Histogram, HistogramDataPoint, Metric, ResourceMetrics,
ScopeMetrics, Sum, SumDataPoint,
},
exporter::PushMetricExporter,
};
use std::time::SystemTime;
use trc::{Collector, TelemetryEvent};
impl OtelMetrics {
pub async fn push_metrics(&self, is_enterprise: bool, start_time: SystemTime) {
let mut metrics = Vec::with_capacity(256);
let now = SystemTime::now();
let time = SystemTime::now();
// Add counters
for counter in Collector::collect_counters(is_enterprise) {
@@ -27,15 +28,15 @@ impl OtelMetrics {
description: counter.id().description().into(),
unit: "events".into(),
data: Box::new(Sum {
data_points: vec![DataPoint {
data_points: vec![SumDataPoint {
attributes: vec![],
start_time: start_time.into(),
time: now.into(),
value: counter.value(),
exemplars: vec![],
}],
temporality: Temporality::Cumulative,
is_monotonic: true,
start_time,
time,
}),
});
}
@@ -47,13 +48,13 @@ impl OtelMetrics {
description: gauge.id().description().into(),
unit: gauge.id().unit().into(),
data: Box::new(Gauge {
data_points: vec![DataPoint {
data_points: vec![GaugeDataPoint {
attributes: vec![],
start_time: start_time.into(),
time: now.into(),
value: gauge.get(),
exemplars: vec![],
}],
start_time: start_time.into(),
time,
}),
});
}
@@ -67,8 +68,6 @@ impl OtelMetrics {
data: Box::new(Histogram {
data_points: vec![HistogramDataPoint {
attributes: vec![],
start_time,
time: now,
count: histogram.count(),
bounds: histogram.upper_bounds_vec(),
bucket_counts: histogram.buckets_vec(),
@@ -78,6 +77,8 @@ impl OtelMetrics {
exemplars: vec![],
}],
temporality: Temporality::Cumulative,
start_time,
time,
}),
});
}
@@ -102,11 +103,12 @@ impl OtelMetrics {
}
pub fn enable_errors() {
let _ = set_error_handler(|error| {
// TODO: Remove this when the OpenTelemetry SDK supports error handling
/*let _ = set_error_handler(|error| {
trc::event!(
Telemetry(TelemetryEvent::OtelMetricsExporterError),
Reason = error.to_string(),
);
});
});*/
}
}

View File

@@ -4,38 +4,34 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use std::{
borrow::Cow,
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
};
use crate::{LONG_1Y_SLUMBER, config::telemetry::OtelTracer};
use ahash::AHashMap;
use mail_parser::DateTime;
use opentelemetry::{
InstrumentationLibrary, Key, KeyValue, Value,
InstrumentationScope, Key, KeyValue, Value,
logs::{AnyValue, Severity},
trace::{SpanContext, SpanKind, Status, TraceFlags, TraceState},
};
use opentelemetry_sdk::{
Resource,
export::{logs::LogBatch, trace::SpanData},
trace::{SpanEvents, SpanLinks},
logs::{LogBatch, LogExporter, SdkLogRecord},
trace::{SpanData, SpanEvents, SpanExporter, SpanLinks},
};
use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION};
use opentelemetry_semantic_conventions::resource::SERVICE_VERSION;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use trc::{Event, EventDetails, Level, TelemetryEvent, ipc::subscriber::SubscriberBuilder};
use crate::{LONG_1Y_SLUMBER, config::telemetry::OtelTracer};
const MAX_EVENTS: usize = 2048;
pub(crate) fn spawn_otel_tracer(builder: SubscriberBuilder, mut otel: OtelTracer) {
let (_, mut rx) = builder.register();
tokio::spawn(async move {
let resource = Cow::Owned(Resource::new([
KeyValue::new(SERVICE_NAME, "stalwart"),
KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")),
]));
let instrumentation = InstrumentationLibrary::builder("stalwart")
let resource = Resource::builder()
.with_service_name("stalwart")
.with_attribute(KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")))
.build();
let instrumentation = InstrumentationScope::builder("stalwart")
.with_version(env!("CARGO_PKG_VERSION"))
.build();
@@ -58,7 +54,7 @@ pub(crate) fn spawn_otel_tracer(builder: SubscriberBuilder, mut otel: OtelTracer
Ok(Some(events)) => {
for event in events {
if otel.log_exporter_enable {
pending_logs.push(build_log_record(&event));
pending_logs.push(otel.build_log_record(&event));
}
if otel.span_exporter_enable {
@@ -114,6 +110,7 @@ pub(crate) fn spawn_otel_tracer(builder: SubscriberBuilder, mut otel: OtelTracer
.iter()
.map(|log| (log, &instrumentation))
.collect::<Vec<_>>();
if let Err(err) = otel.log_exporter.export(LogBatch::new(&logs)).await {
trc::event!(
Telemetry(TelemetryEvent::OtelExporterError),
@@ -143,7 +140,7 @@ fn build_span_data<I, T>(
start_span: &Event<EventDetails>,
end_span: &Event<EventDetails>,
span_events: I,
instrumentation: &InstrumentationLibrary,
instrumentation: &InstrumentationScope,
) -> SpanData
where
I: IntoIterator<Item = T>,
@@ -184,53 +181,58 @@ where
links: SpanLinks::default(),
status: Status::default(),
span_kind: SpanKind::Server,
instrumentation_lib: instrumentation.clone(),
instrumentation_scope: instrumentation.clone(),
}
}
fn build_log_record(event: &Event<EventDetails>) -> opentelemetry_sdk::logs::LogRecord {
use opentelemetry::logs::LogRecord;
let mut record = opentelemetry_sdk::logs::LogRecord::default();
record.event_name = event.inner.typ.name().into();
record.severity_number = match event.inner.level {
Level::Trace => Severity::Trace,
Level::Debug => Severity::Debug,
Level::Info => Severity::Info,
Level::Warn => Severity::Warn,
Level::Error => Severity::Error,
Level::Disable => Severity::Error,
impl OtelTracer {
fn build_log_record(&self, event: &Event<EventDetails>) -> SdkLogRecord {
use opentelemetry::logs::LogRecord;
use opentelemetry::logs::Logger;
let mut record = self.log_provider.create_log_record();
record.set_event_name(event.inner.typ.name());
record.set_severity_number(match event.inner.level {
Level::Trace => Severity::Trace,
Level::Debug => Severity::Debug,
Level::Info => Severity::Info,
Level::Warn => Severity::Warn,
Level::Error => Severity::Error,
Level::Disable => Severity::Error,
});
record.set_severity_text(event.inner.level.as_str());
record.set_body(AnyValue::String(event.inner.typ.description().into()));
record.set_timestamp(UNIX_EPOCH + Duration::from_secs(event.inner.timestamp));
record.set_observed_timestamp(SystemTime::now());
for (k, v) in &event.keys {
record.add_attribute(k.name(), build_any_value(v));
}
record
}
.into();
record.severity_text = event.inner.level.as_str().into();
record.body = AnyValue::String(event.inner.typ.description().into()).into();
record.timestamp = (UNIX_EPOCH + Duration::from_secs(event.inner.timestamp)).into();
record.observed_timestamp = SystemTime::now().into();
for (k, v) in &event.keys {
record.add_attribute(k.name(), build_any_value(v));
}
record
}
fn build_key_value(key_value: &(trc::Key, trc::Value)) -> Option<KeyValue> {
(key_value.0 != trc::Key::SpanId).then(|| KeyValue {
key: build_key(&key_value.0),
value: match &key_value.1 {
trc::Value::String(v) => Value::String(v.to_string().into()),
trc::Value::UInt(v) => Value::I64(*v as i64),
trc::Value::Int(v) => Value::I64(*v),
trc::Value::Float(v) => Value::F64(*v),
trc::Value::Timestamp(v) => {
Value::String(DateTime::from_timestamp(*v as i64).to_rfc3339().into())
}
trc::Value::Duration(v) => Value::I64(*v as i64),
trc::Value::Bytes(_) => Value::String("[binary data]".into()),
trc::Value::Bool(v) => Value::Bool(*v),
trc::Value::Ipv4(v) => Value::String(v.to_string().into()),
trc::Value::Ipv6(v) => Value::String(v.to_string().into()),
trc::Value::Event(_) => Value::String("[event data]".into()),
trc::Value::Array(_) => Value::String("[array]".into()),
trc::Value::None => Value::Bool(false),
},
(key_value.0 != trc::Key::SpanId).then(|| {
KeyValue::new(
build_key(&key_value.0),
match &key_value.1 {
trc::Value::String(v) => Value::String(v.to_string().into()),
trc::Value::UInt(v) => Value::I64(*v as i64),
trc::Value::Int(v) => Value::I64(*v),
trc::Value::Float(v) => Value::F64(*v),
trc::Value::Timestamp(v) => {
Value::String(DateTime::from_timestamp(*v as i64).to_rfc3339().into())
}
trc::Value::Duration(v) => Value::I64(*v as i64),
trc::Value::Bytes(_) => Value::String("[binary data]".into()),
trc::Value::Bool(v) => Value::Bool(*v),
trc::Value::Ipv4(v) => Value::String(v.to_string().into()),
trc::Value::Ipv6(v) => Value::String(v.to_string().into()),
trc::Value::Event(_) => Value::String("[event data]".into()),
trc::Value::Array(_) => Value::String("[array]".into()),
trc::Value::None => Value::Bool(false),
},
)
})
}

View File

@@ -15,7 +15,7 @@ smtp-proto = { version = "0.1" }
mail-parser = { version = "0.11", features = ["full_encoding", "rkyv"] }
mail-send = { version = "0.5", default-features = false, features = ["cram-md5", "ring", "tls12"] }
mail-builder = { version = "0.4" }
tokio = { version = "1.23", features = ["net"] }
tokio = { version = "1.45", features = ["net"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
rustls-pki-types = { version = "1" }
@@ -42,7 +42,7 @@ rkyv = { version = "0.8.10", features = ["little_endian"] }
compact_str = { version = "0.9.0", features = ["rkyv", "serde"] }
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
[features]
test_mode = []

View File

@@ -17,7 +17,7 @@ smtp-proto = { version = "0.1", features = ["rkyv"] }
mail-parser = { version = "0.11", features = ["full_encoding"] }
mail-builder = { version = "0.4" }
sieve-rs = { version = "0.7", features = ["rkyv"] }
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros"] }
serde = { version = "1.0", features = ["derive"]}
serde_json = "1.0"
aes = "0.8.3"
@@ -39,4 +39,4 @@ test_mode = []
enterprise = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -14,7 +14,7 @@ directory = { path = "../directory" }
dav-proto = { path = "../dav-proto" }
calcard = { version = "0.1", features = ["rkyv"] }
hashify = "0.2"
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros"] }
rkyv = { version = "0.8.10", features = ["little_endian"] }
percent-encoding = "2.3.1"
compact_str = "0.9.0"
@@ -25,4 +25,4 @@ test_mode = []
enterprise = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -24,7 +24,7 @@ mail-parser = { version = "0.11", features = ["full_encoding", "rkyv"] }
mail-builder = { version = "0.4" }
mail-auth = { version = "0.7", features = ["generate"] }
mail-send = { version = "0.5", default-features = false, features = ["cram-md5", "ring", "tls12"] }
tokio = { version = "1.23", features = ["rt"] }
tokio = { version = "1.45", features = ["rt"] }
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }
hyper-util = { version = "0.1.1", features = ["tokio"] }
http-body-util = "0.1.0"

View File

@@ -15,4 +15,4 @@ hashify = { version = "0.2" }
compact_str = "0.9.0"
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -18,7 +18,7 @@ mail-parser = { version = "0.11", features = ["full_encoding"] }
mail-send = { version = "0.5", default-features = false, features = ["cram-md5", "ring", "tls12"] }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
rustls-pemfile = "2.0"
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
parking_lot = "0.12"
ahash = { version = "0.8" }

View File

@@ -18,4 +18,4 @@ rkyv = { version = "0.8.10", features = ["little_endian"] }
compact_str = { version = "0.9.0", features = ["rkyv", "serde"] }
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -28,7 +28,7 @@ serde_json = "1.0"
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }
hyper-util = { version = "0.1.1", features = ["tokio"] }
http-body-util = "0.1.0"
tokio = { version = "1.23", features = ["rt"] }
tokio = { version = "1.45", features = ["rt"] }
futures-util = "0.3.28"
async-stream = "0.3.5"
base64 = "0.22"

View File

@@ -34,7 +34,7 @@ services = { path = "../services" }
trc = { path = "../trc" }
utils = { path = "../utils" }
migration = { path = "../migration" }
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
[target.'cfg(not(target_env = "msvc"))'.dependencies]
jemallocator = "0.5.0"

View File

@@ -19,7 +19,7 @@ mail-send = { version = "0.5", default-features = false, features = ["cram-md5",
sieve-rs = { version = "0.7", features = ["rkyv"] }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
rustls-pemfile = "2.0"
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
parking_lot = "0.12"
ahash = { version = "0.8" }

View File

@@ -17,7 +17,7 @@ smtp = { path = "../smtp" }
mail-parser = { version = "0.11", features = ["full_encoding"] }
mail-auth = { version = "0.7", features = ["rkyv"] }
sieve-rs = { version = "0.7", features = ["rkyv"] }
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros"] }
serde = { version = "1.0", features = ["derive"]}
serde_json = "1.0"
rkyv = { version = "0.8.10", features = ["little_endian"] }
@@ -31,4 +31,4 @@ test_mode = []
enterprise = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -26,5 +26,5 @@ hashify = "0.2.1"
test_mode = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
bincode = "1.3.3"

View File

@@ -16,7 +16,7 @@ email = { path = "../email" }
mail-parser = { version = "0.11", features = ["full_encoding"] }
mail-send = { version = "0.5", default-features = false, features = ["cram-md5", "ring", "tls12"] }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
[features]

View File

@@ -13,7 +13,7 @@ email = { path = "../email" }
smtp = { path = "../smtp" }
jmap_proto = { path = "../jmap-proto" }
directory = { path = "../directory" }
tokio = { version = "1.23", features = ["rt"] }
tokio = { version = "1.45", features = ["rt"] }
mail-parser = { version = "0.11", features = ["full_encoding", "rkyv"] }
serde = { version = "1.0", features = ["derive"]}
serde_json = "1.0"

View File

@@ -30,7 +30,7 @@ ahash = { version = "0.8" }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
rustls-pemfile = "2.0"
rustls-pki-types = { version = "1" }
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
webpki-roots = { version = "1.0"}
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }

View File

@@ -15,7 +15,7 @@ mail-parser = { version = "0.11", features = ["full_encoding"] }
mail-builder = { version = "0.4" }
mail-auth = { version = "0.7" }
mail-send = { version = "0.5", default-features = false, features = ["cram-md5", "ring", "tls12"] }
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros"] }
psl = "2"
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }
idna = "1.0"
@@ -32,4 +32,4 @@ test_mode = []
enterprise = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -17,7 +17,7 @@ azure_core = { version = "0.21.0", optional = true }
azure_storage = { version = "0.21.0", default-features = false, features = ["enable_reqwest_rustls", "hmac_rust"], optional = true }
azure_storage_blobs = { version = "0.21.0", default-features = false, features = ["enable_reqwest_rustls", "hmac_rust"], optional = true }
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-webpki-roots", "http2", "stream"]}
tokio = { version = "1.23", features = ["sync", "fs", "io-util"] }
tokio = { version = "1.45", features = ["sync", "fs", "io-util"] }
r2d2 = { version = "0.8.10", optional = true }
futures = { version = "0.3", optional = true }
rand = "0.9.0"
@@ -52,24 +52,36 @@ bitpacking = "0.9.2"
memchr = { version = "2" }
rkyv = { version = "0.8.10", features = ["little_endian"] }
compact_str = "0.9.0"
zenoh = { version = "1.3.4", default-features = false, features = ["auth_pubkey", "transport_multilink", "transport_compression", "transport_quic", "transport_tcp", "transport_tls", "transport_udp"], optional = true }
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
[features]
# Data Stores
rocks = ["rocksdb", "rayon", "num_cpus"]
sqlite = ["rusqlite", "rayon", "r2d2", "num_cpus", "lru-cache"]
postgres = ["tokio-postgres", "deadpool-postgres", "tokio-rustls", "rustls", "ring", "rustls-pki-types", "futures", "bytes"]
elastic = ["elasticsearch", "serde_json"]
mysql = ["mysql_async", "futures"]
nats = ["async-nats"]
s3 = ["rust-s3"]
azure = ["azure_core", "azure_storage", "azure_storage_blobs"]
foundation = ["foundationdb", "futures"]
fdb-chunked-bm = []
redis = ["dep:redis", "deadpool"]
enterprise = []
# Blob stores
s3 = ["rust-s3"]
azure = ["azure_core", "azure_storage", "azure_storage_blobs"]
# Full-text stores
elastic = ["elasticsearch", "serde_json"]
# In-memory stores
redis = ["dep:redis", "deadpool"]
# Pubsub
nats = ["async-nats"]
peer-to-peer = ["zenoh"]
enterprise = []
test_mode = []

View File

@@ -14,7 +14,7 @@ serde_json = "1.0.120"
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-webpki-roots", "http2"]}
rtrb = "0.3.1"
parking_lot = "0.12.3"
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros"] }
ahash = "0.8.11"
rkyv = { version = "0.8.10", features = ["little_endian"] }
compact_str = "0.9.0"

View File

@@ -9,7 +9,7 @@ trc = { path = "../trc" }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
rustls-pemfile = "2.0"
rustls-pki-types = { version = "1" }
tokio = { version = "1.23", features = ["net", "macros"] }
tokio = { version = "1.45", features = ["net", "macros", "signal"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
serde = { version = "1.0", features = ["derive"]}
mail-auth = { version = "0.7" }
@@ -47,4 +47,4 @@ privdrop = "0.5.3"
test_mode = []
[dev-dependencies]
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }

View File

@@ -49,7 +49,7 @@ sieve-rs = { version = "0.7", features = ["rkyv"] }
utils = { path = "../crates/utils", features = ["test_mode"] }
jmap-client = { version = "0.3", features = ["websockets", "debug", "async"] }
mail-parser = { version = "0.11", features = ["full_encoding", "rkyv"] }
tokio = { version = "1.23", features = ["full"] }
tokio = { version = "1.45", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
rustls = { version = "0.23.5", default-features = false, features = ["std", "ring", "tls12"] }
rustls-pemfile = "2.0"