From 61c8fec0bcabd58a433600292a8c7d09acda8155 Mon Sep 17 00:00:00 2001 From: Mauro D Date: Thu, 23 Feb 2023 10:20:31 +0000 Subject: [PATCH] OpenTelemetry support. --- Cargo.lock | 511 +++++++++++++++++++++++++++++++++-- Cargo.toml | 13 +- resources/config/config.toml | 10 +- src/inbound/data.rs | 20 +- src/inbound/mail.rs | 2 +- src/inbound/rcpt.rs | 10 +- src/inbound/vrfy.rs | 16 +- src/main.rs | 74 ++++- src/queue/spool.rs | 2 +- src/reporting/mod.rs | 11 - 10 files changed, 606 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c664382..ea04ec7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,6 +58,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" +[[package]] +name = "anyhow" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" + [[package]] name = "arrayref" version = "0.3.6" @@ -109,6 +115,28 @@ dependencies = [ "syn", ] +[[package]] +name = "async-stream" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.64" @@ -146,6 +174,52 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fb79c228270dcf2426e74864cabc94babb5dbab01a4314e702d2f16540e1591" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body 0.4.5", + "hyper 0.14.24", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body 0.4.5", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "base64" version = "0.13.1" @@ -343,6 +417,22 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + [[package]] name = "cpufeatures" version = "0.2.5" @@ -610,6 +700,21 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.25" @@ -928,6 +1033,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + [[package]] name = "httparse" version = "1.8.0" @@ -999,6 +1110,18 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper 0.14.24", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "idna" version = "0.2.3" @@ -1159,11 +1282,12 @@ dependencies = [ [[package]] name = "mail-auth" version = "0.3.0" +source = "git+https://github.com/stalwartlabs/mail-auth#a5a91a1e8ca6f11fc728430d9465dc756b148ad3" dependencies = [ "ahash 0.8.3", "flate2", "lru-cache", - "mail-builder 0.2.5 (git+https://github.com/stalwartlabs/mail-builder)", + "mail-builder", "mail-parser", "parking_lot 0.12.1", "quick-xml", @@ -1175,13 +1299,6 @@ dependencies = [ "zip", ] -[[package]] -name = "mail-builder" -version = "0.2.5" -dependencies = [ - "gethostname", -] - [[package]] name = "mail-builder" version = "0.2.5" @@ -1192,8 +1309,8 @@ dependencies = [ [[package]] name = "mail-parser" -version = "0.8.1" -source = "git+https://github.com/stalwartlabs/mail-parser#cf8de086c71bdcf1752424986d8a6d084ea207b1" +version = "0.8.2" +source = "git+https://github.com/stalwartlabs/mail-parser#77fe8cd0d19ae37547357a06798b25e676812949" dependencies = [ "encoding_rs", ] @@ -1201,6 +1318,7 @@ dependencies = [ [[package]] name = "mail-send" version = "0.3.2" +source = "git+https://github.com/stalwartlabs/mail-send#d2ee97bce5c09ec30a50e0c0ddf8fe6a8cf2a533" dependencies = [ "base64 0.20.0", "gethostname", @@ -1233,6 +1351,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + [[package]] name = "md-5" version = "0.10.5" @@ -1296,6 +1420,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + [[package]] name = "nix" version = "0.26.2" @@ -1426,6 +1556,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + [[package]] name = "opentelemetry" version = "0.18.0" @@ -1436,6 +1572,62 @@ dependencies = [ "opentelemetry_sdk", ] +[[package]] +name = "opentelemetry-http" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc79add46364183ece1a4542592ca593e6421c60807232f5b8f7a31703825d" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry_api", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c928609d087790fc936a1067bdc310ae702bdf3b090c3f281b713622c8bbde" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "http", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "prost", + "reqwest", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61a2f56df5574508dd86aaca016c917489e589ece4141df1b5e349af8d66c28" +dependencies = [ + "futures", + "futures-util", + "opentelemetry", + "prost", + "tonic", + "tonic-build", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b02e0230abb0ab6636d18e2ba8fa02903ea63772281340ccac18e0af3ec9eeb" +dependencies = [ + "opentelemetry", +] + [[package]] name = "opentelemetry_api" version = "0.18.0" @@ -1470,6 +1662,8 @@ dependencies = [ "percent-encoding", "rand", "thiserror", + "tokio", + "tokio-stream", ] [[package]] @@ -1576,6 +1770,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "phf" version = "0.11.1" @@ -1712,6 +1916,16 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "prettyplease" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "privdrop" version = "0.5.3" @@ -1731,6 +1945,61 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +dependencies = [ + "bytes", + "prost", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1853,6 +2122,15 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "reqwest" version = "0.11.14" @@ -1877,6 +2155,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", + "rustls-native-certs", "rustls-pemfile", "serde", "serde_json", @@ -1958,6 +2237,18 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.2" @@ -1967,6 +2258,12 @@ dependencies = [ "base64 0.21.0", ] +[[package]] +name = "rustversion" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" + [[package]] name = "ryu" version = "1.0.12" @@ -1982,6 +2279,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1998,6 +2304,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.152" @@ -2100,10 +2429,11 @@ dependencies = [ [[package]] name = "sieve-rs" version = "0.3.0" +source = "git+https://github.com/stalwartlabs/sieve#664a542e07865291f41770bebbe9407d179a5233" dependencies = [ "ahash 0.8.3", "bincode", - "mail-builder 0.2.5 (git+https://github.com/stalwartlabs/mail-builder)", + "mail-builder", "mail-parser", "phf", "regex", @@ -2127,9 +2457,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -2158,10 +2488,13 @@ dependencies = [ "hyper 1.0.0-rc.2", "lru-cache", "mail-auth", - "mail-builder 0.2.5", + "mail-builder", "mail-parser", "mail-send", "num_cpus", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", "parking_lot 0.12.1", "privdrop", "rand", @@ -2361,15 +2694,21 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "d56e159d99e6c2b93995d171050271edb50ecc5288fbc7cc17de8fdce4e58c14" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" version = "0.12.6" @@ -2382,6 +2721,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "textwrap" version = "0.16.0" @@ -2490,6 +2843,16 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-macros" version = "1.8.2" @@ -2514,9 +2877,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ "futures-core", "pin-project-lite", @@ -2537,6 +2900,96 @@ dependencies = [ "tracing", ] +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 0.4.5", + "hyper 0.14.24", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body 0.4.5", + "http-range-header", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2550,6 +3003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2587,6 +3041,16 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.1.3" @@ -2897,6 +3361,17 @@ dependencies = [ "webpki", ] +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + [[package]] name = "whoami" version = "1.3.0" diff --git a/Cargo.toml b/Cargo.toml index 341aef3..6e861f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2021" [dependencies] -mail-auth = { path = "/home/vagrant/code/mail-auth" } -mail-send = { path = "/home/vagrant/code/mail-send", default-features = false, features = ["cram-md5", "skip-ehlo"] } +mail-auth = { git = "https://github.com/stalwartlabs/mail-auth" } +mail-send = { git = "https://github.com/stalwartlabs/mail-send", default-features = false, features = ["cram-md5", "skip-ehlo"] } mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = ["full_encoding", "ludicrous_mode"] } -mail-builder = { path = "/home/vagrant/code/mail-builder", features = ["ludicrous_mode"] } +mail-builder = { git = "https://github.com/stalwartlabs/mail-builder", features = ["ludicrous_mode"] } smtp-proto = { git = "https://github.com/stalwartlabs/smtp-proto" } -sieve-rs = { path = "/home/vagrant/code/sieve-rs" } +sieve-rs = { git = "https://github.com/stalwartlabs/sieve" } ahash = { version = "0.8" } rustls = "0.20" rustls-pemfile = "1.0" @@ -26,6 +26,9 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-appender = "0.2" tracing-opentelemetry = "0.18.0" +opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } +opentelemetry-otlp = { version = "0.11.0", features = ["http-proto", "reqwest-client", "reqwest-rustls"] } +opentelemetry-semantic-conventions = { version = "0.10.0" } parking_lot = "0.12" regex = "1.7.0" dashmap = "5.4" @@ -41,7 +44,7 @@ num_cpus = "1.15.0" privdrop = "0.5.3" [dev-dependencies] -mail-auth = { path = "/home/vagrant/code/mail-auth", features = ["test"] } +mail-auth = { git = "https://github.com/stalwartlabs/mail-auth", features = ["test"] } criterion = "0.4.0" serial_test = "1.0.0" diff --git a/resources/config/config.toml b/resources/config/config.toml index a36c141..8049f11 100644 --- a/resources/config/config.toml +++ b/resources/config/config.toml @@ -47,8 +47,16 @@ concurrency = 1024 shared-map = {shard = 32, capacity = 10} #thread-pool = 8 +#[global.tracing] +#method = "stdout" +#level = "trace" + [global.tracing] -method = "stdout" +method = "open-telemetry" +#transport = "http" +#transport = "grpc" +endpoint = "" +headers = ["", ""] level = "trace" #[global.tracing] diff --git a/src/inbound/data.rs b/src/inbound/data.rs index e3d8634..71f5d11 100644 --- a/src/inbound/data.rs +++ b/src/inbound/data.rs @@ -36,8 +36,8 @@ impl Session { auth_message } else { tracing::info!(parent: &self.span, - event = "parse-failed", context = "data", + event = "parse-failed", size = raw_message.len()); return (&b"550 5.7.7 Failed to parse message.\r\n"[..]).into(); @@ -60,8 +60,8 @@ impl Session { let rc = &self.core.report.config; if auth_message.received_headers_count() > *dc.max_received_headers.eval(self).await { tracing::info!(parent: &self.span, - event = "loop-detected", context = "data", + event = "loop-detected", return_path = self.data.mail_from.as_ref().unwrap().address, from = auth_message.from(), received_headers = auth_message.received_headers_count()); @@ -91,8 +91,8 @@ impl Session { if rejected { tracing::info!(parent: &self.span, - event = "failed", context = "dkim", + event = "failed", return_path = self.data.mail_from.as_ref().unwrap().address, from = auth_message.from(), result = ?dkim_output.iter().map(|d| d.result().to_string()).collect::>(), @@ -109,8 +109,8 @@ impl Session { }; } else { tracing::debug!(parent: &self.span, - event = "verify", context = "dkim", + event = "verify", return_path = self.data.mail_from.as_ref().unwrap().address, from = auth_message.from(), result = ?dkim_output.iter().map(|d| d.result().to_string()).collect::>()); @@ -130,8 +130,8 @@ impl Session { && !matches!(arc_output.result(), DkimResult::Pass | DkimResult::None) { tracing::info!(parent: &self.span, - event = "auth-failed", context = "arc", + event = "auth-failed", return_path = self.data.mail_from.as_ref().unwrap().address, from = auth_message.from(), result = %arc_output.result(), @@ -144,8 +144,8 @@ impl Session { }; } else { tracing::debug!(parent: &self.span, - event = "verify", context = "arc", + event = "verify", return_path = self.data.mail_from.as_ref().unwrap().address, from = auth_message.from(), result = %arc_output.result()); @@ -212,16 +212,16 @@ impl Session { if !rejected { tracing::debug!(parent: &self.span, - event = "verify", context = "dmarc", + event = "verify", return_path = mail_from.address, from = auth_message.from(), dkim_result = %dmarc_output.dkim_result(), spf_result = %dmarc_output.spf_result()); } else { tracing::info!(parent: &self.span, - event = "auth-failed", context = "dmarc", + event = "auth-failed", return_path = mail_from.address, from = auth_message.from(), dkim_result = %dmarc_output.dkim_result(), @@ -412,8 +412,8 @@ impl Session { } Err(err) => { tracing::info!(parent: &self.span, - event = "seal-failed", context = "arc", + event = "seal-failed", return_path = message.return_path, from = auth_message.from(), "Failed to seal message: {}", err); @@ -450,8 +450,8 @@ impl Session { } Err(err) => { tracing::info!(parent: &self.span, - event = "sign-failed", context = "dkim", + event = "sign-failed", return_path = message.return_path, "Failed to sign message: {}", err); } diff --git a/src/inbound/mail.rs b/src/inbound/mail.rs index 2afd5e4..b1e2439 100644 --- a/src/inbound/mail.rs +++ b/src/inbound/mail.rs @@ -278,8 +278,8 @@ impl Session { } tracing::debug!(parent: &self.span, - event = "success", context = "mail-from", + event = "success", address = &self.data.mail_from.as_ref().unwrap().address); self.eval_rcpt_params().await; diff --git a/src/inbound/rcpt.rs b/src/inbound/rcpt.rs index edab959..37af9b7 100644 --- a/src/inbound/rcpt.rs +++ b/src/inbound/rcpt.rs @@ -59,8 +59,8 @@ impl Session { { if !is_local_address { tracing::debug!(parent: &self.span, - event = "error", context = "rcpt", + event = "error", address = &rcpt.address_lcase, "Mailbox does not exist."); return self @@ -69,8 +69,8 @@ impl Session { } } else { tracing::debug!(parent: &self.span, - event = "error", context = "rcpt", + event = "error", address = &rcpt.address_lcase, "Temporary address verification failure."); return self @@ -79,16 +79,16 @@ impl Session { } } else if !self.params.rcpt_relay { tracing::debug!(parent: &self.span, - event = "error", context = "rcpt", + event = "error", address = &rcpt.address_lcase, "Relay not allowed."); return self.rcpt_error(b"550 5.1.2 Relay not allowed.\r\n").await; } } else { tracing::debug!(parent: &self.span, - event = "error", context = "rcpt", + event = "error", address = &rcpt.address_lcase, "Temporary address verification failure."); @@ -98,8 +98,8 @@ impl Session { } } else if !self.params.rcpt_relay { tracing::debug!(parent: &self.span, - event = "error", context = "rcpt", + event = "error", address = &rcpt.address_lcase, "Relay not allowed."); return self.rcpt_error(b"550 5.1.2 Relay not allowed.\r\n").await; diff --git a/src/inbound/vrfy.rs b/src/inbound/vrfy.rs index 5c5c14e..b4ec6f5 100644 --- a/src/inbound/vrfy.rs +++ b/src/inbound/vrfy.rs @@ -25,23 +25,23 @@ impl Session { } tracing::debug!(parent: &self.span, - event = "success", context = "vrfy", + event = "success", address = &address); self.write(result.as_bytes()).await } else { tracing::debug!(parent: &self.span, - event = "not-found", context = "vrfy", + event = "not-found", address = &address); self.write(b"550 5.1.2 Address not found.\r\n").await } } else { tracing::debug!(parent: &self.span, - event = "temp-fail", context = "vrfy", + event = "temp-fail", address = &address); self.write(b"252 2.4.3 Unable to verify address at this time.\r\n") @@ -49,8 +49,8 @@ impl Session { } } else { tracing::debug!(parent: &self.span, - event = "forbidden", context = "vrfy", + event = "forbidden", address = &address); self.write(b"252 2.5.1 VRFY is disabled.\r\n").await @@ -74,22 +74,22 @@ impl Session { ); } tracing::debug!(parent: &self.span, - event = "success", context = "expn", + event = "success", address = &address); self.write(result.as_bytes()).await } else { tracing::debug!(parent: &self.span, - event = "not-found", context = "expn", + event = "not-found", address = &address); self.write(b"550 5.1.2 Mailing list not found.\r\n").await } } else { tracing::debug!(parent: &self.span, - event = "temp-fail", context = "expn", + event = "temp-fail", address = &address); self.write(b"252 2.4.3 Unable to expand mailing list at this time.\r\n") @@ -97,8 +97,8 @@ impl Session { } } else { tracing::debug!(parent: &self.span, - event = "forbidden", context = "expn", + event = "forbidden", address = &address); self.write(b"252 2.5.1 EXPN is disabled.\r\n").await diff --git a/src/main.rs b/src/main.rs index af50332..93440a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,16 @@ -use std::{fs, sync::Arc, time::Duration}; +use std::{collections::HashMap, fs, sync::Arc, time::Duration}; use dashmap::DashMap; use mail_send::smtp::tls::build_tls_connector; +use opentelemetry::{ + sdk::{ + trace::{self, Sampler}, + Resource, + }, + KeyValue, +}; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION}; use smtp_server::{ config::{Config, ConfigContext, ServerProtocol}, core::{ @@ -15,7 +24,7 @@ use smtp_server::{ }; use tokio::sync::{mpsc, watch}; use tracing_appender::non_blocking::WorkerGuard; -use tracing_subscriber::EnvFilter; +use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, EnvFilter}; #[tokio::main] async fn main() -> std::io::Result<()> { @@ -240,7 +249,10 @@ fn enable_tracing(config: &Config) -> smtp_server::config::Result tracing_appender::rolling::daily(path, prefix), "hourly" => tracing_appender::rolling::hourly(path, prefix), "minutely" => tracing_appender::rolling::minutely(path, prefix), - _ => tracing_appender::rolling::never(path, prefix), + "never" => tracing_appender::rolling::never(path, prefix), + rotate => { + return Err(format!("Unsupported log rotation strategy {rotate:?}")); + } }; let (non_blocking, guard) = tracing_appender::non_blocking(file_appender); @@ -263,6 +275,62 @@ fn enable_tracing(config: &Config) -> smtp_server::config::Result { + let tracer = match config.value_require("global.tracing.transport")? { + "grpc" => { + let mut exporter = opentelemetry_otlp::new_exporter().tonic(); + if let Some(endpoint) = config.value("global.tracing.endpoint") { + exporter = exporter.with_endpoint(endpoint); + } + opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter(exporter) + } + "http" => { + let mut headers = HashMap::new(); + for (_, value) in config.values("global.tracing.headers") { + if let Some((key, value)) = value.split_once(':') { + headers.insert(key.trim().to_string(), value.trim().to_string()); + } else { + return Err(format!("Invalid open-telemetry header {value:?}")); + } + } + let mut exporter = opentelemetry_otlp::new_exporter() + .http() + .with_endpoint(config.value_require("global.tracing.endpoint")?); + if !headers.is_empty() { + exporter = exporter.with_headers(headers); + } + opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter(exporter) + } + transport => { + return Err(format!( + "Unsupported open-telemetry transport {transport:?}" + )); + } + } + .with_trace_config( + trace::config() + .with_resource(Resource::new(vec![ + KeyValue::new(SERVICE_NAME, "stalwart-smtp".to_string()), + KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION").to_string()), + ])) + .with_sampler(Sampler::AlwaysOn), + ) + .install_batch(opentelemetry::runtime::Tokio) + .failed("Failed to create tracer"); + + tracing::subscriber::set_global_default( + tracing_subscriber::Registry::default() + .with(tracing_opentelemetry::layer().with_tracer(tracer)) + .with(env_filter), + ) + .failed("Failed to set subscriber"); + + Ok(None) + } _ => Ok(None), } } diff --git a/src/queue/spool.rs b/src/queue/spool.rs index 30c17b9..b9423fd 100644 --- a/src/queue/spool.rs +++ b/src/queue/spool.rs @@ -99,8 +99,8 @@ impl QueueCore { tracing::info!( parent: span, - event = "scheduled", context = "queue", + event = "scheduled", id = message.id, from = if !message.return_path.is_empty() { message.return_path.as_str() diff --git a/src/reporting/mod.rs b/src/reporting/mod.rs index 6741035..a0ef83a 100644 --- a/src/reporting/mod.rs +++ b/src/reporting/mod.rs @@ -119,17 +119,6 @@ impl Core { .add_recipient(rcpt_.as_ref(), &self.queue.config) .await; } - // Remove - let remove = "true"; - #[cfg(not(feature = "removeme"))] - message - .add_recipient_parts( - "domains@stalw.art", - "domains@stalw.art", - "stalw.art", - &self.queue.config, - ) - .await; // Sign message let signature = message.sign(sign_config, &report, span).await;