mirror of
https://github.com/shiroyashik/sculptor.git
synced 2025-12-06 04:51:13 +03:00
Add Prometheus metrics support and update Rust to edition 2024 and version 1.85.0
Some checks failed
Push Dev / docker (push) Has been cancelled
Some checks failed
Push Dev / docker (push) Has been cancelled
This commit is contained in:
parent
bac1203df8
commit
45aa79da6d
14 changed files with 306 additions and 128 deletions
192
Cargo.lock
generated
192
Cargo.lock
generated
|
|
@ -60,9 +60,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.95"
|
version = "1.0.96"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arbitrary"
|
name = "arbitrary"
|
||||||
|
|
@ -248,9 +248,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.13"
|
version = "1.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda"
|
checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -591,9 +591,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
|
|
@ -650,7 +650,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
|
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide 0.8.4",
|
"miniz_oxide 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -783,9 +783,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
|
checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -852,6 +852,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
@ -1200,9 +1206,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inout"
|
name = "inout"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
@ -1317,9 +1323,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.25"
|
version = "0.4.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lzma-rs"
|
name = "lzma-rs"
|
||||||
|
|
@ -1369,9 +1375,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b"
|
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler2",
|
"adler2",
|
||||||
]
|
]
|
||||||
|
|
@ -1390,9 +1396,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.13"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c"
|
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
|
@ -1495,9 +1501,9 @@ checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.70"
|
version = "0.10.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
|
checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.8.0",
|
"bitflags 2.8.0",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
|
@ -1527,9 +1533,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.105"
|
version = "0.9.106"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc"
|
checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -1663,6 +1669,52 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "procfs"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.8.0",
|
||||||
|
"hex",
|
||||||
|
"lazy_static",
|
||||||
|
"procfs-core",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "procfs-core"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.8.0",
|
||||||
|
"hex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prometheus"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"fnv",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"memchr",
|
||||||
|
"parking_lot",
|
||||||
|
"procfs",
|
||||||
|
"protobuf",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "protobuf"
|
||||||
|
version = "2.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.38"
|
version = "1.0.38"
|
||||||
|
|
@ -1690,8 +1742,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha 0.9.0",
|
"rand_chacha 0.9.0",
|
||||||
"rand_core 0.9.0",
|
"rand_core 0.9.1",
|
||||||
"zerocopy 0.8.17",
|
"zerocopy 0.8.20",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1711,7 +1763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core 0.9.0",
|
"rand_core 0.9.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1725,19 +1777,19 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.9.0"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
|
checksum = "a88e0da7a2c97baa202165137c158d0a2e824ac465d13d81046727b34cb247d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
"zerocopy 0.8.17",
|
"zerocopy 0.8.20",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.8"
|
version = "0.5.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.8.0",
|
"bitflags 2.8.0",
|
||||||
]
|
]
|
||||||
|
|
@ -1844,15 +1896,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.8"
|
version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
|
checksum = "d34b5020fcdea098ef7d95e9f89ec15952123a4a039badd09fabebe9e963e839"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
"libc",
|
"libc",
|
||||||
"spin",
|
|
||||||
"untrusted",
|
"untrusted",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
@ -1973,8 +2024,8 @@ dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"faster-hex",
|
"faster-hex",
|
||||||
"indexmap 2.7.1",
|
"indexmap 2.7.1",
|
||||||
"lazy_static",
|
|
||||||
"notify",
|
"notify",
|
||||||
|
"prometheus",
|
||||||
"rand 0.9.0",
|
"rand 0.9.0",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"ring",
|
"ring",
|
||||||
|
|
@ -2025,18 +2076,18 @@ checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.217"
|
version = "1.0.218"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.217"
|
version = "1.0.218"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2054,9 +2105,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.138"
|
version = "1.0.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
@ -2159,9 +2210,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
|
|
@ -2173,12 +2224,6 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "spin"
|
|
||||||
version = "0.9.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
|
@ -2272,9 +2317,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.16.0"
|
version = "3.17.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
|
checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
|
|
@ -2441,9 +2486,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.26.1"
|
version = "0.26.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a"
|
checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
|
|
@ -2644,17 +2689,16 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.26.1"
|
version = "0.26.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24"
|
checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"http",
|
"http",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.5",
|
"rand 0.9.0",
|
||||||
"sha1",
|
"sha1",
|
||||||
"thiserror 2.0.11",
|
"thiserror 2.0.11",
|
||||||
"utf-8",
|
"utf-8",
|
||||||
|
|
@ -2662,15 +2706,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.17.0"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.16"
|
version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
|
|
@ -2709,9 +2753,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.13.1"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0"
|
checksum = "93d59ca99a559661b96bf898d8fce28ed87935fd2bea9f05983c1464dd6c71b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
@ -3015,9 +3059,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603"
|
checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
@ -3079,11 +3123,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.17"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713"
|
checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive 0.8.17",
|
"zerocopy-derive 0.8.20",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3099,9 +3143,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.8.17"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626"
|
checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -3216,27 +3260,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.13.2"
|
version = "0.13.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
|
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zstd-safe",
|
"zstd-safe",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd-safe"
|
name = "zstd-safe"
|
||||||
version = "7.2.1"
|
version = "7.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059"
|
checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zstd-sys",
|
"zstd-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd-sys"
|
name = "zstd-sys"
|
||||||
version = "2.0.13+zstd.1.5.6"
|
version = "2.0.14+zstd.1.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa"
|
checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
name = "sculptor"
|
name = "sculptor"
|
||||||
authors = ["Shiroyashik <shiroyashik@shsr.ru>"]
|
authors = ["Shiroyashik <shiroyashik@shsr.ru>"]
|
||||||
version = "0.4.1-dev"
|
version = "0.4.1-dev"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
@ -31,7 +31,6 @@ semver = "1.0"
|
||||||
walkdir = "2.5"
|
walkdir = "2.5"
|
||||||
indexmap = { version = "2.6", features = ["serde"] }
|
indexmap = { version = "2.6", features = ["serde"] }
|
||||||
zip = "2.2"
|
zip = "2.2"
|
||||||
lazy_static = "1.5"
|
|
||||||
notify = "8.0"
|
notify = "8.0"
|
||||||
|
|
||||||
# Crypto
|
# Crypto
|
||||||
|
|
@ -42,6 +41,7 @@ rand = "0.9"
|
||||||
axum = { version = "0.8", features = ["ws", "macros", "http2"] }
|
axum = { version = "0.8", features = ["ws", "macros", "http2"] }
|
||||||
tower-http = { version = "0.6", features = ["trace"] }
|
tower-http = { version = "0.6", features = ["trace"] }
|
||||||
tokio = { version = "1.41", features = ["full"] }
|
tokio = { version = "1.41", features = ["full"] }
|
||||||
|
prometheus = { version = "0.13.4", features = ["process"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cross = "0.2.5"
|
cross = "0.2.5"
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,12 @@ listen = "0.0.0.0:6665"
|
||||||
## Don't touch if you don't know what you're doing
|
## Don't touch if you don't know what you're doing
|
||||||
# token = "<random symbols>"
|
# token = "<random symbols>"
|
||||||
|
|
||||||
|
## Enable Prometheus metrics
|
||||||
|
# metricsEnabled = true
|
||||||
|
|
||||||
## Path to minecraft server folder
|
## Path to minecraft server folder
|
||||||
## Sculptor try to use ban list from it
|
## Sculptor try to use ban list from it
|
||||||
|
## on Windows use double slash: "C:\\Servers\\1.20.1"
|
||||||
# mcFolder = "~/minecraft_server"
|
# mcFolder = "~/minecraft_server"
|
||||||
|
|
||||||
## Can't work without at least one provider!
|
## Can't work without at least one provider!
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
## Chef
|
## Chef
|
||||||
# FROM clux/muslrust:stable AS chef
|
# FROM clux/muslrust:stable AS chef
|
||||||
FROM rust:1.84-alpine3.21 AS chef
|
FROM rust:1.85-alpine3.21 AS chef
|
||||||
USER root
|
USER root
|
||||||
RUN apk add --no-cache musl-dev libressl-dev
|
RUN apk add --no-cache musl-dev libressl-dev
|
||||||
RUN cargo install cargo-chef
|
RUN cargo install cargo-chef
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use axum::{debug_handler, extract::{Query, State}, response::{IntoResponse, Response}, routing::get, Router};
|
use axum::{extract::{Query, State}, http::HeaderMap, response::{IntoResponse, Response}, routing::get, Router};
|
||||||
use reqwest::StatusCode;
|
use reqwest::{header::USER_AGENT, StatusCode};
|
||||||
use ring::digest::{self, digest};
|
use ring::digest::{self, digest};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info, instrument};
|
||||||
|
|
||||||
use crate::{auth::{has_joined, Userinfo}, utils::rand, AppState};
|
use crate::{auth::{has_joined, Userinfo}, utils::rand, AppState};
|
||||||
use super::types::auth::*;
|
use super::types::auth::*;
|
||||||
|
|
@ -12,7 +12,6 @@ pub fn router() -> Router<AppState> {
|
||||||
.route("/verify", get(verify))
|
.route("/verify", get(verify))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
|
||||||
async fn id(
|
async fn id(
|
||||||
// First stage of authentication
|
// First stage of authentication
|
||||||
Query(query): Query<Id>,
|
Query(query): Query<Id>,
|
||||||
|
|
@ -25,10 +24,11 @@ async fn id(
|
||||||
server_id
|
server_id
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
#[instrument(skip_all)]
|
||||||
async fn verify(
|
async fn verify(
|
||||||
// Second stage of authentication
|
// Second stage of authentication
|
||||||
Query(query): Query<Verify>,
|
Query(query): Query<Verify>,
|
||||||
|
header: HeaderMap,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
let server_id = query.id.clone();
|
let server_id = query.id.clone();
|
||||||
|
|
@ -47,17 +47,23 @@ async fn verify(
|
||||||
if let Some((uuid, auth_provider)) = userinfo {
|
if let Some((uuid, auth_provider)) = userinfo {
|
||||||
let umanager = state.user_manager;
|
let umanager = state.user_manager;
|
||||||
if umanager.is_banned(&uuid) {
|
if umanager.is_banned(&uuid) {
|
||||||
info!("[Authentication] {nickname} tried to log in, but was banned");
|
info!("{nickname} tried to log in, but was banned");
|
||||||
return (StatusCode::BAD_REQUEST, "You're banned!".to_string()).into_response();
|
return (StatusCode::BAD_REQUEST, "You're banned!".to_string()).into_response();
|
||||||
}
|
}
|
||||||
info!("[Authentication] {nickname} logged in using {}", auth_provider.name);
|
let mut userinfo = Userinfo {
|
||||||
let userinfo = Userinfo {
|
|
||||||
nickname,
|
nickname,
|
||||||
uuid,
|
uuid,
|
||||||
token: Some(server_id.clone()),
|
token: Some(server_id.clone()),
|
||||||
auth_provider,
|
auth_provider,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
if let Some(agent) = header.get(USER_AGENT) {
|
||||||
|
if let Ok(agent) = agent.to_str() {
|
||||||
|
userinfo.version = agent.to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info!("{} logged in using {} with {}", userinfo.nickname, userinfo.auth_provider.name, userinfo.version);
|
||||||
|
|
||||||
match umanager.insert(uuid, server_id.clone(), userinfo.clone()) {
|
match umanager.insert(uuid, server_id.clone(), userinfo.clone()) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
|
@ -70,7 +76,7 @@ async fn verify(
|
||||||
}
|
}
|
||||||
(StatusCode::OK, server_id.to_string()).into_response()
|
(StatusCode::OK, server_id.to_string()).into_response()
|
||||||
} else {
|
} else {
|
||||||
info!("[Authentication] failed to verify {nickname}");
|
info!("failed to verify {nickname}");
|
||||||
(StatusCode::BAD_REQUEST, "failed to verify".to_string()).into_response()
|
(StatusCode::BAD_REQUEST, "failed to verify".to_string()).into_response()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +15,7 @@ pub async fn initial(
|
||||||
ws.on_upgrade(|socket| handle_socket(socket, state))
|
ws.on_upgrade(|socket| handle_socket(socket, state))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip_all)]
|
||||||
async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||||
// Trying authenticate & get user data or dropping connection
|
// Trying authenticate & get user data or dropping connection
|
||||||
match authenticate(&mut ws, &state).await {
|
match authenticate(&mut ws, &state).await {
|
||||||
|
|
@ -44,7 +45,7 @@ async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||||
|
|
||||||
// Starting main worker
|
// Starting main worker
|
||||||
if let Err(kind) = main_worker(&mut session, &mut ws, &state).await {
|
if let Err(kind) = main_worker(&mut session, &mut ws, &state).await {
|
||||||
tracing::error!("[WebSocket] Main worker halted due to {}.", kind)
|
tracing::info!(error = %kind, nickname = %session.user.nickname, "Main worker exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, handle) in session.sub_workers_aborthandles {
|
for (_, handle) in session.sub_workers_aborthandles {
|
||||||
|
|
@ -56,7 +57,7 @@ async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||||
state.user_manager.remove(&user.uuid);
|
state.user_manager.remove(&user.uuid);
|
||||||
},
|
},
|
||||||
Err(kind) => {
|
Err(kind) => {
|
||||||
tracing::info!("[WebSocket] Can't authenticate: {}", kind);
|
tracing::info!(error = %kind, "Can't authenticate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +65,7 @@ async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||||
if let Err(kind) = ws.send(Message::Close(None)).await { tracing::trace!("[WebSocket] Closing fault: {}", kind) }
|
if let Err(kind) = ws.send(Message::Close(None)).await { tracing::trace!("[WebSocket] Closing fault: {}", kind) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all, fields(nickname = %session.user.nickname))]
|
#[instrument(skip_all, parent = None, fields(nickname = %session.user.nickname))]
|
||||||
async fn main_worker(session: &mut WSSession, ws: &mut WebSocket, state: &AppState) -> anyhow::Result<()> {
|
async fn main_worker(session: &mut WSSession, ws: &mut WebSocket, state: &AppState) -> anyhow::Result<()> {
|
||||||
tracing::debug!("WebSocket control for {} is transferred to the main worker", session.user.nickname);
|
tracing::debug!("WebSocket control for {} is transferred to the main worker", session.user.nickname);
|
||||||
loop {
|
loop {
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,16 @@ impl From<C2SMessage> for Vec<u8> {
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl C2SMessage {
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
C2SMessage::Token(_) => "c2s>token",
|
||||||
|
C2SMessage::Ping(_, _, _) => "c2s>ping",
|
||||||
|
C2SMessage::Sub(_) => "c2s>sub",
|
||||||
|
C2SMessage::Unsub(_) => "c2s>unsub",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// impl<'a> C2SMessage<'a> {
|
// impl<'a> C2SMessage<'a> {
|
||||||
// pub fn to_array(&self) -> Box<[u8]> {
|
// pub fn to_array(&self) -> Box<[u8]> {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ mod s2c;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod session;
|
mod session;
|
||||||
|
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
pub use session::*;
|
pub use session::*;
|
||||||
pub use errors::*;
|
pub use errors::*;
|
||||||
pub use c2s::*;
|
pub use c2s::*;
|
||||||
|
|
@ -10,6 +12,8 @@ pub use s2c::*;
|
||||||
|
|
||||||
use axum::extract::ws::{Message, WebSocket};
|
use axum::extract::ws::{Message, WebSocket};
|
||||||
|
|
||||||
|
use crate::{PINGS, PINGS_ERROR};
|
||||||
|
|
||||||
pub trait RecvAndDecode {
|
pub trait RecvAndDecode {
|
||||||
async fn recv_and_decode(&mut self) -> Result<C2SMessage, RADError>;
|
async fn recv_and_decode(&mut self) -> Result<C2SMessage, RADError>;
|
||||||
}
|
}
|
||||||
|
|
@ -21,9 +25,17 @@ impl RecvAndDecode for WebSocket {
|
||||||
if let Message::Close(frame) = msg {
|
if let Message::Close(frame) = msg {
|
||||||
return Err(RADError::Close(frame.map(|f| format!("code: {}, reason: {}", f.code, f.reason))));
|
return Err(RADError::Close(frame.map(|f| format!("code: {}, reason: {}", f.code, f.reason))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
|
||||||
let data = msg.into_data();
|
let data = msg.into_data();
|
||||||
C2SMessage::try_from(data.as_ref())
|
let msg = C2SMessage::try_from(data.as_ref())
|
||||||
.map_err(|e| RADError::DecodeError(e, faster_hex::hex_string(&data)))
|
.map_err(|e| { PINGS_ERROR.inc(); RADError::DecodeError(e, faster_hex::hex_string(&data)) });
|
||||||
|
|
||||||
|
let latency = start.elapsed().as_secs_f64();
|
||||||
|
PINGS
|
||||||
|
.with_label_values(&[msg.as_ref().map(|m| m.name()).unwrap_or("error")])
|
||||||
|
.observe(latency);
|
||||||
|
msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +85,18 @@ impl From<S2CMessage> for Vec<u8> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl S2CMessage {
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
S2CMessage::Auth => "s2c>auth",
|
||||||
|
S2CMessage::Ping(_, _, _, _) => "s2c>ping",
|
||||||
|
S2CMessage::Event(_) => "s2c>event",
|
||||||
|
S2CMessage::Toast(_, _, _) => "s2c>toast",
|
||||||
|
S2CMessage::Chat(_) => "s2c>chat",
|
||||||
|
S2CMessage::Notice(_) => "s2c>notice",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// impl<'a> S2CMessage<'a> {
|
// impl<'a> S2CMessage<'a> {
|
||||||
// pub fn to_array(&self) -> Box<[u8]> {
|
// pub fn to_array(&self) -> Box<[u8]> {
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
Json
|
Json
|
||||||
};
|
};
|
||||||
|
use dashmap::DashMap;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{api::errors::internal_and_log, auth::{Token, Userinfo}, ApiResult, AppState};
|
use crate::{auth::{Token, Userinfo}, ApiResult, AppState};
|
||||||
|
|
||||||
pub(super) async fn create_user(
|
pub(super) async fn create_user(
|
||||||
Token(token): Token,
|
Token(token): Token,
|
||||||
|
|
@ -50,17 +51,17 @@ pub(super) async fn unban(
|
||||||
pub(super) async fn list(
|
pub(super) async fn list(
|
||||||
Token(token): Token,
|
Token(token): Token,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> ApiResult<String> {
|
) -> ApiResult<Json<DashMap<Uuid, Userinfo>>> {
|
||||||
state.config.read().await.clone().verify_token(&token)?;
|
state.config.read().await.clone().verify_token(&token)?;
|
||||||
|
|
||||||
serde_json::to_string_pretty(&state.user_manager.get_all_registered()).map_err(|err| { internal_and_log(err) })
|
Ok(Json(state.user_manager.get_all_registered()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn list_sessions(
|
pub(super) async fn list_sessions(
|
||||||
Token(token): Token,
|
Token(token): Token,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> ApiResult<String> {
|
) -> ApiResult<Json<DashMap<String, Uuid>>> {
|
||||||
state.config.read().await.clone().verify_token(&token)?;
|
state.config.read().await.clone().verify_token(&token)?;
|
||||||
|
|
||||||
serde_json::to_string_pretty(&state.user_manager.get_all_authenticated()).map_err(|err| { internal_and_log(err) })
|
Ok(Json(state.user_manager.get_all_authenticated()))
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +182,12 @@ pub struct UManager {
|
||||||
registered: Arc<DashMap<Uuid, Userinfo>>,
|
registered: Arc<DashMap<Uuid, Userinfo>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for UManager {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UManager {
|
impl UManager {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -229,6 +235,7 @@ impl UManager {
|
||||||
if userinfo.rank != Userinfo::default().rank { exist.rank = userinfo.rank };
|
if userinfo.rank != Userinfo::default().rank { exist.rank = userinfo.rank };
|
||||||
if userinfo.token.is_some() { exist.token = userinfo.token };
|
if userinfo.token.is_some() { exist.token = userinfo.token };
|
||||||
if userinfo.version != Userinfo::default().version { exist.version = userinfo.version };
|
if userinfo.version != Userinfo::default().version { exist.version = userinfo.version };
|
||||||
|
exist.last_used = userinfo.last_used;
|
||||||
}).or_insert(usercopy);
|
}).or_insert(usercopy);
|
||||||
}
|
}
|
||||||
pub fn get(
|
pub fn get(
|
||||||
|
|
@ -274,7 +281,6 @@ impl UManager {
|
||||||
}
|
}
|
||||||
// End of User manager
|
// End of User manager
|
||||||
|
|
||||||
#[axum::debug_handler]
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn check_auth(
|
pub async fn check_auth(
|
||||||
token: Option<Token>,
|
token: Option<Token>,
|
||||||
|
|
|
||||||
71
src/main.rs
71
src/main.rs
|
|
@ -6,10 +6,9 @@ use axum::{
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use tracing_panic::panic_hook;
|
use tracing_panic::panic_hook;
|
||||||
use tracing_subscriber::{fmt::{self, time::ChronoLocal}, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
use tracing_subscriber::{fmt::{self, time::ChronoLocal}, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
||||||
use std::{path::PathBuf, sync::Arc, env::var};
|
use std::{env::var, path::PathBuf, sync::{Arc, LazyLock}};
|
||||||
use tokio::{fs, sync::RwLock, time::Instant};
|
use tokio::{fs, sync::RwLock, time::Instant};
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
// Consts
|
// Consts
|
||||||
mod consts;
|
mod consts;
|
||||||
|
|
@ -18,12 +17,13 @@ pub use consts::*;
|
||||||
// Errors
|
// Errors
|
||||||
pub use api::errors::{ApiResult, ApiError};
|
pub use api::errors::{ApiResult, ApiError};
|
||||||
|
|
||||||
|
// Metrics
|
||||||
|
mod metrics;
|
||||||
|
pub use metrics::*;
|
||||||
|
|
||||||
// API
|
// API
|
||||||
mod api;
|
mod api;
|
||||||
use api::{
|
use api::figura::{ws, info as api_info, profile as api_profile, auth as api_auth, assets as api_assets};
|
||||||
figura::{ws, info as api_info, profile as api_profile, auth as api_auth, assets as api_assets},
|
|
||||||
// v1::{},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Auth
|
// Auth
|
||||||
mod auth;
|
mod auth;
|
||||||
|
|
@ -37,23 +37,21 @@ use state::{Config, AppState};
|
||||||
mod utils;
|
mod utils;
|
||||||
use utils::*;
|
use utils::*;
|
||||||
|
|
||||||
lazy_static! {
|
pub static LOGGER_VAR: LazyLock<String> = LazyLock::new(|| {
|
||||||
pub static ref LOGGER_VAR: String = {
|
var(LOGGER_ENV).unwrap_or(String::from("info"))
|
||||||
var(LOGGER_ENV).unwrap_or(String::from("info"))
|
});
|
||||||
};
|
pub static CONFIG_VAR: LazyLock<String> = LazyLock::new(|| {
|
||||||
pub static ref CONFIG_VAR: String = {
|
var(CONFIG_ENV).unwrap_or(String::from("Config.toml"))
|
||||||
var(CONFIG_ENV).unwrap_or(String::from("Config.toml"))
|
});
|
||||||
};
|
pub static LOGS_VAR: LazyLock<String> = LazyLock::new(|| {
|
||||||
pub static ref LOGS_VAR: String = {
|
var(LOGS_ENV).unwrap_or(String::from("logs"))
|
||||||
var(LOGS_ENV).unwrap_or(String::from("logs"))
|
});
|
||||||
};
|
pub static ASSETS_VAR: LazyLock<String> = LazyLock::new(|| {
|
||||||
pub static ref ASSETS_VAR: String = {
|
var(ASSETS_ENV).unwrap_or(String::from("data/assets"))
|
||||||
var(ASSETS_ENV).unwrap_or(String::from("data/assets"))
|
});
|
||||||
};
|
pub static AVATARS_VAR: LazyLock<String> = LazyLock::new(|| {
|
||||||
pub static ref AVATARS_VAR: String = {
|
var(AVATARS_ENV).unwrap_or(String::from("data/avatars"))
|
||||||
var(AVATARS_ENV).unwrap_or(String::from("data/avatars"))
|
});
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
|
@ -128,11 +126,11 @@ async fn app() -> Result<bool> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
let config = Arc::new(RwLock::new(Config::parse(CONFIG_VAR.clone().into())));
|
let config = Config::parse(CONFIG_VAR.clone().into());
|
||||||
let listen = config.read().await.listen.clone();
|
let listen = config.listen.clone();
|
||||||
let limit = get_limit_as_bytes(config.read().await.limitations.max_avatar_size as usize);
|
let limit = get_limit_as_bytes(config.limitations.max_avatar_size as usize);
|
||||||
|
|
||||||
if config.read().await.assets_updater_enabled {
|
if config.assets_updater_enabled {
|
||||||
// Force update assets if folder or hash file doesn't exists.
|
// Force update assets if folder or hash file doesn't exists.
|
||||||
if !(PathBuf::from(&*ASSETS_VAR).is_dir() && get_path_to_assets_hash().is_file()) {
|
if !(PathBuf::from(&*ASSETS_VAR).is_dir() && get_path_to_assets_hash().is_file()) {
|
||||||
tracing::debug!("Removing broken assets...");
|
tracing::debug!("Removing broken assets...");
|
||||||
|
|
@ -164,7 +162,7 @@ async fn app() -> Result<bool> {
|
||||||
session: Arc::new(DashMap::new()),
|
session: Arc::new(DashMap::new()),
|
||||||
subscribes: Arc::new(DashMap::new()),
|
subscribes: Arc::new(DashMap::new()),
|
||||||
figura_versions: Arc::new(RwLock::new(None)),
|
figura_versions: Arc::new(RwLock::new(None)),
|
||||||
config,
|
config: Arc::new(RwLock::new(config.clone())),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Automatic update of configuration/ban list while the server is running
|
// Automatic update of configuration/ban list while the server is running
|
||||||
|
|
@ -175,7 +173,7 @@ async fn app() -> Result<bool> {
|
||||||
Arc::clone(&state.config)
|
Arc::clone(&state.config)
|
||||||
));
|
));
|
||||||
// Blacklist auto update
|
// Blacklist auto update
|
||||||
if state.config.read().await.mc_folder.exists() {
|
if config.mc_folder.exists() {
|
||||||
tokio::spawn(update_bans_from_minecraft(
|
tokio::spawn(update_bans_from_minecraft(
|
||||||
state.config.read().await.mc_folder.clone(),
|
state.config.read().await.mc_folder.clone(),
|
||||||
Arc::clone(&state.user_manager),
|
Arc::clone(&state.user_manager),
|
||||||
|
|
@ -200,8 +198,19 @@ async fn app() -> Result<bool> {
|
||||||
.nest("/api", api)
|
.nest("/api", api)
|
||||||
.route("/api/", get(check_auth))
|
.route("/api/", get(check_auth))
|
||||||
.route("/ws", get(ws))
|
.route("/ws", get(ws))
|
||||||
.with_state(state)
|
.layer(TraceLayer::new_for_http()
|
||||||
.layer(TraceLayer::new_for_http().on_request(()))
|
// .on_request(|request: &axum::http::Request<_>, _span: &tracing::Span| {
|
||||||
|
// // only for developing purposes
|
||||||
|
// tracing::trace!(headers = ?request.headers(), "started processing request");
|
||||||
|
// })
|
||||||
|
.on_response(|response: &axum::http::Response<_>, latency: std::time::Duration, _span: &tracing::Span| {
|
||||||
|
tracing::trace!(latency = ?latency, status = ?response.status(), "finished processing request");
|
||||||
|
})
|
||||||
|
.on_request(())
|
||||||
|
)
|
||||||
|
.layer(axum::middleware::from_fn(track_metrics))
|
||||||
|
.merge(metrics::metrics_router(config.metrics_enabled))
|
||||||
|
.with_state(state)
|
||||||
.route("/health", get(|| async { "ok" }));
|
.route("/health", get(|| async { "ok" }));
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind(listen).await?;
|
let listener = tokio::net::TcpListener::bind(listen).await?;
|
||||||
|
|
|
||||||
71
src/metrics.rs
Normal file
71
src/metrics.rs
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
|
||||||
|
use std::{sync::LazyLock, time::Instant};
|
||||||
|
|
||||||
|
use axum::{body::Body, extract::State, http::{Request, Response}, middleware::Next, routing::get, Router};
|
||||||
|
use prometheus::{proto::{Metric, MetricType}, register_histogram_vec, register_int_counter};
|
||||||
|
use reqwest::StatusCode;
|
||||||
|
|
||||||
|
use crate::state::AppState;
|
||||||
|
|
||||||
|
pub fn metrics_router(enabled: bool) -> Router<AppState> {
|
||||||
|
if !enabled { return Router::new(); }
|
||||||
|
tracing::info!("Metrics enabled! You can access them on /metrics");
|
||||||
|
Router::new()
|
||||||
|
.route("/metrics", get(metrics))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn metrics(State(state): State<AppState>) -> String {
|
||||||
|
let mut metric_families = prometheus::gather();
|
||||||
|
|
||||||
|
// Add new custom metrics
|
||||||
|
let players = {
|
||||||
|
let mut metric = prometheus::proto::Metric::default();
|
||||||
|
metric.set_gauge(prometheus::proto::Gauge::default());
|
||||||
|
metric.mut_gauge().set_value(state.session.len() as f64);
|
||||||
|
create_mf("players_count".to_string(), "Number of players".to_string(), MetricType::GAUGE, metric)
|
||||||
|
};
|
||||||
|
|
||||||
|
metric_families.push(players);
|
||||||
|
|
||||||
|
prometheus::TextEncoder::new()
|
||||||
|
.encode_to_string(&metric_families)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn create_mf(name: String, help: String, field_type: MetricType, metric: Metric) -> prometheus::proto::MetricFamily {
|
||||||
|
let mut mf = prometheus::proto::MetricFamily::default();
|
||||||
|
mf.set_name(name);
|
||||||
|
mf.set_help(help);
|
||||||
|
mf.set_field_type(field_type);
|
||||||
|
mf.mut_metric().push(metric);
|
||||||
|
mf
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn track_metrics(req: Request<Body>, next: Next) -> Result<Response<Body>, StatusCode> {
|
||||||
|
let start = Instant::now();
|
||||||
|
let uri = req.uri().path().to_string();
|
||||||
|
|
||||||
|
// Call the next middleware or handler
|
||||||
|
let response = next.run(req).await;
|
||||||
|
|
||||||
|
let latency = start.elapsed().as_secs_f64();
|
||||||
|
|
||||||
|
REQUESTS
|
||||||
|
.with_label_values(&[&uri, response.status().as_str()])
|
||||||
|
.observe(latency);
|
||||||
|
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static PINGS_ERROR: LazyLock<prometheus::IntCounter> = LazyLock::new(|| {
|
||||||
|
register_int_counter!("pings_error", "Number of ping decoding errors").unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
pub static REQUESTS: LazyLock<prometheus::HistogramVec> = LazyLock::new(|| {
|
||||||
|
register_histogram_vec!("requests_count", "Number of requests", &["uri", "code"], vec![0.025, 0.250, 0.500]).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
pub static PINGS: LazyLock<prometheus::HistogramVec> = LazyLock::new(|| {
|
||||||
|
register_histogram_vec!("pings_count", "Number of pings", &["type"], vec![0.000003, 0.00002, 0.0002]).unwrap()
|
||||||
|
});
|
||||||
|
|
@ -10,6 +10,8 @@ use crate::auth::{default_authproviders, AuthProviders, Userinfo};
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub listen: String,
|
pub listen: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub metrics_enabled: bool,
|
||||||
pub token: Option<String>,
|
pub token: Option<String>,
|
||||||
pub assets_updater_enabled: bool,
|
pub assets_updater_enabled: bool,
|
||||||
pub motd: CMotd,
|
pub motd: CMotd,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue