├── .github └── workflows │ ├── ci.yaml │ └── package-extension.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── MIT-LICENSE.txt ├── README.md ├── bin └── release-tools ├── control ├── pg_stat_sysinfo.control └── src ├── cache_worker.rs ├── collector.rs ├── crate_info.rs ├── init.rs ├── lib.rs ├── settings.rs └── shmem_ring_buffer.rs /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md 2 | 3 | on: [push, pull_request] 4 | 5 | name: Continuous Integration 6 | 7 | jobs: 8 | check: 9 | name: Check 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions-rs/toolchain@v1 14 | with: 15 | profile: minimal 16 | toolchain: stable 17 | override: true 18 | - name: Install dependencies 19 | run: | 20 | export DEBIAN_FRONTEND=noninteractive 21 | sudo apt install -y \ 22 | postgresql-server-dev-"$(bin/release-tools pg-major-version)" 23 | - name: Cache ~/.cargo 24 | uses: actions/cache@v3 25 | with: 26 | path: ~/.cargo 27 | key: ${{ runner.os }}-rust-dot-cargo-${{ hashFiles('Cargo.lock') }} 28 | - name: Setup tools in ~/.cargo 29 | run: | 30 | bin/release-tools initialize-cargo-pgrx 31 | - name: Initialize PGRX in ~/.pgrx 32 | run: | 33 | bin/release-tools initialize-pgrx-with-local-pg 34 | - uses: actions-rs/cargo@v1 35 | with: 36 | command: check 37 | 38 | test: 39 | name: Test Suite 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v2 43 | - uses: actions-rs/toolchain@v1 44 | with: 45 | profile: minimal 46 | toolchain: stable 47 | override: true 48 | - name: Install dependencies 49 | run: | 50 | export DEBIAN_FRONTEND=noninteractive 51 | sudo apt install -y \ 52 | postgresql-server-dev-"$(bin/release-tools pg-major-version)" 53 | - name: Cache ~/.cargo 54 | uses: actions/cache@v3 55 | with: 56 | path: ~/.cargo 57 | key: ${{ runner.os }}-rust-dot-cargo-${{ hashFiles('Cargo.lock') }} 58 | - name: Setup tools in ~/.cargo 59 | run: | 60 | bin/release-tools initialize-cargo-pgrx 61 | - name: Initialize PGRX in ~/.pgrx 62 | run: | 63 | bin/release-tools initialize-pgrx-with-local-pg 64 | - uses: actions-rs/cargo@v1 65 | with: 66 | command: test 67 | 68 | fmt: 69 | name: Rustfmt 70 | runs-on: ubuntu-latest 71 | steps: 72 | - uses: actions/checkout@v2 73 | - uses: actions-rs/toolchain@v1 74 | with: 75 | profile: minimal 76 | toolchain: stable 77 | override: true 78 | - run: rustup component add rustfmt 79 | - uses: actions-rs/cargo@v1 80 | with: 81 | command: fmt 82 | args: --all -- --check 83 | 84 | clippy: 85 | name: Clippy 86 | runs-on: ubuntu-latest 87 | steps: 88 | - uses: actions/checkout@v2 89 | - uses: actions-rs/toolchain@v1 90 | with: 91 | profile: minimal 92 | toolchain: stable 93 | override: true 94 | - run: rustup component add clippy 95 | - name: Install dependencies 96 | run: | 97 | export DEBIAN_FRONTEND=noninteractive 98 | sudo apt install -y \ 99 | postgresql-server-dev-"$(bin/release-tools pg-major-version)" 100 | - name: Cache ~/.cargo 101 | uses: actions/cache@v3 102 | with: 103 | path: ~/.cargo 104 | key: ${{ runner.os }}-rust-dot-cargo-${{ hashFiles('Cargo.lock') }} 105 | - name: Setup tools in ~/.cargo 106 | run: | 107 | bin/release-tools initialize-cargo-pgrx 108 | - name: Initialize PGRX in ~/.pgrx 109 | run: | 110 | bin/release-tools initialize-pgrx-with-local-pg 111 | - uses: actions-rs/cargo@v1 112 | with: 113 | command: clippy 114 | args: -- -D warnings 115 | -------------------------------------------------------------------------------- /.github/workflows/package-extension.yml: -------------------------------------------------------------------------------- 1 | name: package extension (deb) 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | packageVersion: 7 | default: "0.0.1" 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | os: ["ubuntu-22.04", "buildjet-4vcpu-ubuntu-2204-arm"] 14 | runs-on: ${{ matrix.os }} 15 | steps: 16 | - uses: actions/checkout@v3 17 | - uses: actions-rs/toolchain@v1 18 | with: 19 | toolchain: stable 20 | - name: Validate cargo is working 21 | uses: postgresml/gh-actions-cargo@master 22 | with: 23 | command: version 24 | - name: Install dependencies 25 | env: 26 | DEBIAN_FRONTEND: noninteractive 27 | TZ: Etc/UTC 28 | run: | 29 | git submodule update --init --recursive 30 | 31 | # PostgreSQL apt 32 | curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null 33 | sudo sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' 34 | 35 | sudo apt-get install -y software-properties-common 36 | sudo add-apt-repository ppa:apt-fast/stable --yes 37 | sudo add-apt-repository ppa:deadsnakes/ppa --yes 38 | sudo apt update 39 | 40 | sudo apt-get install -y apt-fast 41 | sudo apt-get update && sudo apt-fast install -y \ 42 | libopenblas-dev \ 43 | libssl-dev \ 44 | bison \ 45 | flex \ 46 | pkg-config \ 47 | cmake \ 48 | libreadline-dev \ 49 | libz-dev \ 50 | curl \ 51 | lsb-release \ 52 | tzdata \ 53 | sudo \ 54 | cmake \ 55 | libpq-dev \ 56 | libclang-dev \ 57 | wget \ 58 | postgresql-15 \ 59 | postgresql-14 \ 60 | postgresql-13 \ 61 | postgresql-12 \ 62 | postgresql-11 \ 63 | postgresql-server-dev-15 \ 64 | postgresql-server-dev-14 \ 65 | postgresql-server-dev-13 \ 66 | postgresql-server-dev-12 \ 67 | postgresql-server-dev-11 \ 68 | lsb-release \ 69 | python3.10 \ 70 | python3-pip \ 71 | libpython3.10-dev \ 72 | python3.10-dev \ 73 | ruby 74 | 75 | curl -sLO https://github.com/deb-s3/deb-s3/releases/download/0.11.4/deb-s3-0.11.4.gem 76 | sudo gem install deb-s3-0.11.4.gem 77 | dpkg-deb --version 78 | - name: Install pgrx 79 | uses: postgresml/gh-actions-cargo@master 80 | with: 81 | command: install 82 | args: cargo-pgrx --version "0.8.3" --locked 83 | - name: pgrx init 84 | uses: postgresml/gh-actions-cargo@master 85 | with: 86 | command: pgrx 87 | args: init --pg11=/usr/lib/postgresql/11/bin/pg_config --pg12=/usr/lib/postgresql/12/bin/pg_config --pg13=/usr/lib/postgresql/13/bin/pg_config --pg14=/usr/lib/postgresql/14/bin/pg_config --pg15=/usr/lib/postgresql/15/bin/pg_config 88 | # - name: Build Postgres 11 89 | # uses: postgresml/gh-actions-cargo@master 90 | # with: 91 | # command: pgrx 92 | # args: package --pg-config /usr/lib/postgresql/11/bin/pg_config 93 | # - name: Build Postgres 12 94 | # uses: postgresml/gh-actions-cargo@master 95 | # with: 96 | # command: pgrx 97 | # args: package --pg-config /usr/lib/postgresql/12/bin/pg_config 98 | # - name: Build Postgres 13 99 | # uses: postgresml/gh-actions-cargo@master 100 | # with: 101 | # command: pgrx 102 | # args: package --pg-config /usr/lib/postgresql/13/bin/pg_config 103 | - name: Build Postgres 14 104 | uses: postgresml/gh-actions-cargo@master 105 | with: 106 | command: pgrx 107 | args: package --pg-config /usr/lib/postgresql/14/bin/pg_config 108 | - name: Build Postgres 15 109 | uses: postgresml/gh-actions-cargo@master 110 | with: 111 | command: pgrx 112 | args: package --pg-config /usr/lib/postgresql/15/bin/pg_config 113 | - name: Build debs 114 | env: 115 | AWS_ACCESS_KEY_ID: ${{ vars.AWS_ACCESS_KEY_ID }} 116 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 117 | AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} 118 | run: | 119 | for pg in {14..15}; do 120 | export PACKAGE_VERSION=${{ inputs.packageVersion }} 121 | export PGVERSION=${pg} 122 | 123 | if [[ $(arch) == "x86_64" ]]; then 124 | export ARCH=amd64 125 | else 126 | export ARCH=arm64 127 | fi 128 | 129 | mkdir -p target/release/pg_stat_sysinfo-pg${pg}/DEBIAN 130 | (cat control | envsubst) > target/release/pg_stat_sysinfo-pg${pg}/DEBIAN/control 131 | 132 | dpkg-deb \ 133 | --root-owner-group \ 134 | --build target/release/pg_stat_sysinfo-pg${pg} \ 135 | postgresql-pg-stat-sysinfo-${pg}_${PACKAGE_VERSION}-ubuntu22.04-${ARCH}.deb 136 | 137 | deb-s3 upload \ 138 | --bucket apt.postgresml.org \ 139 | postgresql-pg-stat-sysinfo-${pg}_${PACKAGE_VERSION}-ubuntu22.04-${ARCH}.deb \ 140 | --codename $(lsb_release -cs) 141 | done 142 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | tmp/ 7 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.0.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.68" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" 19 | 20 | [[package]] 21 | name = "async-trait" 22 | version = "0.1.61" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" 25 | dependencies = [ 26 | "proc-macro2", 27 | "quote", 28 | "syn 1.0.109", 29 | ] 30 | 31 | [[package]] 32 | name = "atomic-polyfill" 33 | version = "0.1.11" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" 36 | dependencies = [ 37 | "critical-section", 38 | ] 39 | 40 | [[package]] 41 | name = "atomic-traits" 42 | version = "0.3.0" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "b29ec3788e96fb4fdb275ccb9d62811f2fa903d76c5eb4dd6fe7d09a7ed5871f" 45 | dependencies = [ 46 | "cfg-if", 47 | "rustc_version 0.3.3", 48 | ] 49 | 50 | [[package]] 51 | name = "autocfg" 52 | version = "1.1.0" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 55 | 56 | [[package]] 57 | name = "base64" 58 | version = "0.13.1" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 61 | 62 | [[package]] 63 | name = "bindgen" 64 | version = "0.60.1" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" 67 | dependencies = [ 68 | "bitflags", 69 | "cexpr", 70 | "clang-sys", 71 | "lazy_static", 72 | "lazycell", 73 | "peeking_take_while", 74 | "proc-macro2", 75 | "quote", 76 | "regex", 77 | "rustc-hash", 78 | "shlex", 79 | ] 80 | 81 | [[package]] 82 | name = "bitflags" 83 | version = "1.3.2" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 86 | 87 | [[package]] 88 | name = "bitvec" 89 | version = "1.0.1" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" 92 | dependencies = [ 93 | "funty", 94 | "radium", 95 | "tap", 96 | "wyz", 97 | ] 98 | 99 | [[package]] 100 | name = "block-buffer" 101 | version = "0.10.3" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 104 | dependencies = [ 105 | "generic-array", 106 | ] 107 | 108 | [[package]] 109 | name = "byteorder" 110 | version = "1.4.3" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 113 | 114 | [[package]] 115 | name = "bytes" 116 | version = "1.3.0" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" 119 | 120 | [[package]] 121 | name = "bytesize" 122 | version = "1.1.0" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70" 125 | 126 | [[package]] 127 | name = "cargo_toml" 128 | version = "0.15.2" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "7f83bc2e401ed041b7057345ebc488c005efa0341d5541ce7004d30458d0090b" 131 | dependencies = [ 132 | "serde", 133 | "toml", 134 | ] 135 | 136 | [[package]] 137 | name = "cexpr" 138 | version = "0.6.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 141 | dependencies = [ 142 | "nom", 143 | ] 144 | 145 | [[package]] 146 | name = "cfg-if" 147 | version = "1.0.0" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 150 | 151 | [[package]] 152 | name = "ciborium" 153 | version = "0.2.0" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" 156 | dependencies = [ 157 | "ciborium-io", 158 | "ciborium-ll", 159 | "serde", 160 | ] 161 | 162 | [[package]] 163 | name = "ciborium-io" 164 | version = "0.2.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" 167 | 168 | [[package]] 169 | name = "ciborium-ll" 170 | version = "0.2.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" 173 | dependencies = [ 174 | "ciborium-io", 175 | "half", 176 | ] 177 | 178 | [[package]] 179 | name = "clang-sys" 180 | version = "1.4.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" 183 | dependencies = [ 184 | "glob", 185 | "libc", 186 | "libloading", 187 | ] 188 | 189 | [[package]] 190 | name = "clap" 191 | version = "4.1.8" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5" 194 | dependencies = [ 195 | "bitflags", 196 | "clap_derive", 197 | "clap_lex", 198 | "once_cell", 199 | ] 200 | 201 | [[package]] 202 | name = "clap-cargo" 203 | version = "0.10.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "eca953650a7350560b61db95a0ab1d9c6f7b74d146a9e08fb258b834f3cf7e2c" 206 | dependencies = [ 207 | "clap", 208 | "doc-comment", 209 | ] 210 | 211 | [[package]] 212 | name = "clap_derive" 213 | version = "4.1.8" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0" 216 | dependencies = [ 217 | "heck", 218 | "proc-macro-error", 219 | "proc-macro2", 220 | "quote", 221 | "syn 1.0.109", 222 | ] 223 | 224 | [[package]] 225 | name = "clap_lex" 226 | version = "0.3.2" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" 229 | dependencies = [ 230 | "os_str_bytes", 231 | ] 232 | 233 | [[package]] 234 | name = "convert_case" 235 | version = "0.6.0" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 238 | dependencies = [ 239 | "unicode-segmentation", 240 | ] 241 | 242 | [[package]] 243 | name = "core-foundation-sys" 244 | version = "0.8.3" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 247 | 248 | [[package]] 249 | name = "cpufeatures" 250 | version = "0.2.5" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 253 | dependencies = [ 254 | "libc", 255 | ] 256 | 257 | [[package]] 258 | name = "critical-section" 259 | version = "1.1.1" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" 262 | 263 | [[package]] 264 | name = "crossbeam-channel" 265 | version = "0.5.6" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" 268 | dependencies = [ 269 | "cfg-if", 270 | "crossbeam-utils", 271 | ] 272 | 273 | [[package]] 274 | name = "crossbeam-deque" 275 | version = "0.8.2" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" 278 | dependencies = [ 279 | "cfg-if", 280 | "crossbeam-epoch", 281 | "crossbeam-utils", 282 | ] 283 | 284 | [[package]] 285 | name = "crossbeam-epoch" 286 | version = "0.9.13" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" 289 | dependencies = [ 290 | "autocfg", 291 | "cfg-if", 292 | "crossbeam-utils", 293 | "memoffset 0.7.1", 294 | "scopeguard", 295 | ] 296 | 297 | [[package]] 298 | name = "crossbeam-utils" 299 | version = "0.8.14" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" 302 | dependencies = [ 303 | "cfg-if", 304 | ] 305 | 306 | [[package]] 307 | name = "crypto-common" 308 | version = "0.1.6" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 311 | dependencies = [ 312 | "generic-array", 313 | "typenum", 314 | ] 315 | 316 | [[package]] 317 | name = "digest" 318 | version = "0.10.6" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 321 | dependencies = [ 322 | "block-buffer", 323 | "crypto-common", 324 | "subtle", 325 | ] 326 | 327 | [[package]] 328 | name = "dirs" 329 | version = "4.0.0" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" 332 | dependencies = [ 333 | "dirs-sys", 334 | ] 335 | 336 | [[package]] 337 | name = "dirs-sys" 338 | version = "0.3.7" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 341 | dependencies = [ 342 | "libc", 343 | "redox_users", 344 | "winapi", 345 | ] 346 | 347 | [[package]] 348 | name = "doc-comment" 349 | version = "0.3.3" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" 352 | 353 | [[package]] 354 | name = "either" 355 | version = "1.8.0" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" 358 | 359 | [[package]] 360 | name = "enum-map" 361 | version = "2.5.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "988f0d17a0fa38291e5f41f71ea8d46a5d5497b9054d5a759fae2cbb819f2356" 364 | dependencies = [ 365 | "enum-map-derive", 366 | ] 367 | 368 | [[package]] 369 | name = "enum-map-derive" 370 | version = "0.11.0" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "2a4da76b3b6116d758c7ba93f7ec6a35d2e2cf24feda76c6e38a375f4d5c59f2" 373 | dependencies = [ 374 | "proc-macro2", 375 | "quote", 376 | "syn 1.0.109", 377 | ] 378 | 379 | [[package]] 380 | name = "eyre" 381 | version = "0.6.8" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" 384 | dependencies = [ 385 | "indenter", 386 | "once_cell", 387 | ] 388 | 389 | [[package]] 390 | name = "fallible-iterator" 391 | version = "0.2.0" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" 394 | 395 | [[package]] 396 | name = "fixedbitset" 397 | version = "0.4.2" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 400 | 401 | [[package]] 402 | name = "form_urlencoded" 403 | version = "1.1.0" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 406 | dependencies = [ 407 | "percent-encoding", 408 | ] 409 | 410 | [[package]] 411 | name = "funty" 412 | version = "2.0.0" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" 415 | 416 | [[package]] 417 | name = "futures-channel" 418 | version = "0.3.25" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" 421 | dependencies = [ 422 | "futures-core", 423 | "futures-sink", 424 | ] 425 | 426 | [[package]] 427 | name = "futures-core" 428 | version = "0.3.25" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" 431 | 432 | [[package]] 433 | name = "futures-macro" 434 | version = "0.3.25" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" 437 | dependencies = [ 438 | "proc-macro2", 439 | "quote", 440 | "syn 1.0.109", 441 | ] 442 | 443 | [[package]] 444 | name = "futures-sink" 445 | version = "0.3.25" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" 448 | 449 | [[package]] 450 | name = "futures-task" 451 | version = "0.3.25" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" 454 | 455 | [[package]] 456 | name = "futures-util" 457 | version = "0.3.25" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" 460 | dependencies = [ 461 | "futures-core", 462 | "futures-macro", 463 | "futures-sink", 464 | "futures-task", 465 | "pin-project-lite", 466 | "pin-utils", 467 | "slab", 468 | ] 469 | 470 | [[package]] 471 | name = "generic-array" 472 | version = "0.14.6" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 475 | dependencies = [ 476 | "typenum", 477 | "version_check", 478 | ] 479 | 480 | [[package]] 481 | name = "getrandom" 482 | version = "0.2.8" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 485 | dependencies = [ 486 | "cfg-if", 487 | "libc", 488 | "wasi", 489 | ] 490 | 491 | [[package]] 492 | name = "glob" 493 | version = "0.3.1" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 496 | 497 | [[package]] 498 | name = "half" 499 | version = "1.8.2" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" 502 | 503 | [[package]] 504 | name = "hash32" 505 | version = "0.2.1" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" 508 | dependencies = [ 509 | "byteorder", 510 | ] 511 | 512 | [[package]] 513 | name = "hashbrown" 514 | version = "0.12.3" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 517 | 518 | [[package]] 519 | name = "heapless" 520 | version = "0.7.16" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" 523 | dependencies = [ 524 | "atomic-polyfill", 525 | "hash32", 526 | "rustc_version 0.4.0", 527 | "spin", 528 | "stable_deref_trait", 529 | ] 530 | 531 | [[package]] 532 | name = "heck" 533 | version = "0.4.1" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 536 | 537 | [[package]] 538 | name = "hermit-abi" 539 | version = "0.2.6" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 542 | dependencies = [ 543 | "libc", 544 | ] 545 | 546 | [[package]] 547 | name = "hmac" 548 | version = "0.12.1" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 551 | dependencies = [ 552 | "digest", 553 | ] 554 | 555 | [[package]] 556 | name = "idna" 557 | version = "0.3.0" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 560 | dependencies = [ 561 | "unicode-bidi", 562 | "unicode-normalization", 563 | ] 564 | 565 | [[package]] 566 | name = "indenter" 567 | version = "0.3.3" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 570 | 571 | [[package]] 572 | name = "indexmap" 573 | version = "1.9.2" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" 576 | dependencies = [ 577 | "autocfg", 578 | "hashbrown", 579 | ] 580 | 581 | [[package]] 582 | name = "itoa" 583 | version = "1.0.5" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" 586 | 587 | [[package]] 588 | name = "lazy_static" 589 | version = "1.4.0" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 592 | 593 | [[package]] 594 | name = "lazycell" 595 | version = "1.3.0" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 598 | 599 | [[package]] 600 | name = "libc" 601 | version = "0.2.144" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" 604 | 605 | [[package]] 606 | name = "libloading" 607 | version = "0.7.4" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 610 | dependencies = [ 611 | "cfg-if", 612 | "winapi", 613 | ] 614 | 615 | [[package]] 616 | name = "lock_api" 617 | version = "0.4.9" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 620 | dependencies = [ 621 | "autocfg", 622 | "scopeguard", 623 | ] 624 | 625 | [[package]] 626 | name = "log" 627 | version = "0.4.17" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 630 | dependencies = [ 631 | "cfg-if", 632 | ] 633 | 634 | [[package]] 635 | name = "md-5" 636 | version = "0.10.5" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" 639 | dependencies = [ 640 | "digest", 641 | ] 642 | 643 | [[package]] 644 | name = "memchr" 645 | version = "2.5.0" 646 | source = "registry+https://github.com/rust-lang/crates.io-index" 647 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 648 | 649 | [[package]] 650 | name = "memoffset" 651 | version = "0.7.1" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 654 | dependencies = [ 655 | "autocfg", 656 | ] 657 | 658 | [[package]] 659 | name = "memoffset" 660 | version = "0.8.0" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" 663 | dependencies = [ 664 | "autocfg", 665 | ] 666 | 667 | [[package]] 668 | name = "minimal-lexical" 669 | version = "0.2.1" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 672 | 673 | [[package]] 674 | name = "mio" 675 | version = "0.8.5" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" 678 | dependencies = [ 679 | "libc", 680 | "log", 681 | "wasi", 682 | "windows-sys 0.42.0", 683 | ] 684 | 685 | [[package]] 686 | name = "nom" 687 | version = "7.1.2" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c" 690 | dependencies = [ 691 | "memchr", 692 | "minimal-lexical", 693 | ] 694 | 695 | [[package]] 696 | name = "ntapi" 697 | version = "0.4.0" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc" 700 | dependencies = [ 701 | "winapi", 702 | ] 703 | 704 | [[package]] 705 | name = "num_cpus" 706 | version = "1.15.0" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 709 | dependencies = [ 710 | "hermit-abi", 711 | "libc", 712 | ] 713 | 714 | [[package]] 715 | name = "once_cell" 716 | version = "1.17.1" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" 719 | 720 | [[package]] 721 | name = "os_str_bytes" 722 | version = "6.4.1" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" 725 | 726 | [[package]] 727 | name = "owo-colors" 728 | version = "3.5.0" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" 731 | 732 | [[package]] 733 | name = "parking_lot" 734 | version = "0.12.1" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 737 | dependencies = [ 738 | "lock_api", 739 | "parking_lot_core", 740 | ] 741 | 742 | [[package]] 743 | name = "parking_lot_core" 744 | version = "0.9.5" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" 747 | dependencies = [ 748 | "cfg-if", 749 | "libc", 750 | "redox_syscall", 751 | "smallvec", 752 | "windows-sys 0.42.0", 753 | ] 754 | 755 | [[package]] 756 | name = "pathsearch" 757 | version = "0.2.0" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "da983bc5e582ab17179c190b4b66c7d76c5943a69c6d34df2a2b6bf8a2977b05" 760 | dependencies = [ 761 | "anyhow", 762 | "libc", 763 | ] 764 | 765 | [[package]] 766 | name = "peeking_take_while" 767 | version = "0.1.2" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 770 | 771 | [[package]] 772 | name = "percent-encoding" 773 | version = "2.2.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 776 | 777 | [[package]] 778 | name = "pest" 779 | version = "2.5.2" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4" 782 | dependencies = [ 783 | "thiserror", 784 | "ucd-trie", 785 | ] 786 | 787 | [[package]] 788 | name = "petgraph" 789 | version = "0.6.3" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" 792 | dependencies = [ 793 | "fixedbitset", 794 | "indexmap", 795 | ] 796 | 797 | [[package]] 798 | name = "pg_stat_sysinfo" 799 | version = "0.0.1" 800 | dependencies = [ 801 | "anyhow", 802 | "bytesize", 803 | "ciborium", 804 | "heapless", 805 | "lazy_static", 806 | "parking_lot", 807 | "pgrx", 808 | "pgrx-tests", 809 | "serde", 810 | "serde_bare", 811 | "serde_json", 812 | "sysinfo 0.27.8", 813 | "time", 814 | ] 815 | 816 | [[package]] 817 | name = "pgrx" 818 | version = "0.8.3" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "227eb709ecc07be4744b3d48591c5f55263f142a8f8ebe88744adbf24579821f" 821 | dependencies = [ 822 | "atomic-traits", 823 | "bitflags", 824 | "bitvec", 825 | "enum-map", 826 | "heapless", 827 | "libc", 828 | "once_cell", 829 | "pgrx-macros", 830 | "pgrx-pg-sys", 831 | "pgrx-sql-entity-graph", 832 | "seahash", 833 | "seq-macro", 834 | "serde", 835 | "serde_cbor", 836 | "serde_json", 837 | "thiserror", 838 | "time", 839 | "uuid", 840 | ] 841 | 842 | [[package]] 843 | name = "pgrx-macros" 844 | version = "0.8.3" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "e72a1ce1c7947db620a63ec384c714ac548d21a8a24679f2d93c7eb6a37daaac" 847 | dependencies = [ 848 | "pgrx-sql-entity-graph", 849 | "proc-macro2", 850 | "quote", 851 | "syn 1.0.109", 852 | ] 853 | 854 | [[package]] 855 | name = "pgrx-pg-config" 856 | version = "0.8.3" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "636f0e65fb178c6197494c3f84b507d3349bc427098d86ea6e8571895824bf3c" 859 | dependencies = [ 860 | "cargo_toml", 861 | "dirs", 862 | "eyre", 863 | "owo-colors", 864 | "pathsearch", 865 | "serde", 866 | "serde_derive", 867 | "serde_json", 868 | "toml", 869 | "url", 870 | ] 871 | 872 | [[package]] 873 | name = "pgrx-pg-sys" 874 | version = "0.8.3" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "f5934666b9d22d1c2ff09f9de893a49646737e42edb74349b6d4c802ac8d0561" 877 | dependencies = [ 878 | "bindgen", 879 | "eyre", 880 | "libc", 881 | "memoffset 0.8.0", 882 | "once_cell", 883 | "pgrx-macros", 884 | "pgrx-pg-config", 885 | "pgrx-sql-entity-graph", 886 | "proc-macro2", 887 | "quote", 888 | "serde", 889 | "shlex", 890 | "sptr", 891 | "syn 1.0.109", 892 | ] 893 | 894 | [[package]] 895 | name = "pgrx-sql-entity-graph" 896 | version = "0.8.3" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | checksum = "658a0f6638118d9d47b381abe13359e95db0b5fa612a96eb5b35b2dc5d76ea8c" 899 | dependencies = [ 900 | "convert_case", 901 | "eyre", 902 | "petgraph", 903 | "proc-macro2", 904 | "quote", 905 | "syn 1.0.109", 906 | "unescape", 907 | ] 908 | 909 | [[package]] 910 | name = "pgrx-tests" 911 | version = "0.8.3" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "4120e5c68f08a41d213eb4dfe7d299c91a353199fc7b0e8826f7133c7e02f281" 914 | dependencies = [ 915 | "clap-cargo", 916 | "eyre", 917 | "libc", 918 | "once_cell", 919 | "owo-colors", 920 | "pgrx", 921 | "pgrx-macros", 922 | "pgrx-pg-config", 923 | "postgres", 924 | "regex", 925 | "serde", 926 | "serde_json", 927 | "sysinfo 0.28.4", 928 | "thiserror", 929 | "time", 930 | ] 931 | 932 | [[package]] 933 | name = "phf" 934 | version = "0.11.1" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" 937 | dependencies = [ 938 | "phf_shared", 939 | ] 940 | 941 | [[package]] 942 | name = "phf_shared" 943 | version = "0.11.1" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" 946 | dependencies = [ 947 | "siphasher", 948 | ] 949 | 950 | [[package]] 951 | name = "pin-project-lite" 952 | version = "0.2.9" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 955 | 956 | [[package]] 957 | name = "pin-utils" 958 | version = "0.1.0" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 961 | 962 | [[package]] 963 | name = "postgres" 964 | version = "0.19.5" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "0bed5017bc2ff49649c0075d0d7a9d676933c1292480c1d137776fb205b5cd18" 967 | dependencies = [ 968 | "bytes", 969 | "fallible-iterator", 970 | "futures-util", 971 | "log", 972 | "tokio", 973 | "tokio-postgres", 974 | ] 975 | 976 | [[package]] 977 | name = "postgres-protocol" 978 | version = "0.6.4" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "878c6cbf956e03af9aa8204b407b9cbf47c072164800aa918c516cd4b056c50c" 981 | dependencies = [ 982 | "base64", 983 | "byteorder", 984 | "bytes", 985 | "fallible-iterator", 986 | "hmac", 987 | "md-5", 988 | "memchr", 989 | "rand", 990 | "sha2", 991 | "stringprep", 992 | ] 993 | 994 | [[package]] 995 | name = "postgres-types" 996 | version = "0.2.4" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "73d946ec7d256b04dfadc4e6a3292324e6f417124750fc5c0950f981b703a0f1" 999 | dependencies = [ 1000 | "bytes", 1001 | "fallible-iterator", 1002 | "postgres-protocol", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "ppv-lite86" 1007 | version = "0.2.17" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1010 | 1011 | [[package]] 1012 | name = "proc-macro-error" 1013 | version = "1.0.4" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1016 | dependencies = [ 1017 | "proc-macro-error-attr", 1018 | "proc-macro2", 1019 | "quote", 1020 | "syn 1.0.109", 1021 | "version_check", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "proc-macro-error-attr" 1026 | version = "1.0.4" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1029 | dependencies = [ 1030 | "proc-macro2", 1031 | "quote", 1032 | "version_check", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "proc-macro2" 1037 | version = "1.0.56" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" 1040 | dependencies = [ 1041 | "unicode-ident", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "quote" 1046 | version = "1.0.26" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" 1049 | dependencies = [ 1050 | "proc-macro2", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "radium" 1055 | version = "0.7.0" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" 1058 | 1059 | [[package]] 1060 | name = "rand" 1061 | version = "0.8.5" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1064 | dependencies = [ 1065 | "libc", 1066 | "rand_chacha", 1067 | "rand_core", 1068 | ] 1069 | 1070 | [[package]] 1071 | name = "rand_chacha" 1072 | version = "0.3.1" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1075 | dependencies = [ 1076 | "ppv-lite86", 1077 | "rand_core", 1078 | ] 1079 | 1080 | [[package]] 1081 | name = "rand_core" 1082 | version = "0.6.4" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1085 | dependencies = [ 1086 | "getrandom", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "rayon" 1091 | version = "1.6.1" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" 1094 | dependencies = [ 1095 | "either", 1096 | "rayon-core", 1097 | ] 1098 | 1099 | [[package]] 1100 | name = "rayon-core" 1101 | version = "1.10.1" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" 1104 | dependencies = [ 1105 | "crossbeam-channel", 1106 | "crossbeam-deque", 1107 | "crossbeam-utils", 1108 | "num_cpus", 1109 | ] 1110 | 1111 | [[package]] 1112 | name = "redox_syscall" 1113 | version = "0.2.16" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1116 | dependencies = [ 1117 | "bitflags", 1118 | ] 1119 | 1120 | [[package]] 1121 | name = "redox_users" 1122 | version = "0.4.3" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" 1125 | dependencies = [ 1126 | "getrandom", 1127 | "redox_syscall", 1128 | "thiserror", 1129 | ] 1130 | 1131 | [[package]] 1132 | name = "regex" 1133 | version = "1.8.2" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "d1a59b5d8e97dee33696bf13c5ba8ab85341c002922fba050069326b9c498974" 1136 | dependencies = [ 1137 | "aho-corasick", 1138 | "memchr", 1139 | "regex-syntax", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "regex-syntax" 1144 | version = "0.7.2" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" 1147 | 1148 | [[package]] 1149 | name = "rustc-hash" 1150 | version = "1.1.0" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1153 | 1154 | [[package]] 1155 | name = "rustc_version" 1156 | version = "0.3.3" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" 1159 | dependencies = [ 1160 | "semver 0.11.0", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "rustc_version" 1165 | version = "0.4.0" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1168 | dependencies = [ 1169 | "semver 1.0.16", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "ryu" 1174 | version = "1.0.12" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" 1177 | 1178 | [[package]] 1179 | name = "scopeguard" 1180 | version = "1.1.0" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1183 | 1184 | [[package]] 1185 | name = "seahash" 1186 | version = "4.1.0" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" 1189 | 1190 | [[package]] 1191 | name = "semver" 1192 | version = "0.11.0" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" 1195 | dependencies = [ 1196 | "semver-parser", 1197 | ] 1198 | 1199 | [[package]] 1200 | name = "semver" 1201 | version = "1.0.16" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" 1204 | 1205 | [[package]] 1206 | name = "semver-parser" 1207 | version = "0.10.2" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" 1210 | dependencies = [ 1211 | "pest", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "seq-macro" 1216 | version = "0.3.2" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "1685deded9b272198423bdbdb907d8519def2f26cf3699040e54e8c4fbd5c5ce" 1219 | 1220 | [[package]] 1221 | name = "serde" 1222 | version = "1.0.163" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" 1225 | dependencies = [ 1226 | "serde_derive", 1227 | ] 1228 | 1229 | [[package]] 1230 | name = "serde_bare" 1231 | version = "0.5.0" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "51c55386eed0f1ae957b091dc2ca8122f287b60c79c774cbe3d5f2b69fded660" 1234 | dependencies = [ 1235 | "serde", 1236 | ] 1237 | 1238 | [[package]] 1239 | name = "serde_cbor" 1240 | version = "0.11.2" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" 1243 | dependencies = [ 1244 | "half", 1245 | "serde", 1246 | ] 1247 | 1248 | [[package]] 1249 | name = "serde_derive" 1250 | version = "1.0.163" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" 1253 | dependencies = [ 1254 | "proc-macro2", 1255 | "quote", 1256 | "syn 2.0.13", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "serde_json" 1261 | version = "1.0.96" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" 1264 | dependencies = [ 1265 | "itoa", 1266 | "ryu", 1267 | "serde", 1268 | ] 1269 | 1270 | [[package]] 1271 | name = "serde_spanned" 1272 | version = "0.6.1" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" 1275 | dependencies = [ 1276 | "serde", 1277 | ] 1278 | 1279 | [[package]] 1280 | name = "sha2" 1281 | version = "0.10.6" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" 1284 | dependencies = [ 1285 | "cfg-if", 1286 | "cpufeatures", 1287 | "digest", 1288 | ] 1289 | 1290 | [[package]] 1291 | name = "shlex" 1292 | version = "1.1.0" 1293 | source = "registry+https://github.com/rust-lang/crates.io-index" 1294 | checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" 1295 | 1296 | [[package]] 1297 | name = "siphasher" 1298 | version = "0.3.10" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" 1301 | 1302 | [[package]] 1303 | name = "slab" 1304 | version = "0.4.7" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 1307 | dependencies = [ 1308 | "autocfg", 1309 | ] 1310 | 1311 | [[package]] 1312 | name = "smallvec" 1313 | version = "1.10.0" 1314 | source = "registry+https://github.com/rust-lang/crates.io-index" 1315 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1316 | 1317 | [[package]] 1318 | name = "socket2" 1319 | version = "0.4.9" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1322 | dependencies = [ 1323 | "libc", 1324 | "winapi", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "socket2" 1329 | version = "0.5.3" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" 1332 | dependencies = [ 1333 | "libc", 1334 | "windows-sys 0.48.0", 1335 | ] 1336 | 1337 | [[package]] 1338 | name = "spin" 1339 | version = "0.9.4" 1340 | source = "registry+https://github.com/rust-lang/crates.io-index" 1341 | checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" 1342 | dependencies = [ 1343 | "lock_api", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "sptr" 1348 | version = "0.3.2" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" 1351 | 1352 | [[package]] 1353 | name = "stable_deref_trait" 1354 | version = "1.2.0" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1357 | 1358 | [[package]] 1359 | name = "stringprep" 1360 | version = "0.1.2" 1361 | source = "registry+https://github.com/rust-lang/crates.io-index" 1362 | checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" 1363 | dependencies = [ 1364 | "unicode-bidi", 1365 | "unicode-normalization", 1366 | ] 1367 | 1368 | [[package]] 1369 | name = "subtle" 1370 | version = "2.4.1" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1373 | 1374 | [[package]] 1375 | name = "syn" 1376 | version = "1.0.109" 1377 | source = "registry+https://github.com/rust-lang/crates.io-index" 1378 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1379 | dependencies = [ 1380 | "proc-macro2", 1381 | "quote", 1382 | "unicode-ident", 1383 | ] 1384 | 1385 | [[package]] 1386 | name = "syn" 1387 | version = "2.0.13" 1388 | source = "registry+https://github.com/rust-lang/crates.io-index" 1389 | checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" 1390 | dependencies = [ 1391 | "proc-macro2", 1392 | "quote", 1393 | "unicode-ident", 1394 | ] 1395 | 1396 | [[package]] 1397 | name = "sysinfo" 1398 | version = "0.27.8" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "a902e9050fca0a5d6877550b769abd2bd1ce8c04634b941dbe2809735e1a1e33" 1401 | dependencies = [ 1402 | "cfg-if", 1403 | "core-foundation-sys", 1404 | "libc", 1405 | "ntapi", 1406 | "once_cell", 1407 | "rayon", 1408 | "winapi", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "sysinfo" 1413 | version = "0.28.4" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b" 1416 | dependencies = [ 1417 | "cfg-if", 1418 | "core-foundation-sys", 1419 | "libc", 1420 | "ntapi", 1421 | "once_cell", 1422 | "rayon", 1423 | "winapi", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "tap" 1428 | version = "1.0.1" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 1431 | 1432 | [[package]] 1433 | name = "thiserror" 1434 | version = "1.0.38" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" 1437 | dependencies = [ 1438 | "thiserror-impl", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "thiserror-impl" 1443 | version = "1.0.38" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" 1446 | dependencies = [ 1447 | "proc-macro2", 1448 | "quote", 1449 | "syn 1.0.109", 1450 | ] 1451 | 1452 | [[package]] 1453 | name = "time" 1454 | version = "0.3.20" 1455 | source = "registry+https://github.com/rust-lang/crates.io-index" 1456 | checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" 1457 | dependencies = [ 1458 | "itoa", 1459 | "serde", 1460 | "time-core", 1461 | "time-macros", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "time-core" 1466 | version = "0.1.0" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" 1469 | 1470 | [[package]] 1471 | name = "time-macros" 1472 | version = "0.2.8" 1473 | source = "registry+https://github.com/rust-lang/crates.io-index" 1474 | checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" 1475 | dependencies = [ 1476 | "time-core", 1477 | ] 1478 | 1479 | [[package]] 1480 | name = "tinyvec" 1481 | version = "1.6.0" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1484 | dependencies = [ 1485 | "tinyvec_macros", 1486 | ] 1487 | 1488 | [[package]] 1489 | name = "tinyvec_macros" 1490 | version = "0.1.0" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1493 | 1494 | [[package]] 1495 | name = "tokio" 1496 | version = "1.28.1" 1497 | source = "registry+https://github.com/rust-lang/crates.io-index" 1498 | checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" 1499 | dependencies = [ 1500 | "autocfg", 1501 | "bytes", 1502 | "libc", 1503 | "mio", 1504 | "pin-project-lite", 1505 | "socket2 0.4.9", 1506 | "windows-sys 0.48.0", 1507 | ] 1508 | 1509 | [[package]] 1510 | name = "tokio-postgres" 1511 | version = "0.7.8" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" 1514 | dependencies = [ 1515 | "async-trait", 1516 | "byteorder", 1517 | "bytes", 1518 | "fallible-iterator", 1519 | "futures-channel", 1520 | "futures-util", 1521 | "log", 1522 | "parking_lot", 1523 | "percent-encoding", 1524 | "phf", 1525 | "pin-project-lite", 1526 | "postgres-protocol", 1527 | "postgres-types", 1528 | "socket2 0.5.3", 1529 | "tokio", 1530 | "tokio-util", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "tokio-util" 1535 | version = "0.7.4" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" 1538 | dependencies = [ 1539 | "bytes", 1540 | "futures-core", 1541 | "futures-sink", 1542 | "pin-project-lite", 1543 | "tokio", 1544 | "tracing", 1545 | ] 1546 | 1547 | [[package]] 1548 | name = "toml" 1549 | version = "0.7.3" 1550 | source = "registry+https://github.com/rust-lang/crates.io-index" 1551 | checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" 1552 | dependencies = [ 1553 | "serde", 1554 | "serde_spanned", 1555 | "toml_datetime", 1556 | "toml_edit", 1557 | ] 1558 | 1559 | [[package]] 1560 | name = "toml_datetime" 1561 | version = "0.6.1" 1562 | source = "registry+https://github.com/rust-lang/crates.io-index" 1563 | checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" 1564 | dependencies = [ 1565 | "serde", 1566 | ] 1567 | 1568 | [[package]] 1569 | name = "toml_edit" 1570 | version = "0.19.8" 1571 | source = "registry+https://github.com/rust-lang/crates.io-index" 1572 | checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" 1573 | dependencies = [ 1574 | "indexmap", 1575 | "serde", 1576 | "serde_spanned", 1577 | "toml_datetime", 1578 | "winnow", 1579 | ] 1580 | 1581 | [[package]] 1582 | name = "tracing" 1583 | version = "0.1.37" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1586 | dependencies = [ 1587 | "cfg-if", 1588 | "pin-project-lite", 1589 | "tracing-core", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "tracing-core" 1594 | version = "0.1.30" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 1597 | dependencies = [ 1598 | "once_cell", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "typenum" 1603 | version = "1.16.0" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1606 | 1607 | [[package]] 1608 | name = "ucd-trie" 1609 | version = "0.1.5" 1610 | source = "registry+https://github.com/rust-lang/crates.io-index" 1611 | checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" 1612 | 1613 | [[package]] 1614 | name = "unescape" 1615 | version = "0.1.0" 1616 | source = "registry+https://github.com/rust-lang/crates.io-index" 1617 | checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" 1618 | 1619 | [[package]] 1620 | name = "unicode-bidi" 1621 | version = "0.3.8" 1622 | source = "registry+https://github.com/rust-lang/crates.io-index" 1623 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 1624 | 1625 | [[package]] 1626 | name = "unicode-ident" 1627 | version = "1.0.6" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" 1630 | 1631 | [[package]] 1632 | name = "unicode-normalization" 1633 | version = "0.1.22" 1634 | source = "registry+https://github.com/rust-lang/crates.io-index" 1635 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1636 | dependencies = [ 1637 | "tinyvec", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "unicode-segmentation" 1642 | version = "1.10.1" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 1645 | 1646 | [[package]] 1647 | name = "url" 1648 | version = "2.3.1" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1651 | dependencies = [ 1652 | "form_urlencoded", 1653 | "idna", 1654 | "percent-encoding", 1655 | ] 1656 | 1657 | [[package]] 1658 | name = "uuid" 1659 | version = "1.3.3" 1660 | source = "registry+https://github.com/rust-lang/crates.io-index" 1661 | checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" 1662 | dependencies = [ 1663 | "getrandom", 1664 | ] 1665 | 1666 | [[package]] 1667 | name = "version_check" 1668 | version = "0.9.4" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1671 | 1672 | [[package]] 1673 | name = "wasi" 1674 | version = "0.11.0+wasi-snapshot-preview1" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1677 | 1678 | [[package]] 1679 | name = "winapi" 1680 | version = "0.3.9" 1681 | source = "registry+https://github.com/rust-lang/crates.io-index" 1682 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1683 | dependencies = [ 1684 | "winapi-i686-pc-windows-gnu", 1685 | "winapi-x86_64-pc-windows-gnu", 1686 | ] 1687 | 1688 | [[package]] 1689 | name = "winapi-i686-pc-windows-gnu" 1690 | version = "0.4.0" 1691 | source = "registry+https://github.com/rust-lang/crates.io-index" 1692 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1693 | 1694 | [[package]] 1695 | name = "winapi-x86_64-pc-windows-gnu" 1696 | version = "0.4.0" 1697 | source = "registry+https://github.com/rust-lang/crates.io-index" 1698 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1699 | 1700 | [[package]] 1701 | name = "windows-sys" 1702 | version = "0.42.0" 1703 | source = "registry+https://github.com/rust-lang/crates.io-index" 1704 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 1705 | dependencies = [ 1706 | "windows_aarch64_gnullvm 0.42.0", 1707 | "windows_aarch64_msvc 0.42.0", 1708 | "windows_i686_gnu 0.42.0", 1709 | "windows_i686_msvc 0.42.0", 1710 | "windows_x86_64_gnu 0.42.0", 1711 | "windows_x86_64_gnullvm 0.42.0", 1712 | "windows_x86_64_msvc 0.42.0", 1713 | ] 1714 | 1715 | [[package]] 1716 | name = "windows-sys" 1717 | version = "0.48.0" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1720 | dependencies = [ 1721 | "windows-targets", 1722 | ] 1723 | 1724 | [[package]] 1725 | name = "windows-targets" 1726 | version = "0.48.0" 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" 1728 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 1729 | dependencies = [ 1730 | "windows_aarch64_gnullvm 0.48.0", 1731 | "windows_aarch64_msvc 0.48.0", 1732 | "windows_i686_gnu 0.48.0", 1733 | "windows_i686_msvc 0.48.0", 1734 | "windows_x86_64_gnu 0.48.0", 1735 | "windows_x86_64_gnullvm 0.48.0", 1736 | "windows_x86_64_msvc 0.48.0", 1737 | ] 1738 | 1739 | [[package]] 1740 | name = "windows_aarch64_gnullvm" 1741 | version = "0.42.0" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" 1744 | 1745 | [[package]] 1746 | name = "windows_aarch64_gnullvm" 1747 | version = "0.48.0" 1748 | source = "registry+https://github.com/rust-lang/crates.io-index" 1749 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 1750 | 1751 | [[package]] 1752 | name = "windows_aarch64_msvc" 1753 | version = "0.42.0" 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" 1755 | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" 1756 | 1757 | [[package]] 1758 | name = "windows_aarch64_msvc" 1759 | version = "0.48.0" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 1762 | 1763 | [[package]] 1764 | name = "windows_i686_gnu" 1765 | version = "0.42.0" 1766 | source = "registry+https://github.com/rust-lang/crates.io-index" 1767 | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" 1768 | 1769 | [[package]] 1770 | name = "windows_i686_gnu" 1771 | version = "0.48.0" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 1774 | 1775 | [[package]] 1776 | name = "windows_i686_msvc" 1777 | version = "0.42.0" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" 1780 | 1781 | [[package]] 1782 | name = "windows_i686_msvc" 1783 | version = "0.48.0" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 1786 | 1787 | [[package]] 1788 | name = "windows_x86_64_gnu" 1789 | version = "0.42.0" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" 1792 | 1793 | [[package]] 1794 | name = "windows_x86_64_gnu" 1795 | version = "0.48.0" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 1798 | 1799 | [[package]] 1800 | name = "windows_x86_64_gnullvm" 1801 | version = "0.42.0" 1802 | source = "registry+https://github.com/rust-lang/crates.io-index" 1803 | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" 1804 | 1805 | [[package]] 1806 | name = "windows_x86_64_gnullvm" 1807 | version = "0.48.0" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 1810 | 1811 | [[package]] 1812 | name = "windows_x86_64_msvc" 1813 | version = "0.42.0" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" 1816 | 1817 | [[package]] 1818 | name = "windows_x86_64_msvc" 1819 | version = "0.48.0" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 1822 | 1823 | [[package]] 1824 | name = "winnow" 1825 | version = "0.4.1" 1826 | source = "registry+https://github.com/rust-lang/crates.io-index" 1827 | checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" 1828 | dependencies = [ 1829 | "memchr", 1830 | ] 1831 | 1832 | [[package]] 1833 | name = "wyz" 1834 | version = "0.5.1" 1835 | source = "registry+https://github.com/rust-lang/crates.io-index" 1836 | checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" 1837 | dependencies = [ 1838 | "tap", 1839 | ] 1840 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pg_stat_sysinfo" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [features] 10 | default = ["pg14"] 11 | pg11 = ["pgrx/pg11", "pgrx-tests/pg11" ] 12 | pg12 = ["pgrx/pg12", "pgrx-tests/pg12" ] 13 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13" ] 14 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14" ] 15 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15" ] 16 | pg_test = [] 17 | 18 | [dependencies] 19 | anyhow = "1" 20 | bytesize = "1.1.0" 21 | ciborium = "0.2.0" 22 | heapless = "0.7.16" 23 | lazy_static = "1.4.0" 24 | parking_lot = "0.12.1" 25 | pgrx = { version = "=0.8.3", features = ["time-crate"] } 26 | serde = "1.0.152" 27 | serde_bare = { version = "0.5.0", features = ["std"] } 28 | serde_json = "1.0.91" 29 | sysinfo = "0.27.5" 30 | time = { version = "0.3.17", features = ["serde-human-readable"] } 31 | 32 | [dev-dependencies] 33 | pgrx-tests = "=0.8.3" 34 | 35 | [profile.dev] 36 | panic = "unwind" 37 | lto = "thin" 38 | 39 | [profile.release] 40 | panic = "unwind" 41 | opt-level = 3 42 | lto = "fat" 43 | codegen-units = 1 44 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 PostgresML Team 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `pg_stat_sysinfo` 2 | 3 | Collects system statistics. 4 | 5 | ```sql 6 | ---- 7 | CREATE EXTENSION pg_stat_sysinfo; 8 | CREATE EXTENSION 9 | ---- 10 | SELECT * FROM pg_stat_sysinfo_collect(); 11 | metric | dimensions | at | value 12 | ------------------+--------------+------------------------------+-------------------- 13 | load_average | duration:1m | 2023-01-17 20:40:24.74495+00 | 4.3427734375 14 | load_average | duration:5m | 2023-01-17 20:40:24.74495+00 | 2.740234375 15 | load_average | duration:15m | 2023-01-17 20:40:24.74495+00 | 2.390625 16 | cpu_usage | | 2023-01-17 20:40:24.74495+00 | 0.12653848528862 17 | memory_usage | | 2023-01-17 20:40:24.74495+00 | 10.022946522725185 18 | memory_size | | 2023-01-17 20:40:24.74495+00 | 7966543872 19 | memory_available | | 2023-01-17 20:40:24.74495+00 | 7168061440 20 | swap_usage | | 2023-01-17 20:40:24.74495+00 | 0 21 | swap_size | | 2023-01-17 20:40:24.74495+00 | 0 22 | swap_available | | 2023-01-17 20:40:24.74495+00 | 0 23 | disk_usage | fs:/ | 2023-01-17 20:40:24.74495+00 | 48.68292833372914 24 | disk_size | fs:/ | 2023-01-17 20:40:24.74495+00 | 66404147200 25 | disk_available | fs:/ | 2023-01-17 20:40:24.74495+00 | 34076663808 26 | disk_usage | fs:/boot/efi | 2023-01-17 20:40:24.74495+00 | 4.986992082951202 27 | disk_size | fs:/boot/efi | 2023-01-17 20:40:24.74495+00 | 109422592 28 | disk_available | fs:/boot/efi | 2023-01-17 20:40:24.74495+00 | 103965696 29 | (16 rows) 30 | 31 | ``` 32 | 33 | ## Enabling Caching Collector 34 | 35 | Add the extension library to `shared_preload_libraries` and set the collection 36 | interval: 37 | 38 | ```python 39 | shared_preload_libraries = 'pg_stat_sysinfo.so' 40 | pg_stat_sysinfo.interval = '1s' # Accepts any time format Postgres recognizes 41 | ``` 42 | 43 | The cache is stored in Postgres shared memory. Up to 1280 KiB is cached -- over 44 | an hour, in most cases, at 1 query per second. 45 | 46 | ```sql 47 | ---- 48 | CREATE EXTENSION pg_stat_sysinfo; 49 | CREATE EXTENSION 50 | ---- 51 | SELECT DISTINCT min(at) AS oldest, 52 | max(at) - min(at) AS during 53 | FROM pg_stat_sysinfo; 54 | oldest | during 55 | -------------------------------+----------------- 56 | 2023-01-17 20:04:46.220977+00 | 00:55:55.908972 57 | (1 row) 58 | 59 | ---- 60 | SELECT DISTINCT dimensions FROM pg_stat_sysinfo; 61 | dimensions 62 | ---------------- 63 | 64 | duration:1m 65 | duration:5m 66 | duration:15m 67 | disk:/ 68 | disk:/boot/efi 69 | (6 rows) 70 | 71 | ``` 72 | 73 | Basic cache statistics are available: 74 | 75 | ```sql 76 | ---- 77 | SELECT * FROM pg_stat_sysinfo_cache_summary(); 78 | bytes_used | items 79 | ------------+------- 80 | 563159 | 3587 81 | (1 row) 82 | 83 | ``` 84 | 85 | ## Configuration Changes 86 | 87 | The `pg_stat_sysinfo.interval` can be updated by changing `postgres.conf` and 88 | sending `SIGHUP` to the Postgres server process. The cache worker will use the 89 | new interval from that point forward. 90 | 91 | If a long enough time has passed between server startup and a `SIGHUP`, or 92 | between one `SIGHUP` and another, the cache worker will refresh the disk 93 | metadata. This will allow it to pick up any disks that have been added to or 94 | removed from the system. 95 | -------------------------------------------------------------------------------- /bin/release-tools: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit -o nounset -o pipefail 3 | 4 | function main { 5 | msg "Please pass a subcommand:" 6 | self-help >&2 7 | } 8 | 9 | ### Obtain package version. 10 | function notional-package-version { 11 | cargo pkgid | cut -d'#' -f2 12 | } 13 | 14 | ### Name of package. 15 | function notional-package-name { 16 | cargo pkgid | sed -E 's|^.+/([^/]+)#.+$|\1| ; y|_|-|' 17 | } 18 | 19 | ### Name of package in the format of Postgres extensions on Debian distros. 20 | function apt-package-name { 21 | out "postgresql-$(notional-package-name)-$(pg-major-version)" 22 | } 23 | 24 | ### Upload this DEB with `deb-s3`. 25 | function upload-deb-to-s3 { 26 | local bucket="$1" 27 | local pkg="$2" 28 | local codename= 29 | codename="$(lsb-codename)" 30 | 31 | local opts=( 32 | --bucket "$bucket" 33 | --codename "$codename" 34 | "$pkg" 35 | ) 36 | 37 | deb-s3 upload "${opts[@]}" 38 | } 39 | 40 | ### Examine a `Cargo.toml` file to find the version of PGRX that is referenced. 41 | function find-pgrx-version { 42 | egrep '^pgrx = { version = "=[^0-9]*([^"]+)"' | 43 | egrep -o '"[^0-9]*([^"]+)"' | 44 | tr -d -c '.0-9' 45 | } 46 | 47 | ### Install the version of pgrx needed by the Cargo project. 48 | function initialize-cargo-pgrx { 49 | local pgrx_version= 50 | pgrx_version="$(find-pgrx-version < Cargo.toml)" 51 | cargo install cargo-pgrx --version "$pgrx_version" 52 | } 53 | 54 | 55 | ### Run `cargo pgrx init` with whatever version of Postgres is installed. 56 | function initialize-pgrx-with-local-pg { 57 | local path= major_version= 58 | path="$(which pg_config)" 59 | major_version="$(pg-major-version)" 60 | cargo pgrx init --pg"$major_version" "$path" 61 | } 62 | 63 | ### Obtain Linux Standards Base codename. 64 | function lsb-codename { 65 | lsb_release -c | cut -f2 66 | } 67 | 68 | ### Get the Postgres major version from Postgres. 69 | function pg-major-version { 70 | pg_config --version | cut -d' ' -f 2 | cut -d. -f1 71 | } 72 | 73 | ### Install the `deb-s3` utility. 74 | function setup-deb-s3 { 75 | local v='0.11.4' 76 | local opts=( 77 | -sSfL 78 | https://github.com/deb-s3/deb-s3/releases/download/"$v"/deb-s3-"$v".gem 79 | -o 80 | deb-s3-"$v".gem 81 | ) 82 | 83 | curl "${opts[@]}" 84 | 85 | gem install deb-s3-"$v".gem 86 | } 87 | 88 | function self-help { 89 | local self="$0" 90 | sed -nE '/^### / { h; n; /^function / { G; s/### / -- /; p; }; }' "$self" | 91 | sed -E 's/^function ([^ ]+) .+$/\1/' 92 | } 93 | 94 | 95 | ##################################################################### Utilities 96 | 97 | function msg { out "$*" >&2 ;} 98 | function err { local x=$? ; msg "$*" ; return $(( $x == 0 ? 1 : $x )) ;} 99 | function out { printf '%s\n' "$*" ;} 100 | 101 | # Handles "no-match" exit code specified by POSIX for filtering tools. 102 | function maybe { "$@" || return $(( $? == 1 ? 0 : $? )) ;} 103 | 104 | 105 | ######################### Delegates to subcommands or runs main, as appropriate 106 | 107 | if declare -f -- "${1:-}" >/dev/null 108 | then "$@" 109 | else main "$@" 110 | fi 111 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: postgresql-pg-stat-sysinfo-${PGVERSION} 2 | Version: ${PACKAGE_VERSION} 3 | Section: database 4 | Priority: optional 5 | Architecture: ${ARCH} 6 | Depends: postgresql-${PGVERSION} 7 | Maintainer: PostgresML 8 | Homepage: https://postgresml.org 9 | Description: PG Stat Sysinfo - system statistics inside PostgreSQL. 10 | Detailed system statistics, made available through an SQL interface 11 | via PostgreSQL. 12 | -------------------------------------------------------------------------------- /pg_stat_sysinfo.control: -------------------------------------------------------------------------------- 1 | comment = 'pg_stat_sysinfo: Created by the PostgresML team' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = '$libdir/pg_stat_sysinfo' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /src/cache_worker.rs: -------------------------------------------------------------------------------- 1 | use std::panic::catch_unwind; 2 | use std::time::{Duration, Instant}; 3 | 4 | use pgrx::bgworkers::*; 5 | use pgrx::*; 6 | 7 | use crate::collector::*; 8 | use crate::crate_info::*; 9 | use crate::settings; 10 | use crate::shmem_ring_buffer::*; 11 | 12 | static CACHE: PgLwLock> = PgLwLock::new(); 13 | 14 | unsafe impl PGRXSharedMemory for ShmemRingBuffer {} 15 | 16 | pub fn start() { 17 | pg_shmem_init!(CACHE); 18 | 19 | if settings::read_or_default().interval.is_some() { 20 | BackgroundWorkerBuilder::new("Cache Worker") 21 | .set_function("cache_worker") 22 | .set_library("pg_stat_sysinfo") 23 | // We don't run any queries but, without SPI, the worker segfaults 24 | // on startup. 25 | .enable_spi_access() 26 | .load(); 27 | } 28 | } 29 | 30 | pub fn reports() -> Vec { 31 | // It can happen that the lock is not intialized, if the library is not 32 | // loaded with shared_preload_libraries. That leads to a `panic!(...)`. 33 | // 34 | // It is in general not recommended to catch `panic!(...)` but other 35 | // methods are not ready to hand. Setting an static atomic `ENABLED` 36 | // variable and then switching off of that does not work because the 37 | // client backend sees what the variable looks like before the background 38 | // worker backend starts up and sets it to true. The only way they can 39 | // share memory is with something in Postgres shared memory, but such 40 | // values must be locked; and then we have the same problem. 41 | catch_unwind(|| CACHE.share().read()).unwrap_or_default() 42 | } 43 | 44 | pub fn cache_info() -> BufferSummary { 45 | catch_unwind(|| CACHE.share().stats()).unwrap_or_default() 46 | } 47 | 48 | #[pg_guard] 49 | #[no_mangle] 50 | pub extern "C" fn cache_worker() { 51 | let flags = SignalWakeFlags::SIGHUP | SignalWakeFlags::SIGTERM; 52 | 53 | BackgroundWorker::attach_signal_handlers(flags); 54 | 55 | let name = BackgroundWorker::get_name(); 56 | let interval = settings::read_or_default().interval; 57 | let mut last_config = Instant::now(); 58 | 59 | let mut state: WorkerState = WorkerState::default(); 60 | if let Some(interval) = interval { 61 | if state.enable(interval) { 62 | log!( 63 | "{}: Initialising {} with interval: {:?}", 64 | CRATE, 65 | name, 66 | interval 67 | ); 68 | } 69 | } 70 | 71 | let mut remaining_time = if state.enabled { 72 | state.remaining_time() 73 | } else { 74 | Duration::MAX 75 | }; 76 | 77 | while BackgroundWorker::wait_latch(Some(remaining_time)) { 78 | if BackgroundWorker::sighup_received() { 79 | match settings::read_or_default().interval { 80 | Some(interval) => { 81 | if state.enable(interval) { 82 | log!( 83 | "{}: Configuring {} with interval: {:?}", 84 | CRATE, 85 | name, 86 | interval 87 | ); 88 | } 89 | } 90 | None => { 91 | if state.disable() { 92 | log!("{}: Disabling {}.", CRATE, name,); 93 | } 94 | } 95 | } 96 | let dur = Instant::now().saturating_duration_since(last_config); 97 | if dur >= DISK_CACHE_HIATUS { 98 | log!( 99 | "{}: Reloading cache of disk metadata in {} after: {:?}", 100 | CRATE, 101 | name, 102 | dur 103 | ); 104 | refresh_collector_disk_listing(); 105 | } 106 | last_config = Instant::now(); 107 | } 108 | 109 | if !state.enabled { 110 | remaining_time = Duration::MAX; 111 | continue; 112 | } 113 | 114 | if state.remaining_time() == Duration::ZERO { 115 | debug1!( 116 | "{}: Writing to cache in {} after: {:?}", 117 | CRATE, 118 | name, 119 | Instant::now().saturating_duration_since(state.last_run) 120 | ); 121 | write_new_report_to_cache(); 122 | state.last_run = Instant::now(); 123 | } 124 | 125 | remaining_time = state.remaining_time(); 126 | } 127 | 128 | if !state.enabled { 129 | log!("{}: Shutting down {}", CRATE, name); 130 | } 131 | } 132 | 133 | fn write_new_report_to_cache() { 134 | let report = singleton().report(); 135 | CACHE.exclusive().write(report).expect("Full cache?"); 136 | } 137 | 138 | const DISK_CACHE_HIATUS: Duration = Duration::from_secs(100); 139 | 140 | fn refresh_collector_disk_listing() { 141 | singleton().discover_new_disks(); 142 | } 143 | 144 | #[derive(Clone, Debug, PartialEq)] 145 | struct WorkerState { 146 | interval: Duration, 147 | last_run: Instant, 148 | enabled: bool, 149 | } 150 | 151 | impl WorkerState { 152 | fn enable(&mut self, interval: Duration) -> bool { 153 | let mut changed = false; 154 | if !self.enabled { 155 | self.enabled = true; 156 | self.last_run = Instant::now(); 157 | changed = true; 158 | } 159 | if self.interval != interval { 160 | self.interval = interval; 161 | changed = true; 162 | } 163 | changed 164 | } 165 | 166 | fn disable(&mut self) -> bool { 167 | let mut changed = false; 168 | if self.enabled { 169 | self.enabled = false; 170 | changed = true; 171 | } 172 | changed 173 | } 174 | 175 | fn remaining_time(&self) -> Duration { 176 | let passed = Instant::now().saturating_duration_since(self.last_run); 177 | self.interval.saturating_sub(passed) 178 | } 179 | } 180 | 181 | impl Default for WorkerState { 182 | fn default() -> Self { 183 | WorkerState { 184 | interval: Duration::default(), 185 | last_run: Instant::now(), 186 | enabled: false, 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/collector.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::time::{Duration, Instant}; 3 | 4 | use lazy_static::lazy_static; 5 | use parking_lot::{Mutex, MutexGuard}; 6 | use serde::{Deserialize, Serialize}; 7 | use serde_json::{json, Value}; 8 | use sysinfo::{CpuExt, DiskExt, SystemExt}; 9 | use time::OffsetDateTime; 10 | 11 | lazy_static! { 12 | static ref SINGLETON: Mutex = Mutex::new(Collector::new()); 13 | } 14 | /** 15 | Provide singleton collector. 16 | */ 17 | pub fn singleton() -> MutexGuard<'static, Collector> { 18 | SINGLETON.lock() 19 | } 20 | 21 | /** 22 | The system report as Postgres-friendly types. Note that all memory and disk 23 | sizes are stored as `f64`, which allows for exact representation of up to 24 | 8192 terabytes. 25 | */ 26 | #[derive(Clone, Debug, Deserialize, Serialize)] 27 | pub struct Report { 28 | pub load: Load, 29 | pub at: time::OffsetDateTime, 30 | pub cpu_usage: f64, 31 | pub memory: Memory, 32 | pub swap: Memory, 33 | pub volumes: Vec, 34 | } 35 | 36 | impl Report { 37 | pub fn rows(&self) -> Vec<(String, Value, OffsetDateTime, f64)> { 38 | report_rows(self) 39 | } 40 | } 41 | 42 | fn report_rows(r: &Report) -> Vec<(String, Value, OffsetDateTime, f64)> { 43 | let ownerize = |v: Vec<(&str, &Value, OffsetDateTime, f64)>| -> Vec<_> { 44 | v.into_iter() 45 | .map(|(a, b, c, d)| (String::from(a), b.clone(), c, d)) 46 | .collect() 47 | }; 48 | let empty = json!({}); 49 | let duration1m = json!({"duration": "1m"}); 50 | let duration5m = json!({"duration": "5m"}); 51 | let duration15m = json!({"duration": "15m"}); 52 | let mut result = ownerize(vec![ 53 | ("load_average", &duration1m, r.at, r.load.min1), 54 | ("load_average", &duration5m, r.at, r.load.min5), 55 | ("load_average", &duration15m, r.at, r.load.min15), 56 | ("cpu_usage", &empty, r.at, r.cpu_usage), 57 | ("memory_usage", &empty, r.at, r.memory.usage), 58 | ("memory_size", &empty, r.at, r.memory.size), 59 | ("memory_available", &empty, r.at, r.memory.available), 60 | ("swap_usage", &empty, r.at, r.swap.usage), 61 | ("swap_size", &empty, r.at, r.swap.size), 62 | ("swap_available", &empty, r.at, r.swap.available), 63 | ]); 64 | 65 | for vol in &r.volumes { 66 | let dims = json!({ "fs": vol.name }); 67 | result.append(&mut ownerize(vec![ 68 | ("disk_usage", &dims, r.at, vol.usage), 69 | ("disk_size", &dims, r.at, vol.size), 70 | ("disk_available", &dims, r.at, vol.available), 71 | ])); 72 | } 73 | 74 | result 75 | } 76 | 77 | /** 78 | The collector manages system caches and reporting. 79 | */ 80 | pub struct Collector { 81 | client: sysinfo::System, 82 | last_refresh: Option, 83 | } 84 | 85 | impl Collector { 86 | pub fn new() -> Self { 87 | Collector { 88 | client: sysinfo::System::new(), 89 | last_refresh: None, 90 | } 91 | } 92 | 93 | pub fn report(&mut self) -> Report { 94 | if self.last_refresh.is_none() { 95 | self.cache_initialization(); 96 | } 97 | 98 | self.refresh(); 99 | 100 | let at = OffsetDateTime::now_utc(); 101 | 102 | let load_average = self.client.load_average(); 103 | 104 | let disks = self.client.disks(); 105 | let volumes = disks.iter().map(VolumeInfo::from).collect(); 106 | 107 | let memory = Memory::from_total_and_available( 108 | self.client.total_memory(), 109 | // Why this stat: free means memory that is not used for anything, 110 | // whereas available means memory that can be allocated, including 111 | // by flushing cache or buffers. This seems to be more indicative 112 | // of the real system state. 113 | self.client.available_memory(), 114 | ); 115 | let swap = Memory::from_total_and_available( 116 | self.client.total_swap(), 117 | // NB: No `available_swap` statistic. 118 | self.client.free_swap(), 119 | ); 120 | 121 | let cpu_usage = self.client.global_cpu_info().cpu_usage() as f64; 122 | 123 | Report { 124 | load: Load { 125 | min1: load_average.one, 126 | min5: load_average.five, 127 | min15: load_average.fifteen, 128 | }, 129 | at, 130 | cpu_usage, 131 | memory, 132 | swap, 133 | volumes, 134 | } 135 | } 136 | 137 | // Anything that needs to be run before taking the first real measurements. 138 | pub fn cache_initialization(&mut self) { 139 | self.discover_new_disks(); 140 | self.client.refresh_cpu(); 141 | self.last_refresh = Some(Instant::now()); 142 | } 143 | 144 | pub fn is_initialized(&self) -> bool { 145 | self.last_refresh.is_some() 146 | } 147 | 148 | fn refresh(&mut self) { 149 | if let Some(dur) = self.cpu_safe_sleep() { 150 | thread::sleep(dur); 151 | } 152 | // All of these seem to be implemented in a way that is relatively 153 | // fault tolerant. For example, if a disk was removed and can not be 154 | // refreshed, it simply won't be updated. 155 | self.client.refresh_cpu(); 156 | self.client.refresh_disks(); 157 | self.client.refresh_memory(); 158 | 159 | self.last_refresh = Some(Instant::now()); 160 | } 161 | 162 | fn cpu_safe_sleep(&self) -> Option { 163 | let zero = Duration::new(0, 0); 164 | let now = Instant::now(); 165 | let passed = self.last_refresh.map(|t| now - t).unwrap_or(zero); 166 | 167 | sysinfo::System::MINIMUM_CPU_UPDATE_INTERVAL.checked_sub(passed) 168 | } 169 | 170 | // This should be run once in an awhile, or due to device events or 171 | // something of that nature. 172 | pub fn discover_new_disks(&mut self) { 173 | self.client.refresh_disks_list(); 174 | } 175 | } 176 | 177 | #[derive(Clone, Debug, Deserialize, Serialize)] 178 | pub struct VolumeInfo { 179 | pub name: String, 180 | pub size: f64, 181 | pub available: f64, 182 | pub usage: f64, 183 | } 184 | 185 | impl From<&sysinfo::Disk> for VolumeInfo { 186 | fn from(disk: &sysinfo::Disk) -> Self { 187 | let name = disk.mount_point().to_string_lossy().into_owned(); 188 | let size = disk.total_space() as f64; 189 | let available = disk.available_space() as f64; 190 | let usage = usage_percent(size, available); 191 | 192 | VolumeInfo { 193 | name, 194 | size, 195 | available, 196 | usage, 197 | } 198 | } 199 | } 200 | 201 | #[derive(Clone, Debug, Deserialize, Serialize)] 202 | pub struct Load { 203 | pub min1: f64, 204 | pub min5: f64, 205 | pub min15: f64, 206 | } 207 | 208 | #[derive(Clone, Debug, Deserialize, Serialize)] 209 | pub struct Memory { 210 | pub size: f64, 211 | pub available: f64, 212 | pub usage: f64, 213 | } 214 | 215 | impl Memory { 216 | fn from_total_and_available(size: u64, available: u64) -> Self { 217 | let size = size as f64; 218 | let available = available as f64; 219 | let usage = usage_percent(size, available); 220 | 221 | Memory { 222 | size, 223 | available, 224 | usage, 225 | } 226 | } 227 | } 228 | 229 | fn usage_percent(size: f64, available: f64) -> f64 { 230 | 100.0 231 | * if size > 0.0 { 232 | 1.0 - available / size 233 | } else { 234 | 0.0 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /src/crate_info.rs: -------------------------------------------------------------------------------- 1 | // TODO: Pull from Cargo somehow? 2 | pub const CRATE: &str = "pg_stat_sysinfo"; 3 | -------------------------------------------------------------------------------- /src/init.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::CStr; 2 | 3 | use pgrx::pg_sys::{GetBackendTypeDesc, MyBackendType}; 4 | use pgrx::*; 5 | 6 | use crate::cache_worker; 7 | use crate::crate_info::*; 8 | use crate::settings; 9 | 10 | #[pg_guard] 11 | pub extern "C" fn _PG_init() { 12 | let backend_type = backend_type(); 13 | 14 | debug1!( 15 | "{}: Running _PG_init() in backend of type: {}", 16 | CRATE, 17 | backend_type 18 | ); 19 | 20 | settings::define(); 21 | cache_worker::start(); 22 | } 23 | 24 | pub fn backend_type() -> String { 25 | let s = unsafe { 26 | let chars = GetBackendTypeDesc(MyBackendType); 27 | CStr::from_ptr(chars) 28 | }; 29 | String::from_utf8_lossy(s.to_bytes()).to_string() 30 | } 31 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Something about the #[pg_extern] TableIterator functions is confusing to 2 | // Clippy. 3 | #![allow(clippy::useless_conversion)] 4 | 5 | use pgrx::prelude::*; 6 | use pgrx::*; 7 | use serde_json::Value; 8 | use time::OffsetDateTime; 9 | 10 | mod cache_worker; 11 | mod collector; 12 | mod crate_info; 13 | mod init; 14 | mod settings; 15 | mod shmem_ring_buffer; 16 | 17 | pgrx::pg_module_magic!(); 18 | 19 | #[pg_extern(stable)] 20 | fn pg_stat_sysinfo_collect() -> TableIterator< 21 | 'static, 22 | ( 23 | name!(metric, String), 24 | name!(dimensions, JsonB), 25 | name!(at, TimestampWithTimeZone), 26 | name!(value, f64), 27 | ), 28 | > { 29 | let mut instance = collector::singleton(); 30 | 31 | if !instance.is_initialized() { 32 | notice!("Initializing system information caches."); 33 | instance.cache_initialization(); 34 | } 35 | 36 | let report = instance.report().rows(); 37 | 38 | maprows(report.into_iter()) 39 | } 40 | 41 | #[pg_extern(stable)] 42 | fn pg_stat_sysinfo_cache_summary( 43 | ) -> TableIterator<'static, (name!(bytes_used, i64), name!(items, i64))> { 44 | let info = cache_worker::cache_info(); 45 | let translated = (info.bytes_used as i64, info.items as i64); 46 | 47 | TableIterator::new(vec![translated].into_iter()) 48 | } 49 | 50 | #[pg_extern(stable)] 51 | fn pg_stat_sysinfo_cached() -> TableIterator< 52 | 'static, 53 | ( 54 | name!(metric, String), 55 | name!(dimensions, JsonB), 56 | name!(at, TimestampWithTimeZone), 57 | name!(value, f64), 58 | ), 59 | > { 60 | let reports = cache_worker::reports(); 61 | let rows = reports.iter().flat_map(|report| report.rows()); 62 | #[allow(clippy::needless_collect)] 63 | let v: Vec<_> = rows.collect(); 64 | 65 | maprows(v.into_iter()) 66 | } 67 | 68 | extension_sql!( 69 | r#" 70 | CREATE VIEW pg_stat_sysinfo AS 71 | SELECT * FROM pg_stat_sysinfo_cached() 72 | ORDER BY at DESC; 73 | "#, 74 | name = "create_view", 75 | requires = [pg_stat_sysinfo_cached] 76 | ); 77 | 78 | fn maprows<'a, I: Iterator + 'a>( 79 | iter: I, 80 | ) -> TableIterator< 81 | 'a, 82 | ( 83 | name!(metric, String), 84 | name!(dimensions, JsonB), 85 | name!(at, TimestampWithTimeZone), 86 | name!(value, f64), 87 | ), 88 | > { 89 | let translated = iter.filter_map(|(metric, dimensions, at, value)| { 90 | match TimestampWithTimeZone::try_from(at) { 91 | Ok(tstz) => Some((metric, JsonB(dimensions), tstz, value)), 92 | Err(_err) => { 93 | warning!("Failed to translate timestamp: {:?}", at); 94 | None 95 | } 96 | } 97 | }); 98 | 99 | TableIterator::new(translated) 100 | } 101 | -------------------------------------------------------------------------------- /src/settings.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::{c_char, CStr}; 2 | use std::ptr; 3 | 4 | use anyhow::anyhow; 5 | use pgrx::*; 6 | use std::time::Duration; 7 | 8 | use crate::crate_info::CRATE; 9 | 10 | #[derive(Debug, Default)] 11 | pub struct Settings { 12 | pub interval: Option, 13 | } 14 | 15 | pub static INTERVAL: GucSetting> = GucSetting::new(None); 16 | 17 | pub fn define() { 18 | GucRegistry::define_string_guc( 19 | &format!("{CRATE}.interval"), 20 | "The interval at which to collect metrics.", 21 | "A background worker wakes up every interval and gathers statistics.", 22 | &INTERVAL, 23 | GucContext::Sighup, 24 | GucFlags::UNIT_S, 25 | ); 26 | } 27 | 28 | pub fn read() -> anyhow::Result { 29 | let seconds = unsafe { 30 | let name = format!("{CRATE}.interval"); 31 | let input: *const c_char = INTERVAL.get_char_ptr(); 32 | 33 | if input.is_null() { 34 | Ok(None) 35 | } else { 36 | debug1!("{}: {} = {:?}", CRATE, name, CStr::from_ptr(input)); 37 | let mut hintmsg: *const c_char = ptr::null(); 38 | let mut seconds: f64 = 0.0; 39 | let flags = pg_sys::GUC_UNIT_S as i32; 40 | if pg_sys::parse_real(input, &mut seconds, flags, &mut hintmsg) { 41 | Ok(Some(seconds)) 42 | } else { 43 | let hint = CStr::from_ptr(hintmsg); 44 | let s = hint.to_string_lossy(); 45 | Err(anyhow!("Error parsing {}: {}", &name, &s)) 46 | } 47 | } 48 | }?; 49 | 50 | let interval = seconds.map(from_float_seconds); 51 | 52 | Ok(Settings { interval }) 53 | } 54 | 55 | pub fn read_or_default() -> Settings { 56 | match read() { 57 | Ok(settings) => settings, 58 | Err(e) => { 59 | warning!("{}: Failed to parse settings: {:?}", CRATE, e); 60 | Settings::default() 61 | } 62 | } 63 | } 64 | 65 | fn from_float_seconds(seconds: f64) -> Duration { 66 | Duration::from_micros((seconds * 1000000.0) as u64) 67 | } 68 | -------------------------------------------------------------------------------- /src/shmem_ring_buffer.rs: -------------------------------------------------------------------------------- 1 | use std::default::Default; 2 | use std::io::BufReader; 3 | use std::marker::PhantomData; 4 | 5 | use anyhow::anyhow; 6 | use pgrx::*; 7 | use serde::de::DeserializeOwned; 8 | use serde::Serialize; 9 | 10 | use crate::crate_info::CRATE; 11 | 12 | const ONE_KB: usize = 1024; 13 | const PAGE_SIZE: usize = 256 * ONE_KB; 14 | // const PAGE_SIZE: usize = 1 * ONE_KB; 15 | const PAGES: usize = 5; 16 | 17 | /** 18 | The ring buffer is statically allocated, broken into pages of a fixed size. 19 | Objects are serialized into to the buffer. When the last page is full, 20 | the first page is cleared and all the pages are rotated so that the first 21 | page is last, the last page is second to last, and so on. 22 | */ 23 | pub type ShmemRingBuffer = ShmemBackedSerdeRingBuffer; 24 | 25 | #[derive(Clone, Debug)] 26 | pub struct ShmemBackedSerdeRingBuffer< 27 | const N: usize, 28 | const M: usize, 29 | T: Serialize + DeserializeOwned, 30 | > { 31 | data: heapless::Vec, M>, 32 | counts: heapless::Vec, 33 | _phantom: PhantomData, 34 | } 35 | 36 | impl 37 | ShmemBackedSerdeRingBuffer 38 | { 39 | /** 40 | Writes objects as JSON to the ring buffer. 41 | */ 42 | pub fn write(&mut self, item: T) -> anyhow::Result<()> { 43 | let last = self.data.last().expect("No cache pages?"); 44 | let (used, capacity) = (last.len(), last.capacity()); 45 | 46 | let mut encoded = Vec::new(); 47 | serde_bare::to_writer(&mut encoded, &item)?; 48 | 49 | if capacity / 2 < encoded.len() { 50 | // Although it could fit, objects should never be this big; 51 | // something is wrong; and if they get too much bigger, it will 52 | // prevent the rotation from working. 53 | return Err(anyhow!( 54 | "Object is too large ({} bytes) for rings of {} bytes.", 55 | encoded.len(), 56 | capacity 57 | )); 58 | } 59 | 60 | if (used + encoded.len() + 2) >= capacity { 61 | self.data.rotate_left(1); 62 | self.counts.rotate_left(1); 63 | 64 | if !self.data.last().expect("No cache pages?").is_empty() { 65 | let was = self.stats(); 66 | self.data.last_mut().expect("No cache pages?").clear(); 67 | *self.counts.last_mut().expect("No counts?") = 0; 68 | let is = self.stats(); 69 | debug1!( 70 | "{}: Rotated buffer -- cleared one page. \ 71 | usage: {} -> {} | items: {} -> {} | bytes/item: {} -> {}", 72 | CRATE, 73 | bytesize::to_string(was.bytes_used as u64, true), 74 | bytesize::to_string(is.bytes_used as u64, true), 75 | was.items, 76 | is.items, 77 | was.item_average_bytes, 78 | is.item_average_bytes, 79 | ); 80 | } 81 | } 82 | 83 | let err = |_| anyhow!("Failure to extend: heapless::Vec"); 84 | let real_last = self.data.last_mut().expect("No cache pages?"); 85 | real_last.extend_from_slice(&encoded).map_err(err)?; 86 | *self.counts.last_mut().expect("No counts?") += 1; 87 | 88 | Ok(()) 89 | } 90 | 91 | pub fn read(&self) -> Vec { 92 | let mut results: Vec = vec![]; 93 | 94 | for page in &self.data { 95 | let mut reader = BufReader::new(page.as_slice()); 96 | let mut error: Option<_> = None; 97 | 98 | while error.is_none() { 99 | match serde_bare::from_reader(&mut reader) { 100 | Ok(item) => { 101 | results.push(item); 102 | } 103 | Err(err) => { 104 | error = Some(err); 105 | // TODO: Distinguish real errors and the "error" of 106 | // reaching the end of the buffer. 107 | } 108 | } 109 | } 110 | } 111 | 112 | results 113 | } 114 | 115 | pub fn stats(&self) -> BufferSummary { 116 | let items = self.counts.iter().sum(); 117 | let bytes_used = self.data.iter().map(|v| v.len()).sum(); 118 | let item_average_bytes = (bytes_used as f64 / items as f64) as f32; 119 | 120 | BufferSummary { 121 | items, 122 | bytes_used, 123 | item_average_bytes, 124 | } 125 | } 126 | } 127 | 128 | impl Default 129 | for ShmemBackedSerdeRingBuffer 130 | { 131 | fn default() -> Self { 132 | let _phantom = PhantomData; 133 | let mut data = heapless::Vec::default(); 134 | let mut counts = heapless::Vec::default(); 135 | for _ in 0..data.capacity() { 136 | let msg = "Pushing too many elements here is impossible."; 137 | data.push(heapless::Vec::default()).expect(msg); 138 | counts.push(0).expect(msg); 139 | } 140 | ShmemBackedSerdeRingBuffer { 141 | data, 142 | counts, 143 | _phantom, 144 | } 145 | } 146 | } 147 | 148 | #[derive(Clone, Debug, Default)] 149 | pub struct BufferSummary { 150 | pub items: usize, 151 | pub bytes_used: usize, 152 | pub item_average_bytes: f32, 153 | } 154 | --------------------------------------------------------------------------------