diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7a07c2e4587e68248f4a0f272ff169d7ebde4d45..1a65f141496e8852187bd9528e0411480c550378 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -60,7 +60,7 @@ jobs:
           command: build
           use-cross: ${{ matrix.job.use-cross }}
           toolchain: ${{ matrix.rust }}
-          args: --release --features=all --target ${{ matrix.job.target }}
+          args: --release --features=all,metrics --target ${{ matrix.job.target }}
 
       - name: install strip command
         shell: bash
diff --git a/Cargo.lock b/Cargo.lock
index 99adcf2054ade0782360e0ede7912d5e918bc3d9..b7636517249376d030c1ac3aca38701996addf0b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16,7 +16,7 @@ dependencies = [
  "memchr",
  "pin-project-lite",
  "tokio",
- "tokio-util 0.7.0",
+ "tokio-util 0.7.1",
 ]
 
 [[package]]
@@ -125,7 +125,7 @@ dependencies = [
  "actix-utils",
  "futures-core",
  "futures-util",
- "mio 0.8.0",
+ "mio 0.8.2",
  "num_cpus",
  "socket2",
  "tokio",
@@ -189,7 +189,7 @@ dependencies = [
  "serde_urlencoded",
  "smallvec",
  "socket2",
- "time 0.3.7",
+ "time 0.3.9",
  "url",
 ]
 
@@ -205,6 +205,18 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "actix-web-prom"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9df3127d20a5d01c9fc9aceb969a38d31a6767e1b48a54d55a8f56c769a84923"
+dependencies = [
+ "actix-web",
+ "futures-core",
+ "pin-project-lite",
+ "prometheus",
+]
+
 [[package]]
 name = "adler"
 version = "1.0.2"
@@ -321,9 +333,9 @@ checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9"
 
 [[package]]
 name = "async-trait"
-version = "0.1.52"
+version = "0.1.53"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3"
+checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -451,9 +463,9 @@ dependencies = [
 
 [[package]]
 name = "brotli"
-version = "3.3.3"
+version = "3.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f838e47a451d5a8fa552371f80024dd6ace9b7acdf25c4c3d0f9bc6816fb1c39"
+checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -608,7 +620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05"
 dependencies = [
  "percent-encoding",
- "time 0.3.7",
+ "time 0.3.9",
  "version_check",
 ]
 
@@ -636,9 +648,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
+checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
 dependencies = [
  "libc",
 ]
@@ -669,9 +681,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.2"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
+checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
@@ -679,9 +691,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-queue"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dd435b205a4842da59efd07628f921c096bc1cc0a156835b4fa0bcb9a19bcce"
+checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
@@ -689,9 +701,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.7"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
+checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
 dependencies = [
  "cfg-if",
  "lazy_static",
@@ -800,9 +812,9 @@ dependencies = [
 
 [[package]]
 name = "dirs-sys"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
 dependencies = [
  "libc",
  "redox_users",
@@ -890,9 +902,9 @@ dependencies = [
 
 [[package]]
 name = "flume"
-version = "0.10.11"
+version = "0.10.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b279436a715a9de95dcd26b151db590a71961cc06e54918b24fe0dd5b7d3fc4"
+checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1064,20 +1076,20 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
+checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.10.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "h2"
-version = "0.3.12"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b"
+checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
 dependencies = [
  "bytes",
  "fnv",
@@ -1088,7 +1100,7 @@ dependencies = [
  "indexmap",
  "slab",
  "tokio",
- "tokio-util 0.6.9",
+ "tokio-util 0.7.1",
  "tracing",
 ]
 
@@ -1223,9 +1235,9 @@ dependencies = [
 
 [[package]]
 name = "hyper"
-version = "0.14.17"
+version = "0.14.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd"
+checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -1271,9 +1283,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
+checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
 dependencies = [
  "autocfg 1.1.0",
  "hashbrown",
@@ -1376,9 +1388,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.119"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
+checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
 
 [[package]]
 name = "libm"
@@ -1417,18 +1429,19 @@ checksum = "902eb695eb0591864543cbfbf6d742510642a605a61fc5e97fe6ceb5a30ac4fb"
 
 [[package]]
 name = "lock_api"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
+checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
 dependencies = [
+ "autocfg 1.1.0",
  "scopeguard",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.14"
+version = "0.4.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
 dependencies = [
  "cfg-if",
 ]
@@ -1518,14 +1531,15 @@ dependencies = [
 
 [[package]]
 name = "mio"
-version = "0.8.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2"
+checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
 dependencies = [
  "libc",
  "log",
  "miow",
  "ntapi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
  "winapi",
 ]
 
@@ -1575,9 +1589,9 @@ dependencies = [
 
 [[package]]
 name = "native-tls"
-version = "0.2.8"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
+checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9"
 dependencies = [
  "lazy_static",
  "libc",
@@ -1593,13 +1607,12 @@ dependencies = [
 
 [[package]]
 name = "nom"
-version = "7.1.0"
+version = "7.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
 dependencies = [
  "memchr",
  "minimal-lexical",
- "version_check",
 ]
 
 [[package]]
@@ -1683,9 +1696,9 @@ dependencies = [
 
 [[package]]
 name = "num_threads"
-version = "0.1.3"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15"
+checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0"
 dependencies = [
  "libc",
 ]
@@ -1730,9 +1743,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
 name = "openssl-src"
-version = "111.17.0+1.1.1m"
+version = "111.18.0+1.1.1n"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05d6a336abd10814198f66e2a91ccd7336611f30334119ca8ce300536666fcf4"
+checksum = "7897a926e1e8d00219127dc020130eca4292e5ca666dd592480d72c3eca2ff6c"
 dependencies = [
  "cc",
 ]
@@ -1769,7 +1782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.1",
+ "parking_lot_core 0.9.2",
 ]
 
 [[package]]
@@ -1788,9 +1801,9 @@ dependencies = [
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.1"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954"
+checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
 dependencies = [
  "cfg-if",
  "libc",
@@ -1801,9 +1814,9 @@ dependencies = [
 
 [[package]]
 name = "paste"
-version = "1.0.6"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
+checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
 
 [[package]]
 name = "pem"
@@ -1943,9 +1956,9 @@ dependencies = [
 
 [[package]]
 name = "pkg-config"
-version = "0.3.24"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
+checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
 
 [[package]]
 name = "ppv-lite86"
@@ -1992,6 +2005,27 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "prometheus"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7f64969ffd5dd8f39bd57a68ac53c163a095ed9d0fb707146da1b27025a3504"
+dependencies = [
+ "cfg-if",
+ "fnv",
+ "lazy_static",
+ "memchr",
+ "parking_lot 0.11.2",
+ "protobuf",
+ "thiserror",
+]
+
+[[package]]
+name = "protobuf"
+version = "2.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96"
+
 [[package]]
 name = "py_sql"
 version = "1.0.1"
@@ -2006,9 +2040,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.15"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
+checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58"
 dependencies = [
  "proc-macro2",
 ]
@@ -2073,9 +2107,9 @@ dependencies = [
 
 [[package]]
 name = "rbatis"
-version = "3.1.1"
+version = "3.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8713306748b70f300b4f95a3155d1ea2b559ebe3dca6c0e6aa02788e83d2b19"
+checksum = "0a6696fb4732261ee61307d99b8a3d9e4178eee837593f7e43c0b28cd8558b1f"
 dependencies = [
  "async-trait",
  "chrono",
@@ -2095,9 +2129,9 @@ dependencies = [
 
 [[package]]
 name = "rbatis-core"
-version = "3.0.21"
+version = "3.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac21224137c4c885210ab3fd659ecd440806de10ea49ce43461d83acf3d54c1a"
+checksum = "b11a31670a18f9229481027358e77ff7828c501c4e834f629ab46bc60dad87ea"
 dependencies = [
  "base64",
  "bigdecimal",
@@ -2119,9 +2153,9 @@ dependencies = [
 
 [[package]]
 name = "rbatis-macro-driver"
-version = "3.1.0"
+version = "3.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7599aab108652a411f5cebd41a4640f3ca42a781c1964afb30d9e6bc3e1cecef"
+checksum = "1d8f48a4f8e6c2aca6b528fd613362199ae1d3266fd3cb38a11aebff88a379ec"
 dependencies = [
  "html_parser",
  "proc-macro2",
@@ -2131,9 +2165,9 @@ dependencies = [
 
 [[package]]
 name = "rbatis_sql"
-version = "3.0.13"
+version = "3.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3852b627d81d1e2d8313b024d899190baaf8e75429f5d49e842a0bdac77474c4"
+checksum = "bd41bd85af47c69fde29e2654df87307a234b52f0a2152e7797331d47bb43f69"
 dependencies = [
  "async-trait",
  "base64",
@@ -2145,9 +2179,9 @@ dependencies = [
 
 [[package]]
 name = "rbatis_sql_macro"
-version = "3.0.7"
+version = "3.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5050d3450a18cb42f377c8881df476fd33e6a65df28309bf8be08995ac8e4935"
+checksum = "98b73d4dd3555bb3d0aceccf768d595593b4b74db242c0e0bb054d4ba58b939f"
 dependencies = [
  "async-trait",
  "base64",
@@ -2209,21 +2243,22 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.11"
+version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
+checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "redox_users"
-version = "0.4.0"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
 dependencies = [
  "getrandom",
  "redox_syscall",
+ "thiserror",
 ]
 
 [[package]]
@@ -2260,9 +2295,9 @@ dependencies = [
 
 [[package]]
 name = "reqwest"
-version = "0.11.9"
+version = "0.11.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525"
+checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb"
 dependencies = [
  "base64",
  "bytes",
@@ -2342,9 +2377,9 @@ dependencies = [
 
 [[package]]
 name = "rust_decimal"
-version = "1.22.0"
+version = "1.23.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d37baa70cf8662d2ba1c1868c5983dda16ef32b105cce41fb5c47e72936a90b3"
+checksum = "22dc69eadbf0ee2110b8d20418c0c6edbaefec2811c4963dc17b6344e11fe0f8"
 dependencies = [
  "arrayvec",
  "num-traits",
@@ -2366,7 +2401,7 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
 dependencies = [
- "semver 1.0.6",
+ "semver 1.0.7",
 ]
 
 [[package]]
@@ -2384,11 +2419,12 @@ dependencies = [
 
 [[package]]
 name = "rustus"
-version = "0.4.10"
+version = "0.4.11"
 dependencies = [
  "actix-files",
  "actix-rt",
  "actix-web",
+ "actix-web-prom",
  "async-trait",
  "base64",
  "bytes",
@@ -2405,6 +2441,7 @@ dependencies = [
  "mobc-lapin",
  "mobc-redis",
  "openssl",
+ "prometheus",
  "rbatis",
  "rbson",
  "reqwest",
@@ -2495,9 +2532,9 @@ dependencies = [
 
 [[package]]
 name = "semver"
-version = "1.0.6"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
+checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
 
 [[package]]
 name = "semver-parser"
@@ -2655,9 +2692,9 @@ dependencies = [
 
 [[package]]
 name = "slab"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
+checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
 
 [[package]]
 name = "smallvec"
@@ -2920,9 +2957,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "syn"
-version = "1.0.86"
+version = "1.0.90"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
+checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3013,7 +3050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
 dependencies = [
  "libc",
- "wasi",
+ "wasi 0.10.0+wasi-snapshot-preview1",
  "winapi",
 ]
 
@@ -3035,14 +3072,14 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.7"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
 dependencies = [
  "itoa 1.0.1",
  "libc",
  "num_threads",
- "time-macros 0.2.3",
+ "time-macros 0.2.4",
 ]
 
 [[package]]
@@ -3057,9 +3094,9 @@ dependencies = [
 
 [[package]]
 name = "time-macros"
-version = "0.2.3"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
+checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
 
 [[package]]
 name = "time-macros-impl"
@@ -3098,7 +3135,7 @@ dependencies = [
  "bytes",
  "libc",
  "memchr",
- "mio 0.8.0",
+ "mio 0.8.2",
  "num_cpus",
  "once_cell",
  "parking_lot 0.12.0",
@@ -3179,16 +3216,16 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.7.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64910e1b9c1901aaf5375561e35b9c057d95ff41a44ede043a03e09279eabaf1"
+checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
 dependencies = [
  "bytes",
  "futures-core",
  "futures-sink",
- "log",
  "pin-project-lite",
  "tokio",
+ "tracing",
 ]
 
 [[package]]
@@ -3206,14 +3243,26 @@ dependencies = [
  "cfg-if",
  "log",
  "pin-project-lite",
+ "tracing-attributes",
  "tracing-core",
 ]
 
+[[package]]
+name = "tracing-attributes"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "tracing-core"
-version = "0.1.23"
+version = "0.1.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c"
+checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee"
 dependencies = [
  "lazy_static",
 ]
@@ -3355,6 +3404,12 @@ version = "0.10.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
 
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
 [[package]]
 name = "wasm-bindgen"
 version = "0.2.79"
@@ -3484,9 +3539,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
 name = "windows-sys"
-version = "0.32.0"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
+checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
 dependencies = [
  "windows_aarch64_msvc",
  "windows_i686_gnu",
@@ -3497,39 +3552,39 @@ dependencies = [
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.32.0"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
+checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.32.0"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
+checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.32.0"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
+checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.32.0"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
+checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.32.0"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
+checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
 
 [[package]]
 name = "winreg"
-version = "0.7.0"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
 dependencies = [
  "winapi",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 0d8e3d786f84bac0eb5fc385df0e88a1e3c7ebe1..56dabcb73cd27a9ac6c7df9305af3b932f562ab6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rustus"
-version = "0.4.10"
+version = "0.4.11"
 edition = "2021"
 description = "TUS protocol implementation written in Rust."
 keywords = [
@@ -30,6 +30,8 @@ strfmt = "^0.1.6"
 thiserror = "^1.0"
 url = "^2.2.2"
 bytes = "^1.1.0"
+prometheus = "^0.13.0"
+actix-web-prom = "^0.6.0"
 
 [dependencies.digest]
 version = "0.10.3"
@@ -133,6 +135,7 @@ default = []
 http_notifier = ["reqwest"]
 redis_info_storage = ["mobc-redis"]
 hashers = ["md-5", "sha1", "sha2", "digest"]
+metrics = []
 
 ### For testing
 test_redis = []
diff --git a/README.md b/README.md
index 94837937d791f0bc8371c4e073c650c3e9f66ecb..d82157f3e6dca39f8b8ed9db3e824dae654bb740 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
 This implementation has several features to make usage as simple as possible.
 
 * Rustus is robust, since it uses asynchronous Rust;
-* It can store information about files in databases;
+* It can store information about uploads in databases;
 * You can specify directory structure to organize your uploads;
 * It has a lot of hooks options, and hooks can be combined.
 * Highly configurable;
@@ -33,7 +33,7 @@ Preferred version is 1.59.0.
 ```bash
 git clone https://github.com/s3rius/rustus.git
 cd rustus
-cargo install --path . --features=all
+cargo install --path . --features=all,metrics
 ```
 Also you can speedup build by disabling some features.
 
@@ -44,7 +44,8 @@ Available features:
 * `http_notifier` - adds support for notifying about upload status via http protocol;
 * `redis_info_storage` - adds support for storing information about upload in redis database;
 * `hashers` - adds support for checksum verification;
-* `all` - enables all rustus features.
+* `metrics` - adds rustus specific metrics to prometheus endpoint;
+* `all` - enables all rustus features except `metrics`.
 
 All precompiled binaries have all features enabled.
 
diff --git a/deploy/Dockerfile b/deploy/Dockerfile
index 4fca83a51e82e2558cda1acd829e99b23368a90c..acd2de40abef2f59e3b7839c4ac7eacc6e8555e4 100644
--- a/deploy/Dockerfile
+++ b/deploy/Dockerfile
@@ -8,7 +8,7 @@ RUN cargo chef prepare --recipe-path recipe.json
 FROM chef AS builder
 COPY --from=planner /app/recipe.json recipe.json
 # Build dependencies - this is the caching Docker layer!
-RUN cargo chef cook --release --features=all --recipe-path recipe.json
+RUN cargo chef cook --release --features=all,metrics --recipe-path recipe.json
 # Build application
 COPY . .
 RUN cargo build --release --bin rustus --features=all
diff --git a/docs/configuration.md b/docs/configuration.md
index 5e6f7f71b4760037d1c9784d7a81b8dc57c4e5b7..9f7bf213ea93f0524269edabde783dd072b0a286 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -3,13 +3,12 @@ title: Configuration
 description: "How to configure Rusts"
 ---
 
-Rustus is highly configurable you can configure rustus with CLI or you can use environment variables.
+Rustus is highly configurable. You can adjust it with CLI or you can use environment variables.
 
-!!! info
+!!! warning
     Some options can be passed only through as CLI parameters
 
 !!! info
-
     Information about hooks you can find on [Hooks page](../hooks).
 
 
@@ -126,7 +125,7 @@ about it requested from storage to get actual path of an upload.
 Available info storages:
 
 * `file-info-storage` - stores information in files on disk;
-* `redis-info-storage` - information is stored in redis;
+* `redis-info-storage` - information is stored in Redis;
 * `db-info-storage` - information is stored in database;
 
 ### File info storage
@@ -142,8 +141,7 @@ storing information about uploads. But if you don't plan to have many uploads, i
 === "CLI"
 
     ``` bash
-    rustus --force-fsync \
-        --storage "file-info-storage" \
+    rustus --info-storage "file-info-storage" \
         --info-dir "./data"
     ```
 
@@ -162,18 +160,17 @@ Redis db is a good way to store information.
 
 !!! note
 
-    If you're using redis as a cluster
-    you must provide connection string for master redis server.
+    If you're using Redis as a cluster
+    you must provide connection string for master Redis server.
     Since rustus need to have latest information and it writes a lot.
 
-`--info-db-dsn` - connection string for your redis database.
-It's required if redis-info-storage is chosen.
+`--info-db-dsn` - connection string for your Redis database.
+It's required if `redis-info-storage` is chosen.
 
 === "CLI"
 
     ``` bash
-    rustus --force-fsync \
-        --storage "redis-info-storage" \
+    rustus --info-storage "redis-info-storage" \
         --info-db-dsn "redis://localhost/0"
     ```
 
@@ -189,10 +186,10 @@ It's required if redis-info-storage is chosen.
 
 ### DB info storage
 
-Rustus can store information about upload in database.
+Rustus can store information about upload in a database.
 
-It's a good and reliable option. But rustus can't work
-with replicas since it requires most recent information
+It's a good and reliable option. But Rustus can't work
+with replicas, since it requires the most recent information
 about uploads.
 
 You can use `postgresql`, `mysql` or even `sqlite` schemas to
@@ -203,8 +200,7 @@ connect to database.
 === "CLI"
 
     ``` bash
-    rustus --force-fsync \
-        --storage "db-info-storage" \
+    rustus --info-storage "db-info-storage" \
         --info-db-dsn "postgresql://user:password@localhost/db"
     ```
 
@@ -219,11 +215,11 @@ connect to database.
 
 ## Configuring TUS
 
-Since tus protocol offers extensibility you can turn off some protocol extensions.
+Since TUS protocol offers extensibility you can turn off some protocol extensions.
 
 Available extensions:
 
-* `getting` - rustus specific extension that helps you download uploaded files with get request;
+* `getting` - Rustus specific extension that helps you download uploaded files with get request;
 * `creation` - helps you to create files (It's like a core feature you better have this enabled);
 * `termination` - allows you to delete uploads with DELETE request;
 * `creation-with-upload` - allows you to write first bytes of a file while creating;
@@ -234,13 +230,15 @@ Available extensions:
 You can read more about extensions on [official web-site](https://tus.io/protocols/resumable-upload.html#protocol-extensions).
 
 `--tus-extensions` - a list of enabled extensions.
+`--remove-parts` - remove parts files after successfull concatentation (disabled by default).
 
 By default all extensions are enabled.
 
 === "CLI"
 
     ``` bash
-    rustus --tus-extensions "getting,creation,termination,creation-with-upload,creation-defer-length,concatenation,checksum"
+    rustus --remove-parts \
+        --tus-extensions "getting,creation,termination,creation-with-upload,creation-defer-length,concatenation,checksum"
     ```
 
 === "ENV"
@@ -248,5 +246,5 @@ By default all extensions are enabled.
     ``` bash
     export RUSTUS_TUS_EXTENSIONS="getting,creation,termination,creation-with-upload,creation-defer-length,concatenation,checksum"
 
-    rustus
+    rustus --remove-parts
     ```
diff --git a/docs/deploy.md b/docs/deploy.md
index 2d180e029ca170f86175484305a51445012b0d97..b7f243289a7a8e5844136c60ebed6ec494814ada 100644
--- a/docs/deploy.md
+++ b/docs/deploy.md
@@ -6,8 +6,13 @@ description: "How to deploy rustus"
 # Deployment
 
 Deploying an application is always a challenge. Rustus was made to make deployment as easy as possible.
-Since this application works with files so if you want to scale number of rustus instances you
-have to somehow make different rustus instances to work with the same data or info directory.
+Since Rustus works with files you have to be careful while scaling it. All rustus instances
+must have access to the same data and info storages.
+
+!!! info
+
+    If you want to track you rustus instances with **prometheus** you can
+    always get metrics at `/metrics` endpoint.
 
 ## Docker compose
 
@@ -69,7 +74,7 @@ volumes:
 The main idea is that traffic that comes into nginx-proxy
 is routed in one of multiple rustus containers.
 Here I used `jwilder/nginx-proxy` but you can use other
-reverse-proxies such as raw `nginx proxy` or `traefik`.
+reverse-proxies such as [Nginx proxy](https://www.nginx.com/), [Traefik](https://traefik.io/) or [Envoy proxy](https://www.envoyproxy.io/).
 
 Now you can run multiple rustus instnaces like this.
 
@@ -81,11 +86,11 @@ After that you can upload files to `http://localhost:8080/files`
 
 ## Kubernetes
 
-Configuration for kubernetes is almost the same as docker.
+Configuration for Kubernetes is almost the same as for Docker.
 But the most preferable way is an official helm chart.
 
-Load balancing is done by kubernetes so you just have to
-create volume to mount data and info directories.
+Load balancing is done by Kubernetes, so you just have to
+create a volume to mount data and info directories.
 
 ## Helm
 
@@ -93,19 +98,23 @@ You can install rustus by running this set of commands:
 ``` bash
 helm repo add "rustus" "https://s3rius.github.io/rustus/helm_releases"
 helm repo update
-helm repo install "rustus/rustus"
+helm install "rustus" "rustus/rustus"
 ```
 
 ### Configuration
-But of course it can be configured.
+
+Since default deplyment may not fit you.
+You can adjust it to satisfy your needs.
+You can do it easily with helm.
+
+
+At first you need to save default values on disk.
 
 ``` bash
 # You can download basic configuration by running
 helm show values "rustus/rustus" > values.yml
 ```
 
-By editing values.yml you can configure many different options.
-
 !!! warning
 
     For production use you must provide and mount PersistentVolumeClaim
@@ -113,9 +122,24 @@ By editing values.yml you can configure many different options.
 
     This helm chart has only one replica by default.
 
+You can read more about configuration below.
+
+After you done editing `values.yml`, you can apply the configuration like this:
+
+``` bash
+helm upgrade \
+--install \ # Install chart if it's not installed
+--namespace rustus \ # k8s namespace
+--create-namespace \ # Creates namespace if it doesn't exist
+--atomic \ # Ensures that everything is deployed correctly
+--values "values.yml" \ # Link to values.yml file
+"rustus" \ # name of a release
+"rustus/rustus" # Name of the chart
+```
+
 ### Persistence
 
-You can add pvc mount by editing `persistence` section.
+You can add PVC mount by editing `persistence` section.
 The most preferable way is to create `PersistentVolume` and `PersistentVolumeClaim`
 before installing this chart.
 
@@ -156,16 +180,3 @@ You can find information about configuration these subcharts here:
 * [Repo](https://github.com/bitnami/charts/tree/master/bitnami/postgresql) for postgresql.
 
 In production you may ignore these subcharts to deploy your own redis or mysql or postgresql.
-
-After you done editing `values.yml` you can apply the configuration like this:
-
-``` bash
-helm upgrade \
---install \ # Install chart if it's not installed
---namespace rustus \ # k8s namespace
---create-namespace \ # Creates namespace if it doesn't exist
---atomic \ # Ensures that everything is deployed correctly
---values "values.yml" \ # Link to values.yml file
-"rustus" \ # name of a release
-"rustus/rustus" # Name of the chart
-```
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index eacebf7f944924e37485d1b9eb8ad9863d7715e5..f80c599b0ba488de59649b2647b7469624d9edca 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -15,12 +15,12 @@ description: Rustus docs
 
 Rustus is a [TUS](https://tus.io) protocol implementation that helps you handle file uploads.
 
-This project has many features that makes it easy to integrate in your service.
+This project has many features that makes it easy to integrate with your application.
 
 
 ## Installation
 
-You can install rustus by 4 different ways.
+You can install rustus in four different ways.
 
 ### From source
 
@@ -30,24 +30,26 @@ Preferred version is 1.59.0.
 ```bash
 git clone https://github.com/s3rius/rustus.git
 cd rustus
-cargo install --path . --features=all
+cargo install --path . --features=all,metrics
 ```
-Also you can speedup build by disabling some features.
+
+Also, you can speedup build by disabling some features.
 
 Available features:
 
-* `amqp_notifier` - adds amqp protocol support for notifying about upload status;
-* `db_info_storage` - adds support for storing information about upload in different databases (Postgres, MySQL, SQLite);
-* `http_notifier` - adds support for notifying about upload status via http protocol;
-* `redis_info_storage` - adds support for storing information about upload in redis database;
+* `amqp_notifier` - adds `AMQP` protocol support for notifying about upload status;
+* `db_info_storage` - adds support for storing information about upload in different databases (`Postgres`, `MySQL`, `SQLite`);
+* `http_notifier` - adds support for notifying about upload status via `HTTP` protocol;
+* `redis_info_storage` - adds support for storing information about upload in `Redis` database;
 * `hashers` - adds support for checksum verification;
-* `all` - enables all rustus features.
+* `metrics` - adds rustus specific metrics to prometheus endpoint;
+* `all` - enables all rustus features except `metrics`.
 
 All precompiled binaries have all features enabled.
 
 ### With cargo
 
-If you have cargo installed maybe it would be easier to
+If you have cargo installed, it might be easier to
 install it directly from crates.io.
 
 ```bash
@@ -56,27 +58,29 @@ cargo install rustus --features=all
 
 ### Binaries
 
-All precompiled binaries available on github releases page.
+All precompiled binaries available on Github releases page.
 You can download binaries from [here](https://github.com/s3rius/rustus/releases), unpack it and run.
 
 ```bash
 ./rustus
 ```
 
-Make sure that you download version for your cpu and os.
+Make sure you download right version for your CPU architecture and OS.
 
-### Using docker
+### Using Docker
 
-One of the most simple ways to run rustus is docker.
+One of the most simple ways to run rustus is `Docker`.
 
 Rustus has two containers for each version.
-1. debian based image
-2. alpine based image
+1. Debian based image
+2. Alpine based image
 
-Alpine based images are more lightweight than debian
+Alpine based images are more lightweight than Debian
 
-To run rustus you just need to run this command
+To run Rustus with Docker you just need to run this command
 
 ```bash
 docker run --rm -p "1081:1081" -d s3rius/rustus --log-level "DEBUG"
-```
\ No newline at end of file
+```
+
+More information about Rustus docker images you can find on [Docker hub page](https://hub.docker.com/r/s3rius/rustus/).
diff --git a/src/errors.rs b/src/errors.rs
index 13ad2ae57a614f7cbae16168fb21eef0185fea64..0f1760231548456baa68761d6c24d88a7a0b8aed 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -65,6 +65,8 @@ pub enum RustusError {
     WrongChecksum,
     #[error("The header value is incorrect")]
     WrongHeaderValue,
+    #[error("Metrics error: {0}")]
+    PrometheusError(#[from] prometheus::Error),
 }
 
 /// This conversion allows us to use `RustusError` in the `main` function.
diff --git a/src/info_storages/db_info_storage.rs b/src/info_storages/db_info_storage.rs
index 74901bf4c604eeedc4b1e8c7b86d87f54458270e..2a7a1f2ae44d5443c24eb3ada7e4dbfd61ae158e 100644
--- a/src/info_storages/db_info_storage.rs
+++ b/src/info_storages/db_info_storage.rs
@@ -1,7 +1,7 @@
 use std::time::Duration;
 
 use async_trait::async_trait;
-use rbatis::{crud::CRUD, crud_table, db::DBPoolOptions, executor::Executor, rbatis::Rbatis};
+use rbatis::{crud::CRUD, crud_table, db::DBPoolOptions, rbatis::Rbatis};
 
 use crate::{
     errors::{RustusError, RustusResult},
diff --git a/src/main.rs b/src/main.rs
index 6fc08e66bc997f51c7b6b52a4e4a0b3655bc05cc..26ab5eb6d072cac7361b51deff98cebe836486d2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,14 +11,17 @@ use fern::{
     colors::{Color, ColoredLevelConfig},
     Dispatch,
 };
-use log::LevelFilter;
+use log::{error, LevelFilter};
 
 use config::RustusConf;
 
 use crate::{
-    errors::RustusResult, info_storages::InfoStorage,
-    notifiers::models::notification_manager::NotificationManager, server::rustus_service,
-    state::State, storages::Storage,
+    errors::{RustusError, RustusResult},
+    info_storages::InfoStorage,
+    notifiers::models::notification_manager::NotificationManager,
+    server::rustus_service,
+    state::State,
+    storages::Storage,
 };
 
 mod config;
@@ -72,14 +75,37 @@ fn greeting(app_conf: &RustusConf) {
 /// if the server can't be bound to the
 /// given address.
 #[cfg_attr(coverage, no_coverage)]
-pub fn create_server(state: State) -> Result<Server, std::io::Error> {
+pub fn create_server(state: State) -> RustusResult<Server> {
     let host = state.config.host.clone();
     let port = state.config.port;
     let workers = state.config.workers;
     let state_data: web::Data<State> = web::Data::from(Arc::new(state));
+    let metrics = actix_web_prom::PrometheusMetricsBuilder::new("")
+        .endpoint("/metrics")
+        .build()
+        .map_err(|err| {
+            error!("{}", err);
+            RustusError::Unknown
+        })?;
+    let active_uploads =
+        prometheus::IntGauge::new("active_uploads", "Number of active file uploads")?;
+    let file_sizes = prometheus::Histogram::with_opts(
+        prometheus::HistogramOpts::new("uploads_sizes", "Size of uploaded files in bytes")
+            .buckets(prometheus::exponential_buckets(2., 2., 40)?),
+    )?;
+    #[cfg(feature = "metrics")]
+    {
+        metrics
+            .registry
+            .register(Box::new(active_uploads.clone()))?;
+        metrics.registry.register(Box::new(file_sizes.clone()))?;
+    }
     let mut server = HttpServer::new(move || {
         App::new()
+            .app_data(web::Data::new(active_uploads.clone()))
+            .app_data(web::Data::new(file_sizes.clone()))
             .configure(rustus_service(state_data.clone()))
+            .wrap(metrics.clone())
             .wrap(middleware::Logger::new("\"%r\" \"-\" \"%s\" \"%a\" \"%D\""))
             // Middleware that overrides method of a request if
             // "X-HTTP-Method-Override" header is provided.
diff --git a/src/protocol/core/write_bytes.rs b/src/protocol/core/write_bytes.rs
index fafc64e59c9da415eb623f50cb8fc5178046dcf2..422c0e4f4bfe56dfbe618a8a22b60c512d034f39 100644
--- a/src/protocol/core/write_bytes.rs
+++ b/src/protocol/core/write_bytes.rs
@@ -14,6 +14,7 @@ pub async fn write_bytes(
     request: HttpRequest,
     bytes: Bytes,
     state: web::Data<State>,
+    #[cfg(feature = "metrics")] active_uploads: web::Data<prometheus::IntGauge>,
 ) -> RustusResult<HttpResponse> {
     // Checking if request has required headers.
     let check_content_type = |val: &str| val == "application/offset+octet-stream";
@@ -109,10 +110,9 @@ pub async fn write_bytes(
     state.info_storage.set_info(&file_info, false).await?;
 
     let mut hook = Hook::PostReceive;
-    let mut keep_alive = true;
+
     if file_info.length == Some(file_info.offset) {
         hook = Hook::PostFinish;
-        keep_alive = false;
     }
     if state.config.hook_is_active(hook) {
         let message = state
@@ -128,16 +128,15 @@ pub async fn write_bytes(
                 .await
         });
     }
-    if keep_alive {
-        Ok(HttpResponse::NoContent()
-            .insert_header(("Upload-Offset", file_info.offset.to_string()))
-            .keep_alive()
-            .finish())
-    } else {
-        Ok(HttpResponse::NoContent()
-            .insert_header(("Upload-Offset", file_info.offset.to_string()))
-            .finish())
+
+    #[cfg(feature = "metrics")]
+    if hook == Hook::PostFinish {
+        active_uploads.dec();
     }
+
+    Ok(HttpResponse::NoContent()
+        .insert_header(("Upload-Offset", file_info.offset.to_string()))
+        .finish())
 }
 
 #[cfg(test)]
diff --git a/src/protocol/creation/routes.rs b/src/protocol/creation/routes.rs
index 86c8b3440e421694db23a60c5b50164b3bdfc196..52fc2c70f570a39ce50fa156d63dde68e4e19057 100644
--- a/src/protocol/creation/routes.rs
+++ b/src/protocol/creation/routes.rs
@@ -71,6 +71,8 @@ fn get_upload_parts(request: &HttpRequest) -> Vec<String> {
 /// extension is enabled.
 #[allow(clippy::too_many_lines)]
 pub async fn create_file(
+    #[cfg(feature = "metrics")] active_uploads: web::Data<prometheus::IntGauge>,
+    #[cfg(feature = "metrics")] file_sizes: web::Data<prometheus::Histogram>,
     state: web::Data<State>,
     request: HttpRequest,
     bytes: Bytes,
@@ -140,6 +142,16 @@ pub async fn create_file(
     // Create file and get the it's path.
     file_info.path = Some(state.data_storage.create_file(&file_info).await?);
 
+    // Incrementing number of active uploads
+    #[cfg(feature = "metrics")]
+    active_uploads.inc();
+
+    #[cfg(feature = "metrics")]
+    if let Some(length) = file_info.length {
+        #[allow(clippy::cast_precision_loss)]
+        file_sizes.observe(length as f64);
+    }
+
     if file_info.is_final {
         let mut final_size = 0;
         let mut parts_info = Vec::new();
diff --git a/src/routes.rs b/src/routes.rs
index 6a0769234bc6aff0463f9c9769c7b4c327b4d235..fa5463135e3a567e09cf06728cc0a3dd5baec6d0 100644
--- a/src/routes.rs
+++ b/src/routes.rs
@@ -1,14 +1,12 @@
 use actix_web::HttpResponse;
 
-use crate::errors::{RustusError, RustusResult};
-
 /// Default response to all unknown URLs.
 /// All protocol urls can be found
 /// at `crate::protocol::*`.
 #[allow(clippy::unused_async)]
 #[cfg_attr(coverage, no_coverage)]
-pub async fn not_found() -> RustusResult<HttpResponse> {
-    Err(RustusError::FileNotFound)
+pub async fn not_found() -> HttpResponse {
+    HttpResponse::NotFound().finish()
 }
 
 /// Checks that application is accepting connections correctly.
diff --git a/src/state.rs b/src/state.rs
index 45fa622adf357d1195cfcb6e8fc844c9621ba96a..f74a2d6bcd4c4b424e2f7c575c8468dbff4f376e 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -25,7 +25,7 @@ impl State {
     }
 
     #[cfg(test)]
-    pub async fn from_config(config: RustusConf) -> Self {
+    pub async fn from_config_test(config: RustusConf) -> Self {
         Self {
             config: config.clone(),
             data_storage: Box::new(crate::storages::file_storage::FileStorage::new(
@@ -56,13 +56,13 @@ impl State {
             ]
             .into_iter(),
         );
-        Self::from_config(config).await
+        Self::from_config_test(config).await
     }
 
     #[cfg(test)]
     pub async fn test_clone(&self) -> Self {
         let config = self.config.clone();
-        Self::from_config(config).await
+        Self::from_config_test(config).await
     }
 
     #[cfg(test)]