diff --git a/Cargo.lock b/Cargo.lock index 5610ef0..0ccb7f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,8 +39,8 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2", - "http", + "h2 0.3.26", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -76,7 +76,7 @@ checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", "cfg-if", - "http", + "http 0.2.12", "regex", "regex-lite", "serde", @@ -104,7 +104,7 @@ dependencies = [ "actix-utils", "futures-core", "futures-util", - "mio", + "mio 1.0.2", "socket2", "tokio", "tracing", @@ -450,6 +450,28 @@ dependencies = [ "nom", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -470,12 +492,65 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "axum" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http 1.1.0", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 1.0.1", + "tower 0.5.1", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.1.0", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -1149,14 +1224,39 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", - "indexmap", + "http 0.2.12", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.5.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.5" @@ -1173,7 +1273,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -1232,6 +1332,40 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.9.4" @@ -1259,6 +1393,59 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.61" @@ -1308,6 +1495,16 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.5.0" @@ -1315,7 +1512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -1443,6 +1640,21 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "md-5" version = "0.10.6" @@ -1490,6 +1702,17 @@ dependencies = [ "adler2", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "mio" version = "1.0.2" @@ -1503,6 +1726,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mutually_exclusive_features" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94e1e6445d314f972ff7395df2de295fe51b71821694f0b0e1e79c4f12c8577" + [[package]] name = "nom" version = "7.1.3" @@ -1513,6 +1742,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -1566,6 +1805,16 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "object" version = "0.36.4" @@ -1587,6 +1836,83 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "opentelemetry" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "803801d3d3b71cd026851a53f974ea03df3d179cb758b260136a6c9e22e196af" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "596b1719b3cab83addb20bcbffdf21575279d9436d9ccccfe651a3bf0ab5ab06" +dependencies = [ + "async-trait", + "futures-core", + "http 1.1.0", + "opentelemetry", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c43620e8f93359eb7e627a3b16ee92d8585774986f24f2ab010817426c5ce61" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db945c1eaea8ac6a9677185357480d215bb6999faa9f691d0c4d4d641eab7a09" + +[[package]] +name = "opentelemetry_sdk" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0da0d6b47a3dbc6e9c9e36a0520e25cf943e046843818faaa3f87365a548c82" +dependencies = [ + "async-trait", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "once_cell", + "opentelemetry", + "percent-encoding", + "rand", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.1" @@ -1660,6 +1986,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1744,6 +2090,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "quick-xml" version = "0.36.2" @@ -1810,8 +2179,17 @@ checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1822,7 +2200,7 @@ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.4", ] [[package]] @@ -1831,6 +2209,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.4" @@ -1934,6 +2318,10 @@ dependencies = [ "async-trait", "clap", "env_logger", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", "rustical_caldav", "rustical_carddav", "rustical_frontend", @@ -1943,6 +2331,9 @@ dependencies = [ "tokio", "toml", "tracing", + "tracing-actix-web", + "tracing-opentelemetry", + "tracing-subscriber", ] [[package]] @@ -1961,10 +2352,11 @@ dependencies = [ "rustical_dav", "rustical_store", "serde", - "serde_json", "strum", "thiserror", "tokio", + "tracing", + "tracing-actix-web", "url", ] @@ -2006,6 +2398,8 @@ dependencies = [ "serde", "strum", "thiserror", + "tracing", + "tracing-actix-web", ] [[package]] @@ -2044,6 +2438,7 @@ dependencies = [ "thiserror", "tokio", "toml", + "tracing", ] [[package]] @@ -2158,6 +2553,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2272,10 +2676,10 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", - "hashbrown", + "hashbrown 0.14.5", "hashlink", "hex", - "indexmap", + "indexmap 2.5.0", "log", "memchr", "once_cell", @@ -2498,6 +2902,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "tempfile" version = "3.13.0" @@ -2531,6 +2947,16 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.3.36" @@ -2579,28 +3005,29 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", "libc", - "mio", + "mio 0.8.11", + "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", @@ -2658,13 +3085,89 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", "winnow", ] +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2 0.4.6", + "http 1.1.0", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "socket2", + "tokio", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[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 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.40" @@ -2677,6 +3180,19 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-actix-web" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bc0cd5f72e837e310f4d978a90abf202a7f7d8ef3272246bae381d0086d3bf" +dependencies = [ + "actix-web", + "mutually_exclusive_features", + "pin-project", + "tracing", + "uuid", +] + [[package]] name = "tracing-attributes" version = "0.1.27" @@ -2695,8 +3211,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", ] +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eabc56d23707ad55ba2a0750fc24767125d5a0f51993ba41ad2c441cc7b8dea" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.17.0" @@ -2783,6 +3353,15 @@ name = "uuid" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vcpkg" @@ -2796,6 +3375,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2863,6 +3451,16 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "whoami" version = "1.5.2" @@ -2873,6 +3471,28 @@ dependencies = [ "wasite", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 4ade2a4..d76d30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,39 +1,97 @@ -[package] -name = "rustical" -version = "0.1.0" -edition = "2021" -resolver = "2" - [workspace] members = ["crates/*"] -[dependencies] -rustical_store = { path = "./crates/store/" } -rustical_caldav = { path = "./crates/caldav/" } -rustical_carddav = { path = "./crates/carddav/" } -rustical_frontend = { path = "./crates/frontend/" } -serde = { version = "1.0", features = ["derive"] } -tokio = { version = "1.40", features = [ +[workspace.package] +version = "0.1.0" +edition = "2021" + +[package] +name = "rustical" +version.workspace = true +edition.workspace = true +resolver = "2" + +[workspace.dependencies] +async-trait = "0.1" +actix-web = "4.9" +tracing = { version = "0.1", features = ["async-await"] } +tracing-actix-web = "0.7" +actix-session = { version = "0.10", features = ["cookie-session"] } +actix-web-httpauth = "0.8" +anyhow = { version = "1.0", features = ["backtrace"] } +serde = { version = "1.0", features = ["serde_derive", "derive", "rc"] } +futures-util = "0.3" +password-auth = "1.0" +chrono = { version = "0.4", features = ["serde"] } +regex = "1.10" +lazy_static = "1.5" +rstest = "0.23" +rstest_reuse = "0.7" +sha2 = "0.10" +tokio = { version = "1", features = [ "net", "tracing", "macros", "rt-multi-thread", "full", ] } -tracing = "0.1" -env_logger = "0.11" -actix-web = "4.9" -anyhow = { version = "1.0", features = ["backtrace"] } -toml = "0.8" -clap = { version = "4.5", features = ["derive", "env"] } +url = "2.5" +roxmltree = "0.20" +base64 = "0.22" +thiserror = "1.0" +quick-xml = { version = "0.36", features = [ + "serde", + "serde-types", + "serialize", +] } +itertools = "0.13" +log = "0.4" +strum = { version = "0.26", features = ["strum_macros", "derive"] } +derive_more = { version = "1.0", features = ["from", "into", "deref"] } +askama = { version = "0.12", features = ["serde", "with-actix-web"] } +askama_actix = "0.14" sqlx = { version = "0.8", features = [ "sqlx-sqlite", - "sqlx-postgres", "uuid", "chrono", - "postgres", "sqlite", "runtime-tokio", "migrate", ] } -async-trait = "0.1" +ical = { version = "0.11", features = ["generator", "serde"] } +toml = "0.8" +rustical_dav = { path = "./crates/dav/" } +rustical_store = { path = "./crates/store/" } +rustical_caldav = { path = "./crates/caldav/" } +rustical_carddav = { path = "./crates/carddav/" } +rustical_frontend = { path = "./crates/frontend/" } + +[dependencies] +rustical_store = { workspace = true } +rustical_caldav = { workspace = true } +rustical_carddav = { workspace = true } +rustical_frontend = { workspace = true } +actix-web = { workspace = true } +toml = { workspace = true } +serde = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +env_logger = "0.11" +anyhow = { workspace = true } +clap = { version = "4.5", features = ["derive", "env"] } +sqlx = { workspace = true } +async-trait = { workspace = true } +tracing-actix-web = { workspace = true } + +# 0.25 is the latest version supported by tracing-opentelemetry +opentelemetry = "0.25.0" +opentelemetry-otlp = "0.25.0" +opentelemetry_sdk = { version = "0.25.0", features = ["rt-tokio"] } + +opentelemetry-semantic-conventions = "0.26" +tracing-opentelemetry = "0.26.0" +tracing-subscriber = { version = "0.3.18", features = [ + "env-filter", + "fmt", + "registry", +] } diff --git a/crates/caldav/Cargo.toml b/crates/caldav/Cargo.toml index a03b29d..2888cc4 100644 --- a/crates/caldav/Cargo.toml +++ b/crates/caldav/Cargo.toml @@ -1,27 +1,24 @@ [package] name = "rustical_caldav" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true [dependencies] -actix-web = "4.9" -actix-web-httpauth = "0.8" -anyhow = { version = "1.0", features = ["backtrace"] } -base64 = "0.22" -futures-util = "0.3" -quick-xml = { version = "0.36", features = [ - "serde", - "serde-types", - "serialize", -] } -roxmltree = "0.20" -rustical_store = { path = "../store/" } -rustical_dav = { path = "../dav/" } -serde = { version = "1.0", features = ["serde_derive", "derive"] } -serde_json = "1.0" -tokio = { version = "1.40", features = ["sync", "full"] } -async-trait = "0.1" -thiserror = "1.0" -strum = { version = "0.26", features = ["strum_macros", "derive"] } -derive_more = { version = "1.0", features = ["from", "into"] } -url = "2.5.2" +anyhow = { workspace = true } +actix-web = { workspace = true } +async-trait = { workspace = true } +thiserror = { workspace = true } +quick-xml = { workspace = true } +strum = { workspace = true } +tracing = { workspace = true } +tracing-actix-web = { workspace = true } +futures-util = { workspace = true } +derive_more = { workspace = true } +actix-web-httpauth = { workspace = true } +base64 = { workspace = true } +serde = { workspace = true } +tokio = { workspace = true } +roxmltree = { workspace = true } +url = { workspace = true } +rustical_dav = { workspace = true } +rustical_store = { workspace = true } diff --git a/crates/carddav/Cargo.toml b/crates/carddav/Cargo.toml index 24e55e7..5f1e1c7 100644 --- a/crates/carddav/Cargo.toml +++ b/crates/carddav/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustical_carddav" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true [dependencies] actix-web = "4.9" @@ -19,7 +19,7 @@ rustical_store = { path = "../store/" } rustical_dav = { path = "../dav/" } serde = { version = "1.0", features = ["serde_derive", "derive"] } serde_json = "1.0" -tokio = { version = "1.40", features = ["sync", "full"] } +tokio = { version = "1", features = ["sync", "full"] } async-trait = "0.1" thiserror = "1.0" strum = { version = "0.26", features = ["strum_macros", "derive"] } diff --git a/crates/dav/Cargo.toml b/crates/dav/Cargo.toml index 41ce23d..4a6a1d4 100644 --- a/crates/dav/Cargo.toml +++ b/crates/dav/Cargo.toml @@ -1,23 +1,21 @@ [package] name = "rustical_dav" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true [dependencies] -actix-web = "4.9" -anyhow = "1.0" -async-trait = "0.1" -futures-util = "0.3" -quick-xml = { version = "0.36", features = [ - "serde", - "serde-types", - "serialize", -] } -rustical_store = { path = "../store/" } -serde = { version = "1.0", features = ["derive"] } -strum = "0.26" -itertools = "0.13" -thiserror = "1.0" -roxmltree = "0.20" -log = "0.4" -derive_more = { version = "1.0.0", features = ["deref"] } +actix-web = { workspace = true } +anyhow = { workspace = true } +async-trait = { workspace = true } +futures-util = { workspace = true } +quick-xml = { workspace = true } +rustical_store = { workspace = true } +serde = { workspace = true } +strum = { workspace = true } +thiserror = { workspace = true } +roxmltree = { workspace = true } +itertools = { workspace = true } +log = { workspace = true } +derive_more = { workspace = true } +tracing = { workspace = true } +tracing-actix-web = { workspace = true } diff --git a/crates/dav/src/methods/propfind.rs b/crates/dav/src/methods/propfind.rs index 46afb5f..1e516a0 100644 --- a/crates/dav/src/methods/propfind.rs +++ b/crates/dav/src/methods/propfind.rs @@ -8,9 +8,10 @@ use crate::Error; use actix_web::web::Path; use actix_web::HttpRequest; use derive_more::derive::Deref; -use log::debug; use rustical_store::auth::User; use serde::Deserialize; +use tracing::instrument; +use tracing_actix_web::RootSpan; // This is not the final place for this struct #[derive(Deref)] @@ -38,12 +39,14 @@ struct PropfindElement { prop: PropfindType, } +#[instrument(parent = root_span.id(), skip(path_components, req, root_span))] pub async fn route_propfind( path_components: Path, body: String, req: HttpRequest, user: User, depth: Depth, + root_span: RootSpan, ) -> Result< MultistatusElement< PropstatWrapper<::Prop>, @@ -51,8 +54,6 @@ pub async fn route_propfind( >, R::Error, > { - debug!("{body}"); - let resource_service = R::new(&req, path_components.into_inner()).await?; // A request body is optional. If empty we MUST return all props diff --git a/crates/dav/src/xml/multistatus.rs b/crates/dav/src/xml/multistatus.rs index f186ef7..aa0c490 100644 --- a/crates/dav/src/xml/multistatus.rs +++ b/crates/dav/src/xml/multistatus.rs @@ -94,7 +94,7 @@ impl Responder for MultistatusElement { if let Err(err) = self.serialize(ser) { return crate::Error::from(err).error_response(); } - debug!("Return multistatus:\n{output}"); + // debug!("Return multistatus:\n{output}"); HttpResponse::MultiStatus() .content_type(ContentType::xml()) diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index 03aedc1..32ab78f 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -1,30 +1,24 @@ [package] name = "rustical_store" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true [dependencies] -anyhow = { version = "1.0", features = ["backtrace"] } -async-trait = "0.1" -serde = { version = "1.0", features = ["derive", "rc"] } -sha2 = "0.10" -sqlx = { version = "0.8", features = [ - "sqlx-sqlite", - "uuid", - "chrono", - "sqlite", - "runtime-tokio", - "migrate", -] } -tokio = { version = "1.40", features = ["sync", "full"] } -toml = "0.8" -ical = { version = "0.11", features = ["generator", "serde"] } -chrono = { version = "0.4", features = ["serde"] } -regex = "1.10" -lazy_static = "1.5" -rstest = "0.23" -rstest_reuse = "0.7" -thiserror = "1.0" -password-auth = "1.0" -actix-web = "4.9" -actix-web-httpauth = "0.8" +anyhow = { workspace = true } +async-trait = { workspace = true } +serde = { workspace = true } +sha2 = { workspace = true } +sqlx = { workspace = true } +tokio = { workspace = true } +toml = { workspace = true } +ical = { workspace = true } +chrono = { workspace = true } +regex = { workspace = true } +lazy_static = { workspace = true } +rstest = { workspace = true } +rstest_reuse = { workspace = true } +thiserror = { workspace = true } +password-auth = { workspace = true } +actix-web = { workspace = true } +actix-web-httpauth = { workspace = true } +tracing = { workspace = true } diff --git a/crates/store/src/sqlite_store.rs b/crates/store/src/sqlite_store.rs index 64b93be..0d6f9c9 100644 --- a/crates/store/src/sqlite_store.rs +++ b/crates/store/src/sqlite_store.rs @@ -6,6 +6,7 @@ use async_trait::async_trait; use serde::Serialize; use sqlx::Transaction; use sqlx::{sqlite::SqliteConnectOptions, Pool, Sqlite, SqlitePool}; +use tracing::instrument; #[derive(Debug)] pub struct SqliteCalendarStore { @@ -77,6 +78,7 @@ async fn log_object_operation( #[async_trait] impl CalendarStore for SqliteCalendarStore { + #[instrument] async fn get_calendar(&self, principal: &str, id: &str) -> Result { let cal = sqlx::query_as!( Calendar, @@ -91,6 +93,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(cal) } + #[instrument] async fn get_calendars(&self, principal: &str) -> Result, Error> { let cals = sqlx::query_as!( Calendar, @@ -104,6 +107,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(cals) } + #[instrument] async fn insert_calendar(&mut self, calendar: Calendar) -> Result<(), Error> { sqlx::query!( r#"INSERT INTO calendars (principal, id, displayname, description, "order", color, timezone) @@ -121,6 +125,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(()) } + #[instrument] async fn update_calendar( &mut self, principal: String, @@ -147,6 +152,7 @@ impl CalendarStore for SqliteCalendarStore { } // Does not actually delete the calendar but just disables it + #[instrument] async fn delete_calendar( &mut self, principal: &str, @@ -175,6 +181,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(()) } + #[instrument] async fn restore_calendar(&mut self, principal: &str, id: &str) -> Result<(), Error> { sqlx::query!( r"UPDATE calendars SET deleted_at = NULL WHERE (principal, id) = (?, ?)", @@ -186,6 +193,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(()) } + #[instrument] async fn get_objects(&self, principal: &str, cid: &str) -> Result, Error> { sqlx::query_as!( CalendarObjectRow, @@ -200,6 +208,7 @@ impl CalendarStore for SqliteCalendarStore { .collect() } + #[instrument] async fn get_object( &self, principal: &str, @@ -218,6 +227,7 @@ impl CalendarStore for SqliteCalendarStore { .try_into()?) } + #[instrument] async fn put_object( &mut self, principal: String, @@ -244,6 +254,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(()) } + #[instrument] async fn delete_object( &mut self, principal: &str, @@ -286,6 +297,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(()) } + #[instrument] async fn restore_object(&mut self, principal: &str, cid: &str, uid: &str) -> Result<(), Error> { let mut tx = self.db.begin().await?; @@ -310,6 +322,7 @@ impl CalendarStore for SqliteCalendarStore { Ok(()) } + #[instrument] async fn sync_changes( &self, principal: &str, diff --git a/src/app.rs b/src/app.rs index 33373c1..69efae4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,12 +1,32 @@ use actix_web::body::MessageBody; use actix_web::dev::{ServiceFactory, ServiceRequest, ServiceResponse}; -use actix_web::middleware::{Logger, NormalizePath}; +use actix_web::middleware::NormalizePath; use actix_web::{web, App}; use rustical_frontend::configure_frontend; use rustical_store::auth::AuthenticationProvider; use rustical_store::CalendarStore; use std::sync::Arc; use tokio::sync::RwLock; +use tracing_actix_web::{DefaultRootSpanBuilder, RootSpanBuilder, TracingLogger}; + +struct DomainRootSpanBuilder; + +impl RootSpanBuilder for DomainRootSpanBuilder { + fn on_request_start(request: &ServiceRequest) -> tracing::Span { + tracing_actix_web::root_span!( + request, + request_body = tracing::field::Empty, + user = tracing::field::Empty, + reponse_body = tracing::field::Empty + ) + } + fn on_request_end( + span: tracing::Span, + outcome: &Result, actix_web::Error>, + ) { + DefaultRootSpanBuilder::on_request_end(span, outcome); + } +} pub fn make_app( cal_store: Arc>, @@ -21,7 +41,8 @@ pub fn make_app( >, > { App::new() - .wrap(Logger::new("[%s] %r")) + .wrap(TracingLogger::::new()) + // .wrap(Logger::new("[%s] %r")) .wrap(NormalizePath::trim()) .service(web::scope("/caldav").configure(|cfg| { rustical_caldav::configure_dav( diff --git a/src/config.rs b/src/config.rs index 6ff766b..649dd4b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -25,10 +25,16 @@ pub enum AuthConfig { Static(StaticUserStoreConfig), } +#[derive(Debug, Deserialize, Serialize)] +pub struct TracingConfig { + pub opentelemetry: bool, +} + #[derive(Debug, Deserialize, Serialize)] pub struct Config { pub calendar_store: CalendarStoreConfig, pub auth: AuthConfig, pub http: HttpConfig, pub frontend: FrontendConfig, + pub tracing: TracingConfig, } diff --git a/src/main.rs b/src/main.rs index 8e977f4..93f8f3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,13 +3,28 @@ use actix_web::HttpServer; use anyhow::Result; use app::make_app; use clap::Parser; -use config::{CalendarStoreConfig, SqliteCalendarStoreConfig}; +use config::{CalendarStoreConfig, SqliteCalendarStoreConfig, TracingConfig}; +use opentelemetry::global; +use opentelemetry::trace::TracerProvider; +use opentelemetry::KeyValue; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_sdk::propagation::TraceContextPropagator; +use opentelemetry_sdk::trace::{self, BatchConfig, Tracer}; +use opentelemetry_sdk::{runtime, Resource}; +use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION}; +use opentelemetry_semantic_conventions::SCHEMA_URL; use rustical_store::auth::StaticUserStore; use rustical_store::sqlite_store::{create_db_pool, SqliteCalendarStore}; use rustical_store::CalendarStore; use std::fs; use std::sync::Arc; +use std::time::Duration; use tokio::sync::RwLock; +use tracing::level_filters::LevelFilter; +use tracing_opentelemetry::OpenTelemetryLayer; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::EnvFilter; mod app; mod config; @@ -36,13 +51,59 @@ async fn get_cal_store( Ok(cal_store) } +pub fn init_tracer() -> Tracer { + let otel_exporter = opentelemetry_otlp::new_exporter() + .tonic() + .with_timeout(Duration::from_secs(1)); + + let tracer_provider = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter(otel_exporter) + .with_trace_config( + trace::Config::default().with_resource(Resource::from_schema_url( + [ + KeyValue::new(SERVICE_NAME, env!("CARGO_PKG_NAME")), + KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")), + ], + SCHEMA_URL, + )), + ) + .with_batch_config(BatchConfig::default()) + .install_batch(runtime::Tokio) + .expect("Failed to install tracer"); + + global::set_tracer_provider(tracer_provider.clone()); + tracer_provider.tracer("rustical") +} + +fn setup_tracing(config: &TracingConfig) { + let fmt_layer = tracing_subscriber::fmt::layer(); + let filter_layer = EnvFilter::builder() + .with_default_directive(LevelFilter::WARN.into()) + .from_env_lossy() + .add_directive("h2=warn".parse().unwrap()) + .add_directive("hyper_util=warn".parse().unwrap()) + .add_directive("tower=warn".parse().unwrap()); + + let registry = tracing_subscriber::registry() + .with(filter_layer) + .with(fmt_layer); + + if config.opentelemetry { + global::set_text_map_propagator(TraceContextPropagator::new()); + registry.with(OpenTelemetryLayer::new(init_tracer())).init(); + } else { + registry.init(); + } +} + #[tokio::main] async fn main() -> Result<()> { - env_logger::init_from_env(env_logger::Env::default().default_filter_or("info")); - let args = Args::parse(); let config: Config = toml::from_str(&fs::read_to_string(&args.config_file)?)?; + setup_tracing(&config.tracing); + let cal_store = get_cal_store(args.migrate, &config.calendar_store).await?; let user_store = Arc::new(match config.auth {