mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-08-17 16:34:54 -05:00
feat: opentelemetry metrics exporter (#776)
* feat: opentelemetry metrics exporter * chore: run first export after the period has passed * feat: include gpu name in attributes * chore: fix typo * chore: update docs * fix: disable coverage action
This commit is contained in:
+22
-21
@@ -59,30 +59,31 @@ jobs:
|
||||
- name: Run cargo audit
|
||||
run: cargo audit
|
||||
|
||||
coverage:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ github.event_name == 'push' || !github.event.pull_request.draft }}
|
||||
steps:
|
||||
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2
|
||||
- uses: ./.github/actions/setup-environment
|
||||
# Disabled temporarily due to failing dependency build
|
||||
# coverage:
|
||||
# runs-on: ubuntu-24.04
|
||||
# if: ${{ github.event_name == 'push' || !github.event.pull_request.draft }}
|
||||
# steps:
|
||||
# - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2
|
||||
# - uses: ./.github/actions/setup-environment
|
||||
|
||||
- name: Install cargo-llvm-cov from crates.io
|
||||
uses: baptiste0928/cargo-install@v3
|
||||
with:
|
||||
crate: cargo-llvm-cov
|
||||
version: '0.6.18'
|
||||
# - name: Install cargo-llvm-cov from crates.io
|
||||
# uses: baptiste0928/cargo-install@v3
|
||||
# with:
|
||||
# crate: cargo-llvm-cov
|
||||
# version: '0.6.18'
|
||||
|
||||
- name: Generate coverage report
|
||||
run: cargo llvm-cov --no-fail-fast --include-ffi --workspace --lcov --output-path lcov.info
|
||||
# - name: Generate coverage report
|
||||
# run: cargo llvm-cov --no-fail-fast --include-ffi --workspace --lcov --output-path lcov.info
|
||||
|
||||
- name: Upload to Codecov
|
||||
uses: codecov/codecov-action@v5.5.1
|
||||
continue-on-error: true
|
||||
with:
|
||||
files: lcov.info
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
# - name: Upload to Codecov
|
||||
# uses: codecov/codecov-action@v5.5.1
|
||||
# continue-on-error: true
|
||||
# with:
|
||||
# files: lcov.info
|
||||
# fail_ci_if_error: true
|
||||
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||
# verbose: true
|
||||
|
||||
test-miri:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
Generated
+444
@@ -428,6 +428,35 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"time",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie_store"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fc4bff745c9b4c7fb1e97b25d13153da2bc7796260141df62378998d070207f"
|
||||
dependencies = [
|
||||
"cookie",
|
||||
"document-features",
|
||||
"idna",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"time",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@@ -602,6 +631,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
|
||||
dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "easy_fuser"
|
||||
version = "0.4.2"
|
||||
@@ -746,6 +784,16 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent"
|
||||
version = "0.17.0"
|
||||
@@ -809,6 +857,15 @@ version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fragile"
|
||||
version = "2.0.1"
|
||||
@@ -1261,6 +1318,23 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||
|
||||
[[package]]
|
||||
name = "i18n-config"
|
||||
version = "0.4.8"
|
||||
@@ -1352,12 +1426,119 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"potential_utf",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_core"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"smallvec",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_locale_core",
|
||||
"icu_properties_data",
|
||||
"icu_provider",
|
||||
"potential_utf",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locale_core",
|
||||
"stable_deref_trait",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
|
||||
dependencies = [
|
||||
"idna_adapter",
|
||||
"smallvec",
|
||||
"utf8_iter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna_adapter"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
|
||||
dependencies = [
|
||||
"icu_normalizer",
|
||||
"icu_properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.11.1"
|
||||
@@ -1554,6 +1735,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"ureq",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
@@ -1722,6 +1904,18 @@ version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.13"
|
||||
@@ -1775,6 +1969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2043,6 +2238,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
@@ -2089,6 +2290,15 @@ dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
|
||||
dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
@@ -2260,6 +2470,20 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom 0.2.16",
|
||||
"libc",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rle-decode-fast"
|
||||
version = "1.0.3"
|
||||
@@ -2334,6 +2558,50 @@ dependencies = [
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
|
||||
dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
@@ -2510,6 +2778,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.7.0"
|
||||
@@ -2547,6 +2821,12 @@ dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
@@ -2559,6 +2839,12 @@ version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
@@ -2570,6 +2856,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-locale"
|
||||
version = "0.3.2"
|
||||
@@ -2958,6 +3255,69 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39abd59bf32521c7f2301b52d05a6a2c975b6003521cbd0c6dc1582f0a22104"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "3.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"cookie_store",
|
||||
"flate2",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"ureq-proto",
|
||||
"utf-8",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ureq-proto"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf8_iter"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
@@ -3097,6 +3457,15 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@@ -3468,6 +3837,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.5.1"
|
||||
@@ -3484,6 +3859,30 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
"yoke-derive",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "5.11.0"
|
||||
@@ -3564,6 +3963,38 @@ name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||
dependencies = [
|
||||
"zerofrom-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom-derive"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
@@ -3571,7 +4002,20 @@ version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
|
||||
dependencies = [
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec-derive"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -38,6 +38,7 @@ system.
|
||||
- GPU undervolting (via voltage offset on AMD, [indirectly](https://github.com/ilya-zlobintsev/LACT/wiki/Frequently-asked-questions#how-to-undervolt-nvidia-gpus) on Nvidia)
|
||||
- #### Settings profiles
|
||||
- Automatic profile activation based on running processes or gamemode status
|
||||
- #### [OpenTelemetry metrics exporter](./docs/EXPORTER.md)
|
||||
|
||||
GPU configuration is handled by a system service that does not depend on a graphical session (Wayland/X11).
|
||||
|
||||
@@ -53,6 +54,7 @@ The service can also be used standalone with a config file, for example in headl
|
||||
- [API](./docs/API.md)
|
||||
- [Power profiles daemon note](#power-profiles-daemon-note)
|
||||
- [Recovery from a bad overclock](https://github.com/ilya-zlobintsev/LACT/wiki/Recovering-from-a-bad-overclock)
|
||||
- [Metrics exporter](./docs/EXPORTER.md)
|
||||
- [Contribute translations](#localization)
|
||||
- [Support the project](#support-the-project)
|
||||
|
||||
|
||||
@@ -31,6 +31,14 @@ daemon:
|
||||
# By default TCP access is disabled, and only a unix socket is present.
|
||||
# Specifying this option enables the TCP listener.
|
||||
tcp_listen_address: 127.0.0.1:12853
|
||||
# Opentelemetry metrics exporter configuration
|
||||
# Omitted by default, meaning the exporter is disabled.
|
||||
metrics:
|
||||
# Opentelemetry collector URL. The following example is for local Prometheus.
|
||||
collector_address: 'http://localhost:9090/api/v1/otlp/v1/metrics'
|
||||
# Interval in seconds for how often to collect the metrics.
|
||||
# Defaults to 30.
|
||||
interval: 30
|
||||
|
||||
# Period in seconds for how long settings should wait to be confirmed.
|
||||
# Most GPU setting change commands require a confirmation command to be used
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# OpenTelemetry exporter
|
||||
|
||||
The LACT daemon supports exporting GPU metrics using the standard [OpenTelemetry metrics API](https://opentelemetry.io/docs/specs/otel/metrics/).
|
||||
In particular, it uses the [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/#otlphttp) protocol with a JSON payload.
|
||||
|
||||
To use this functionality, you need an OpenTelemetry-compatible metrics collector such as Prometheus [with OTLP support enabled](https://prometheus.io/docs/guides/opentelemetry/).
|
||||
|
||||
After this, you need to set the collector URL in `/etc/lact/config.yaml`. For example:
|
||||
```yaml
|
||||
daemon:
|
||||
metrics:
|
||||
# This example is a local Prometheus URL. Other collectors might simply use `/v1/metrics` as the path.
|
||||
collector_address: 'http://localhost:9090/api/v1/otlp/v1/metrics'
|
||||
# Metrics collection interval in seconds. Not necessary to set, defaults to 30 seconds.
|
||||
interval: 30
|
||||
```
|
||||
|
||||
Restart the daemon after changing the config.
|
||||
|
||||
The following metrics are currently supported :
|
||||
- lact_gpu_usage
|
||||
- lact_gpu_power_usage
|
||||
- lact_gpu_power_usage_cap
|
||||
- lact_gpu_temperature
|
||||
- lact_gpu_clockspeed
|
||||
- lact_gpu_voltage
|
||||
- lact_gpu_fan_speed
|
||||
- lact_gpu_fan_speed_max
|
||||
- lact_gpu_fan_percent
|
||||
- lact_gpu_vram_used
|
||||
- lact_gpu_vram_total
|
||||
|
||||
|
||||
Note: this is the source metric name, collectors might alter it for queries. For example, Prometheus adds a unit suffix, e.g. `lact_gpu_power_usage` -> `lact_gpu_power_usage_watts`
|
||||
|
||||

|
||||
@@ -608,6 +608,32 @@
|
||||
"dest": "cargo/vendor/console-0.15.11",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/cookie/cookie-0.18.1.crate",
|
||||
"sha256": "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747",
|
||||
"dest": "cargo/vendor/cookie-0.18.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/cookie-0.18.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/cookie_store/cookie_store-0.22.0.crate",
|
||||
"sha256": "3fc4bff745c9b4c7fb1e97b25d13153da2bc7796260141df62378998d070207f",
|
||||
"dest": "cargo/vendor/cookie_store-0.22.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"3fc4bff745c9b4c7fb1e97b25d13153da2bc7796260141df62378998d070207f\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/cookie_store-0.22.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -842,6 +868,19 @@
|
||||
"dest": "cargo/vendor/dlopen2_derive-0.4.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/document-features/document-features-0.2.11.crate",
|
||||
"sha256": "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d",
|
||||
"dest": "cargo/vendor/document-features-0.2.11"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/document-features-0.2.11",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1050,6 +1089,19 @@
|
||||
"dest": "cargo/vendor/find-msvc-tools-0.1.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/flate2/flate2-1.1.4.crate",
|
||||
"sha256": "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9",
|
||||
"dest": "cargo/vendor/flate2-1.1.4"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/flate2-1.1.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1128,6 +1180,19 @@
|
||||
"dest": "cargo/vendor/fnv-1.0.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/form_urlencoded/form_urlencoded-1.2.2.crate",
|
||||
"sha256": "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf",
|
||||
"dest": "cargo/vendor/form_urlencoded-1.2.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/form_urlencoded-1.2.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1635,6 +1700,32 @@
|
||||
"dest": "cargo/vendor/hex-0.4.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/http/http-1.3.1.crate",
|
||||
"sha256": "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565",
|
||||
"dest": "cargo/vendor/http-1.3.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/http-1.3.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/httparse/httparse-1.10.1.crate",
|
||||
"sha256": "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87",
|
||||
"dest": "cargo/vendor/httparse-1.10.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/httparse-1.10.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1713,6 +1804,97 @@
|
||||
"dest": "cargo/vendor/iana-time-zone-haiku-0.1.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_collections/icu_collections-2.0.0.crate",
|
||||
"sha256": "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47",
|
||||
"dest": "cargo/vendor/icu_collections-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_collections-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_locale_core/icu_locale_core-2.0.0.crate",
|
||||
"sha256": "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a",
|
||||
"dest": "cargo/vendor/icu_locale_core-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_locale_core-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_normalizer/icu_normalizer-2.0.0.crate",
|
||||
"sha256": "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979",
|
||||
"dest": "cargo/vendor/icu_normalizer-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_normalizer-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_normalizer_data/icu_normalizer_data-2.0.0.crate",
|
||||
"sha256": "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3",
|
||||
"dest": "cargo/vendor/icu_normalizer_data-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_normalizer_data-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_properties/icu_properties-2.0.1.crate",
|
||||
"sha256": "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b",
|
||||
"dest": "cargo/vendor/icu_properties-2.0.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_properties-2.0.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_properties_data/icu_properties_data-2.0.1.crate",
|
||||
"sha256": "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632",
|
||||
"dest": "cargo/vendor/icu_properties_data-2.0.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_properties_data-2.0.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_provider/icu_provider-2.0.0.crate",
|
||||
"sha256": "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af",
|
||||
"dest": "cargo/vendor/icu_provider-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_provider-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1726,6 +1908,32 @@
|
||||
"dest": "cargo/vendor/ident_case-1.0.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/idna/idna-1.1.0.crate",
|
||||
"sha256": "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de",
|
||||
"dest": "cargo/vendor/idna-1.1.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/idna-1.1.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/idna_adapter/idna_adapter-1.2.1.crate",
|
||||
"sha256": "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344",
|
||||
"dest": "cargo/vendor/idna_adapter-1.2.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/idna_adapter-1.2.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2038,6 +2246,32 @@
|
||||
"dest": "cargo/vendor/linux-raw-sys-0.11.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/litemap/litemap-0.8.0.crate",
|
||||
"sha256": "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956",
|
||||
"dest": "cargo/vendor/litemap-0.8.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/litemap-0.8.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/litrs/litrs-0.4.2.crate",
|
||||
"sha256": "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed",
|
||||
"dest": "cargo/vendor/litrs-0.4.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/litrs-0.4.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2480,6 +2714,19 @@
|
||||
"dest": "cargo/vendor/pciid-parser-0.8.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/percent-encoding/percent-encoding-2.3.2.crate",
|
||||
"sha256": "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220",
|
||||
"dest": "cargo/vendor/percent-encoding-2.3.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/percent-encoding-2.3.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2558,6 +2805,19 @@
|
||||
"dest": "cargo/vendor/plotters-cairo-0.8.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/potential_utf/potential_utf-0.1.3.crate",
|
||||
"sha256": "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a",
|
||||
"dest": "cargo/vendor/potential_utf-0.1.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/potential_utf-0.1.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2792,6 +3052,19 @@
|
||||
"dest": "cargo/vendor/relm4-macros-0.10.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/ring/ring-0.17.14.crate",
|
||||
"sha256": "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7",
|
||||
"dest": "cargo/vendor/ring-0.17.14"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/ring-0.17.14",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2896,6 +3169,58 @@
|
||||
"dest": "cargo/vendor/rustix-1.1.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rustls/rustls-0.23.32.crate",
|
||||
"sha256": "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40",
|
||||
"dest": "cargo/vendor/rustls-0.23.32"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rustls-0.23.32",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rustls-pemfile/rustls-pemfile-2.2.0.crate",
|
||||
"sha256": "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50",
|
||||
"dest": "cargo/vendor/rustls-pemfile-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rustls-pemfile-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rustls-pki-types/rustls-pki-types-1.12.0.crate",
|
||||
"sha256": "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79",
|
||||
"dest": "cargo/vendor/rustls-pki-types-1.12.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rustls-pki-types-1.12.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rustls-webpki/rustls-webpki-0.103.7.crate",
|
||||
"sha256": "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf",
|
||||
"dest": "cargo/vendor/rustls-webpki-0.103.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rustls-webpki-0.103.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3143,6 +3468,19 @@
|
||||
"dest": "cargo/vendor/signal-hook-registry-1.4.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/simd-adler32/simd-adler32-0.3.7.crate",
|
||||
"sha256": "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe",
|
||||
"dest": "cargo/vendor/simd-adler32-0.3.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/simd-adler32-0.3.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3208,6 +3546,19 @@
|
||||
"dest": "cargo/vendor/spin-0.9.8",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/stable_deref_trait/stable_deref_trait-1.2.0.crate",
|
||||
"sha256": "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3",
|
||||
"dest": "cargo/vendor/stable_deref_trait-1.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/stable_deref_trait-1.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3234,6 +3585,19 @@
|
||||
"dest": "cargo/vendor/strsim-0.11.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/subtle/subtle-2.6.1.crate",
|
||||
"sha256": "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292",
|
||||
"dest": "cargo/vendor/subtle-2.6.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/subtle-2.6.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3247,6 +3611,19 @@
|
||||
"dest": "cargo/vendor/syn-2.0.106",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/synstructure/synstructure-0.13.2.crate",
|
||||
"sha256": "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2",
|
||||
"dest": "cargo/vendor/synstructure-0.13.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/synstructure-0.13.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3728,6 +4105,84 @@
|
||||
"dest": "cargo/vendor/unsafe-libyaml-norway-0.2.15",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/untrusted/untrusted-0.9.0.crate",
|
||||
"sha256": "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1",
|
||||
"dest": "cargo/vendor/untrusted-0.9.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/untrusted-0.9.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/ureq/ureq-3.1.2.crate",
|
||||
"sha256": "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537",
|
||||
"dest": "cargo/vendor/ureq-3.1.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/ureq-3.1.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/ureq-proto/ureq-proto-0.5.2.crate",
|
||||
"sha256": "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2",
|
||||
"dest": "cargo/vendor/ureq-proto-0.5.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/ureq-proto-0.5.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/url/url-2.5.7.crate",
|
||||
"sha256": "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b",
|
||||
"dest": "cargo/vendor/url-2.5.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/url-2.5.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/utf-8/utf-8-0.7.6.crate",
|
||||
"sha256": "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9",
|
||||
"dest": "cargo/vendor/utf-8-0.7.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/utf-8-0.7.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/utf8_iter/utf8_iter-1.0.4.crate",
|
||||
"sha256": "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be",
|
||||
"dest": "cargo/vendor/utf8_iter-1.0.4"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/utf8_iter-1.0.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3923,6 +4378,19 @@
|
||||
"dest": "cargo/vendor/web-sys-0.3.78",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/webpki-roots/webpki-roots-1.0.3.crate",
|
||||
"sha256": "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8",
|
||||
"dest": "cargo/vendor/webpki-roots-1.0.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/webpki-roots-1.0.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -4495,6 +4963,19 @@
|
||||
"dest": "cargo/vendor/wrapcenum-derive-0.4.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/writeable/writeable-0.6.1.crate",
|
||||
"sha256": "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb",
|
||||
"dest": "cargo/vendor/writeable-0.6.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/writeable-0.6.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -4521,6 +5002,32 @@
|
||||
"dest": "cargo/vendor/yansi-1.0.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/yoke/yoke-0.8.0.crate",
|
||||
"sha256": "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc",
|
||||
"dest": "cargo/vendor/yoke-0.8.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/yoke-0.8.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/yoke-derive/yoke-derive-0.8.0.crate",
|
||||
"sha256": "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6",
|
||||
"dest": "cargo/vendor/yoke-derive-0.8.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/yoke-derive-0.8.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -4599,6 +5106,45 @@
|
||||
"dest": "cargo/vendor/zerofrom-0.1.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerofrom-derive/zerofrom-derive-0.1.6.crate",
|
||||
"sha256": "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502",
|
||||
"dest": "cargo/vendor/zerofrom-derive-0.1.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerofrom-derive-0.1.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zeroize/zeroize-1.8.2.crate",
|
||||
"sha256": "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0",
|
||||
"dest": "cargo/vendor/zeroize-1.8.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zeroize-1.8.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerotrie/zerotrie-0.2.2.crate",
|
||||
"sha256": "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595",
|
||||
"dest": "cargo/vendor/zerotrie-0.2.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerotrie-0.2.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -4612,6 +5158,19 @@
|
||||
"dest": "cargo/vendor/zerovec-0.11.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerovec-derive/zerovec-derive-0.11.1.crate",
|
||||
"sha256": "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f",
|
||||
"dest": "cargo/vendor/zerovec-derive-0.11.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerovec-derive-0.11.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
|
||||
@@ -50,6 +50,8 @@ cl3 = { git = "https://github.com/kenba/cl3", branch = "develop", features = [
|
||||
"static",
|
||||
] }
|
||||
|
||||
ureq = { version = "3.1.2", features = ["json", "rustls"] }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = { workspace = true }
|
||||
insta = { version = "1.41.1", features = ["json", "yaml"] }
|
||||
|
||||
@@ -68,6 +68,7 @@ pub struct Daemon {
|
||||
pub disable_clocks_cleanup: bool,
|
||||
pub disable_nvapi: Option<bool>,
|
||||
pub tcp_listen_address: Option<String>,
|
||||
pub metrics: Option<Metrics>,
|
||||
}
|
||||
|
||||
impl Default for Daemon {
|
||||
@@ -88,6 +89,7 @@ impl Default for Daemon {
|
||||
disable_clocks_cleanup: false,
|
||||
tcp_listen_address: None,
|
||||
disable_nvapi: None,
|
||||
metrics: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,6 +280,17 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Metrics {
|
||||
pub collector_address: String,
|
||||
#[serde(default = "default_metrics_interval")]
|
||||
pub interval: u64,
|
||||
}
|
||||
|
||||
fn default_metrics_interval() -> u64 {
|
||||
30
|
||||
}
|
||||
|
||||
pub fn start_watcher(config_last_saved: Rc<Cell<Instant>>) -> mpsc::UnboundedReceiver<Config> {
|
||||
let (config_tx, config_rx) = mpsc::unbounded_channel();
|
||||
let (event_tx, mut event_rx) = mpsc::channel(64);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod gpu_controller;
|
||||
pub mod handler;
|
||||
mod metrics;
|
||||
mod opencl;
|
||||
mod profiles;
|
||||
mod vulkan;
|
||||
@@ -15,7 +16,7 @@ use tokio::{
|
||||
io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt, BufReader},
|
||||
net::{TcpListener, UnixListener},
|
||||
};
|
||||
use tracing::{error, info, instrument, trace};
|
||||
use tracing::{debug, error, info, instrument, trace};
|
||||
|
||||
pub struct Server {
|
||||
pub handler: Handler,
|
||||
@@ -49,6 +50,12 @@ impl Server {
|
||||
socket::cleanup();
|
||||
})?;
|
||||
|
||||
if let Some(metrics_config) = handler.config.read().await.daemon.metrics.clone() {
|
||||
metrics::setup(handler.clone(), metrics_config);
|
||||
} else {
|
||||
debug!("metrics exporter disabled");
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
handler,
|
||||
unix_listener,
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
mod schema;
|
||||
|
||||
use crate::{
|
||||
config,
|
||||
server::{handler::Handler, metrics::schema::NumberValue},
|
||||
};
|
||||
use chrono::Local;
|
||||
use indexmap::IndexMap;
|
||||
use lact_schema::DeviceStats;
|
||||
use schema::{
|
||||
Attribute, Gauge, GaugeDataPoint, Metric, MetricsPayload, Resource, ResourceMetric, Scope,
|
||||
ScopeMetric, Value,
|
||||
};
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
pub fn setup(handler: Handler, config: config::Metrics) {
|
||||
info!(
|
||||
"exporting metrics to {} every {} seconds",
|
||||
config.collector_address, config.interval
|
||||
);
|
||||
|
||||
let interval = Duration::from_secs(config.interval);
|
||||
|
||||
tokio::task::spawn_local(async move {
|
||||
let client = ureq::config::Config::builder()
|
||||
.http_status_as_error(false)
|
||||
.build()
|
||||
.new_agent();
|
||||
|
||||
loop {
|
||||
sleep(interval).await;
|
||||
|
||||
match get_stats(&handler).await {
|
||||
Ok(devices) => {
|
||||
debug!("collecting metrics for {} devices", devices.len());
|
||||
let mut metrics = Vec::with_capacity(10);
|
||||
let timestamp = Local::now()
|
||||
.timestamp_nanos_opt()
|
||||
.expect("Invalid timestamp")
|
||||
.to_string();
|
||||
|
||||
for (gpu_id, (gpu_name, stats)) in &devices {
|
||||
collect_metrics(gpu_id, gpu_name, stats, &mut metrics, ×tamp);
|
||||
}
|
||||
|
||||
let metric_count = metrics.len();
|
||||
|
||||
let request = MetricsPayload {
|
||||
resource_metrics: vec![ResourceMetric {
|
||||
resource: Resource {
|
||||
attributes: vec![Attribute {
|
||||
key: "service.name",
|
||||
value: Value::String("LACT"),
|
||||
}],
|
||||
},
|
||||
scope_metrics: vec![ScopeMetric {
|
||||
scope: Scope {
|
||||
name: "LACT".to_owned(),
|
||||
version: env!("CARGO_PKG_VERSION").to_owned(),
|
||||
attributes: vec![],
|
||||
},
|
||||
metrics,
|
||||
}],
|
||||
}],
|
||||
};
|
||||
|
||||
let url = config.collector_address.clone();
|
||||
let client = client.clone();
|
||||
let payload =
|
||||
serde_json::to_string(&request).expect("Could not serialize request body");
|
||||
|
||||
let response = tokio::task::spawn_blocking(move || {
|
||||
client
|
||||
.post(url)
|
||||
.content_type("application/json")
|
||||
.send(payload)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
match response {
|
||||
Ok(response) => {
|
||||
if response.status().is_success() {
|
||||
debug!("{metric_count} metrics were uploaded");
|
||||
} else {
|
||||
let status = response.status();
|
||||
let body = response
|
||||
.into_body()
|
||||
.read_to_string()
|
||||
.unwrap_or_else(|_| "<Invalid string>".to_owned());
|
||||
debug!("could not submit metrics, status code {status}: {body}");
|
||||
}
|
||||
}
|
||||
Err(err) => error!("could not submit metrics: {err}"),
|
||||
}
|
||||
}
|
||||
Err(err) => error!("could not fetch metrics: {err:#}"),
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(
|
||||
clippy::cast_possible_wrap,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::too_many_lines
|
||||
)]
|
||||
fn collect_metrics<'a>(
|
||||
gpu_id: &'a str,
|
||||
gpu_name: &'a str,
|
||||
stats: &'a DeviceStats,
|
||||
metrics: &mut Vec<Metric<'a>>,
|
||||
timestamp: &'a str,
|
||||
) {
|
||||
let base_attrs = vec![
|
||||
Attribute {
|
||||
key: "gpu_id",
|
||||
value: Value::String(gpu_id),
|
||||
},
|
||||
Attribute {
|
||||
key: "gpu_name",
|
||||
value: Value::String(gpu_name),
|
||||
},
|
||||
];
|
||||
|
||||
if let Some(usage) = stats.busy_percent {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_usage",
|
||||
i64::from(usage).into(),
|
||||
"%",
|
||||
"Current GPU usage",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(power) = stats.power.current.or(stats.power.average) {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_power_usage",
|
||||
power.into(),
|
||||
"W",
|
||||
"Current power usage",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(power_cap) = stats.power.cap_current {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_power_usage_cap",
|
||||
power_cap.into(),
|
||||
"W",
|
||||
"Maximum configured power usage",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
for (key, temp) in &stats.temps {
|
||||
let mut temp_attrs = base_attrs.clone();
|
||||
temp_attrs.push(Attribute {
|
||||
key: "sensor",
|
||||
value: Value::String(key),
|
||||
});
|
||||
|
||||
if let Some(current) = temp.current {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_temperature",
|
||||
f64::from(current).into(),
|
||||
"Cel",
|
||||
"Current temperature",
|
||||
timestamp,
|
||||
temp_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(crit) = temp.crit {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_temperature_crit",
|
||||
f64::from(crit).into(),
|
||||
"Cel",
|
||||
"Critical temperature",
|
||||
timestamp,
|
||||
temp_attrs.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(gpu_clock) = stats.clockspeed.gpu_clockspeed {
|
||||
let mut attrs = base_attrs.clone();
|
||||
attrs.push(Attribute {
|
||||
key: "clockspeed_type",
|
||||
value: Value::String("gpu_current"),
|
||||
});
|
||||
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_clockspeed",
|
||||
(gpu_clock as i64 * 1000 * 1000).into(),
|
||||
"Hz",
|
||||
"Current clockspeed",
|
||||
timestamp,
|
||||
attrs,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(gpu_target_clock) = stats.clockspeed.current_gfxclk {
|
||||
let mut attrs = base_attrs.clone();
|
||||
attrs.push(Attribute {
|
||||
key: "clockspeed_type",
|
||||
value: Value::String("gpu_target"),
|
||||
});
|
||||
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_clockspeed",
|
||||
(gpu_target_clock as i64 * 1000 * 1000).into(),
|
||||
"Hz",
|
||||
"Current clockspeed",
|
||||
timestamp,
|
||||
attrs,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(vram_clock) = stats.clockspeed.vram_clockspeed {
|
||||
let mut attrs = base_attrs.clone();
|
||||
attrs.push(Attribute {
|
||||
key: "clockspeed_type",
|
||||
value: Value::String("memory"),
|
||||
});
|
||||
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_clockspeed",
|
||||
(vram_clock as i64 * 1000 * 1000).into(),
|
||||
"Hz",
|
||||
"Current clockspeed",
|
||||
timestamp,
|
||||
attrs,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(gpu_voltage) = stats.voltage.gpu {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_voltage",
|
||||
(gpu_voltage as f64 * 1000.0).into(),
|
||||
"V",
|
||||
"Current voltage",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(fan_rpm) = stats.fan.speed_current {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_fan_speed",
|
||||
i64::from(fan_rpm).into(),
|
||||
"RPM",
|
||||
"Current fan speed (RPM)",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(fan_rpm_max) = stats.fan.speed_max {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_fan_speed_max",
|
||||
i64::from(fan_rpm_max).into(),
|
||||
"RPM",
|
||||
"Maximum fan speed (RPM)",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(fan_pwm) = stats.fan.pwm_current {
|
||||
let percent = f64::from(fan_pwm) / f64::from(u8::MAX) * 100.0;
|
||||
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_fan_percent",
|
||||
percent.into(),
|
||||
"%",
|
||||
"Current fan speed (%)",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(vram_used) = stats.vram.used {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_vram_used",
|
||||
(vram_used as i64).into(),
|
||||
"By",
|
||||
"Current VRAM usage",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(vram_total) = stats.vram.total {
|
||||
metrics.push(make_metric(
|
||||
"lact_gpu_vram_total",
|
||||
(vram_total as i64).into(),
|
||||
"By",
|
||||
"Total VRAM available",
|
||||
timestamp,
|
||||
base_attrs.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn make_metric<'a>(
|
||||
name: &'static str,
|
||||
value: NumberValue,
|
||||
unit: &'static str,
|
||||
description: &'static str,
|
||||
timestamp: &'a str,
|
||||
attrs: Vec<Attribute<'a>>,
|
||||
) -> Metric<'a> {
|
||||
Metric {
|
||||
name,
|
||||
unit,
|
||||
description,
|
||||
gauge: Gauge {
|
||||
data_points: vec![GaugeDataPoint {
|
||||
value,
|
||||
time_unix_nano: timestamp,
|
||||
attributes: attrs,
|
||||
}],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_stats(handler: &Handler) -> anyhow::Result<IndexMap<String, (String, DeviceStats)>> {
|
||||
let mut devices = IndexMap::new();
|
||||
|
||||
let device_list = handler.list_devices().await;
|
||||
|
||||
for device in device_list {
|
||||
let stats = handler.get_gpu_stats(&device.id).await?;
|
||||
|
||||
devices.insert(device.id, (device.name.unwrap_or_default(), stats));
|
||||
}
|
||||
|
||||
Ok(devices)
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MetricsPayload<'a> {
|
||||
pub resource_metrics: Vec<ResourceMetric<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ResourceMetric<'a> {
|
||||
pub resource: Resource<'a>,
|
||||
pub scope_metrics: Vec<ScopeMetric<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Resource<'a> {
|
||||
pub attributes: Vec<Attribute<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ScopeMetric<'a> {
|
||||
pub scope: Scope<'a>,
|
||||
pub metrics: Vec<Metric<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Scope<'a> {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub attributes: Vec<Attribute<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct Attribute<'a> {
|
||||
pub key: &'static str,
|
||||
pub value: Value<'a>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Metric<'a> {
|
||||
pub name: &'static str,
|
||||
pub unit: &'static str,
|
||||
pub description: &'static str,
|
||||
pub gauge: Gauge<'a>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Gauge<'a> {
|
||||
pub data_points: Vec<GaugeDataPoint<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GaugeDataPoint<'a> {
|
||||
#[serde(flatten)]
|
||||
pub value: NumberValue,
|
||||
pub time_unix_nano: &'a str,
|
||||
pub attributes: Vec<Attribute<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub enum NumberValue {
|
||||
#[serde(rename = "asDouble")]
|
||||
Float(f64),
|
||||
#[serde(rename = "asInt")]
|
||||
Int(i64),
|
||||
}
|
||||
|
||||
impl From<f64> for NumberValue {
|
||||
fn from(value: f64) -> Self {
|
||||
Self::Float(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for NumberValue {
|
||||
fn from(value: i64) -> Self {
|
||||
Self::Int(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub enum Value<'a> {
|
||||
#[serde(rename = "stringValue")]
|
||||
String(&'a str),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_value() {
|
||||
let value = Value::String("asd");
|
||||
let expected_result = r#"{"stringValue":"asd"}"#;
|
||||
assert_eq!(expected_result, serde_json::to_string(&value).unwrap());
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,9 @@ daemon:
|
||||
disable_clocks_cleanup: false
|
||||
disable_nvapi: false
|
||||
tcp_listen_address: "127.0.0.1:12853"
|
||||
metrics:
|
||||
collector_address: "http://localhost:9090/api/v1/otlp/v1/metrics"
|
||||
interval: 30
|
||||
apply_settings_timer: 5
|
||||
gpus:
|
||||
"1002:687F-1043:0555-0000:0b:00.0":
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Reference in New Issue
Block a user