diff --git a/.woodpecker.yml b/.woodpecker.yml index c037259..ebf1d4f 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,30 +1,18 @@ pipeline: - fmt: + checkmate: group: default image: rust_full commands: - - cargo fmt --all -- --check - - clippy: - group: default - image: rust_full - commands: - - cargo clippy --all-features - - doc: - group: default - image: rust_full - commands: - - cargo doc --all-features - - build: - group: default - image: rust_full - commands: - - cargo build --all-features + - cargo checkmate build_release: - group: release + group: default image: rust_full commands: - cargo build --all-features --release + + build_deb: + group: default + image: rust_full + commands: + - cargo deb diff --git a/Cargo.lock b/Cargo.lock index 9a86816..463a8da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,18 +38,91 @@ version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +[[package]] +name = "async-trait" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f523b4e98ba6897ae90994bc18423d9877c54f9047b06a00ddc8122a957b1c70" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3ddbd16eabff8b45f21b98671fddcc93daaa7ac4c84f8473693437226040de5" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "cc" version = "1.0.73" @@ -62,6 +135,225 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "3.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c167e37342afc5f33fd87bbc870cedd020d2a6dffa05d45ccd9241fbdd146db" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "lazy_static", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +dependencies = [ + "bytes", + "http", + "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.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.124" @@ -88,6 +380,15 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "log" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +dependencies = [ + "cfg-if", +] + [[package]] name = "mach" version = "0.1.2" @@ -106,6 +407,18 @@ dependencies = [ "libc", ] +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + [[package]] name = "memchr" version = "2.4.1" @@ -123,10 +436,44 @@ dependencies = [ [[package]] name = "mightyohm-gc-exporter" -version = "0.1.0-dev" +version = "0.1.0" dependencies = [ "anyhow", + "axum", + "clap", + "env_logger", + "log", "serialport", + "tokio", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mio" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "wasi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", ] [[package]] @@ -142,12 +489,117 @@ dependencies = [ "memoffset", ] +[[package]] +name = "ntapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +dependencies = [ + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + [[package]] name = "regex" version = "1.5.5" @@ -165,6 +617,41 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" + +[[package]] +name = "serde_json" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serialport" version = "4.1.0" @@ -182,6 +669,196 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + +[[package]] +name = "tokio" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +dependencies = [ + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" @@ -198,6 +875,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 69355f2..053928e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "mightyohm-gc-exporter" -version = "0.1.0-dev" +version = "0.1.0" +authors = ["finga "] edition = "2021" -description = "Prometheus exporter for the MightyOhm Geiger Counter" +description = "Prometheus exporter for the MightyOhm Geiger Counter." +readme = "README.md" license = "GPL-3.0-or-later" repository = "https://git.onders.org/finga/mightyohm-gc-exporter" keywords = ["prometheus", "metrics"] @@ -11,3 +13,19 @@ categories = ["api-bindings", "command-line-utilities", "visualization"] [dependencies] anyhow = "1.0" serialport = "4.1" +log = "0.4" +env_logger = "0.9" +tokio = { version = "1.17", features = ["rt-multi-thread", "macros"] } +axum = "0.5" +clap = { version = "3.1", features = ["derive"] } + +[package.metadata.deb] +extended-description = "Prometheus exporter for the MightyOhm Geiger Counter." +section = "utility" +maintainer-scripts = "debian/" +systemd-units = { enable = true } +assets = [ + ["target/release/mightyohm-gc-exporter", "usr/bin/", "755"], + ["README.md", "usr/share/doc/mightyohm-gc-exporter/README", "644"], + ["debian/default", "etc/default/mightyohm-gc-exporter", "644"], +] diff --git a/README.md b/README.md index 35264c1..90857ec 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,53 @@ A Prometheus exporter for the [MightyOhm Geiger Counter](https://mightyohm.com/blog/products/geiger-counter/). ## Build +Cargo, the Rust package manager, is used to build this project. + ### Same architecture as system -To compile it for the same architecture as the build system: +Compile it for the same architecture as the build system: ```sh cargo build --release ``` -### Cross-compile for aarch64 (recent RaspberryPi) -To cross-compile it for RaspberryPi: +### Cross-compile for amd64 (recent RaspberryPi) +Cross-compile it for the amd64 architecture: ```sh PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu cargo build --target aarch64-unknown-linux-gnu --release ``` + +## Debian +To build a package for Debian, Raspbian, and so on, +[`cargo-deb`](https://crates.io/crates/cargo-deb) can be used. + +The package comes with an automatically started and enabled systemd +service unit which can be configured via +`/etc/default/mightyohm-gc-exporter`. + +### Same architecture as system +Build a `deb` package for the same architecture as the build system: +```sh +cargo deb +``` + +### Cross-compile for amd64 (recent RaspberryPi) +Build a `deb` package for the amd64 architecture: +```sh +PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu cargo deb --target aarch64-unknown-linux-gnu +``` + +## Usage +``` +USAGE: + mightyohm-gc-exporter [OPTIONS] + +OPTIONS: + -a, --address
The IPv4 or IPv6 address where the metrics are served + [default: 127.0.0.1] + -b, --baud-rate The baudrate of the serial connection [default: 9600] + -h, --help Print help information + -p, --port The port where the metrics are served [default: 9111] + -s, --serial-port The port of the serial device, usually in '/dev/...' + [default: /dev/serial0] + -t, --timeout Timeout of the serial connection in ms [default: 1000] + -V, --version Print version information +``` diff --git a/debian/default b/debian/default new file mode 100644 index 0000000..e19cecb --- /dev/null +++ b/debian/default @@ -0,0 +1,10 @@ +ARGS="" + +# mightyohm-gc-exporter supports the following options: +# -a, --address
The IPv4 or IPv6 address where the metrics are served +# [default: 127.0.0.1] +# -b, --baud-rate The baudrate of the serial connection [default: 9600] +# -p, --port The port where the metrics are served [default: 9111] +# -s, --serial-port The port of the serial device, usually in '/dev/...' +# [default: /dev/serial0] +# -t, --timeout Timeout of the serial connection in ms [default: 1000] diff --git a/debian/service b/debian/service new file mode 100644 index 0000000..cf71344 --- /dev/null +++ b/debian/service @@ -0,0 +1,11 @@ +[Unit] +Description=MightyOhm Geiger Counter exporter + +[Service] +Group=dialout +Restart=always +EnvironmentFile=/etc/default/mightyohm-gc-exporter +ExecStart=/usr/bin/mightyohm-gc-exporter $ARGS + +[Install] +WantedBy=multi-user.target diff --git a/src/main.rs b/src/main.rs index 2b4638e..64c577f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,203 @@ -use anyhow::Result; +use anyhow::{bail, Error, Result}; +use axum::{extract::Extension, routing::get, Router, Server}; +use clap::Parser; +use log::{debug, info, trace}; use std::{ io::{BufRead, BufReader}, + net::{IpAddr, SocketAddr}, + str::FromStr, + sync::{ + atomic::{AtomicU32, AtomicUsize, Ordering}, + Arc, + }, time::Duration, }; +use tokio::{spawn, task::JoinHandle, try_join}; -fn main() -> Result<()> { - let port_name = "/dev/serial0"; - let baud_rate = 9600; +#[derive(Parser)] +#[clap( + about, + version, + author, + infer_subcommands(true), + propagate_version(true) +)] +struct Args { + /// The port of the serial device, usually in '/dev/...'. + #[clap(short, long, default_value = "/dev/serial0")] + serial_port: String, + /// The baudrate of the serial connection. + #[clap(short, long, default_value = "9600")] + baud_rate: u32, + /// Timeout of the serial connection in ms. + #[clap(short, long, default_value = "1000")] + timeout: u64, + /// The IPv4 or IPv6 address where the metrics are served. + #[clap(short, long, default_value = "127.0.0.1")] + address: IpAddr, + /// The port where the metrics are served. + #[clap(short, long, default_value = "9111")] + port: u16, +} +#[derive(Default)] +struct AtomicF32 { + storage: AtomicU32, +} + +impl AtomicF32 { + fn store(&self, value: f32, ordering: Ordering) { + let as_u32 = value.to_bits(); + self.storage.store(as_u32, ordering); + } + + fn load(&self, ordering: Ordering) -> f32 { + let as_u32 = self.storage.load(ordering); + f32::from_bits(as_u32) + } +} + +#[derive(Debug)] +enum Speed { + Slow = 0, + Fast, + Inst, +} + +impl FromStr for Speed { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s { + "SLOW" => Ok(Self::Slow), + "FAST" => Ok(Self::Fast), + "INST" => Ok(Self::Inst), + _ => bail!("Could not parse speed"), + } + } +} + +#[derive(Default)] +struct Metrics { + cps: AtomicUsize, + cpm: AtomicUsize, + radiation: AtomicF32, + mode: AtomicUsize, +} + +fn parse(input: &str) -> Result<(usize, usize, f32, Speed)> { + let input = input + .replace("CPS, ", "") + .replace(", CPM, ", " ") + .replace(", uSv/hr, ", " ") + .replace(", ", " "); + let input: Vec<&str> = input.split(' ').collect(); + + trace!( + "Parsed values: cps = {}, cpm = {}, μSv/h = {}, mode = {:?}", + input[0], + input[1], + input[2], + input[3] + ); + + Ok(( + input[0].parse::()?, + input[1].parse::()?, + input[2].parse::()?, + input[3].parse::()?, + )) +} + +#[allow(clippy::unused_async, clippy::similar_names)] +async fn listen_serial( + port_name: String, + baud_rate: u32, + timeout: u64, + metrics: Arc, +) -> Result<()> { let port = serialport::new(port_name, baud_rate) - .timeout(Duration::from_millis(1000)) + .timeout(Duration::from_millis(timeout)) .open()?; let mut port = BufReader::new(port); loop { let mut line = String::new(); port.read_line(&mut line)?; - println!("{:?}", line); + let line = line.trim(); + debug!("Reading line from serial port: {}", line); + let (cps, cpm, radiation, mode) = parse(line)?; + + metrics.cps.store(cps, Ordering::Relaxed); + metrics.cpm.store(cpm, Ordering::Relaxed); + metrics.radiation.store(radiation, Ordering::Relaxed); + metrics.mode.store(mode as usize, Ordering::Relaxed); } } + +#[allow(clippy::unused_async)] +async fn get_metrics(Extension(metrics): Extension>) -> String { + format!( + r"# HELP mightyohm_gc_cps Counts per second. +# TYPE mightyohm_gc_cps gauge +mightyohm_gc_cps {} +# HELP mightyohm_gc_cpm Counts per minute. +# TYPE mightyohm_gc_cpm gauge +mightyohm_gc_cpm {} +# HELP mightyohm_gc_radiation Ionizing Radiation in μSv/h. +# TYPE mightyohm_gc_radiation gauge +mightyohm_gc_radiation {} +# HELP mightyohm_gc_mode Data acquisition mode (0 = Slow, 1 = Fast, 2 = Inst). +# TYPE mightyohm_gc_mode gauge +mightyohm_gc_mode {} +", + metrics.cps.load(Ordering::Relaxed), + metrics.cpm.load(Ordering::Relaxed), + metrics.radiation.load(Ordering::Relaxed), + metrics.mode.load(Ordering::Relaxed) + ) +} + +async fn listen_http(address: IpAddr, port: u16, metrics: Arc) -> Result<()> { + let app = Router::new() + .route("/metrics", get(get_metrics)) + .layer(Extension(metrics)); + let addr = SocketAddr::from((address, port)); + info!("Listening on {}:{}", address, port); + + Ok(Server::bind(&addr).serve(app.into_make_service()).await?) +} + +async fn flatten(handle: JoinHandle>) -> Result +where + T: Send, +{ + match handle.await { + Ok(Ok(result)) => Ok(result), + Ok(Err(err)) => bail!(err), + Err(err) => bail!(err), + } +} + +#[tokio::main] +async fn main() -> Result<()> { + env_logger::init(); + let args = Args::parse(); + let metrics = Arc::new(Metrics::default()); + + try_join!( + flatten(spawn(listen_serial( + args.serial_port, + args.baud_rate, + args.timeout, + Arc::clone(&metrics) + ))), + flatten(spawn(listen_http( + args.address, + args.port, + Arc::clone(&metrics) + ))) + )?; + + Ok(()) +}