Add `sys metric storage` for checking on-disk storage usage

next
Sayan Nandan 3 years ago
parent d201c74150
commit df994cf4f7
No known key found for this signature in database
GPG Key ID: 8BC07A0A4D41DD52

@ -13,6 +13,7 @@ All changes in this project will be noted in this file.
- `protover`: Protocol version float
- `metric`: For dynamic properties:
- `health`: System health
- `storage`: Bytes used for on-disk storage
- `INSPECT KEYSPACE` without arguments to inspect the current keyspace
- `INSPECT TABLE` without arguments to inspect the current table
- `AUTH WHOAMI` returns the AuthID of the currently logged in user

@ -153,6 +153,7 @@ global:
Returns dynamic properties of the system, i.e metrics are properties that can change during
runtime. The following metrics are available:
- `health`: Returns "good" or "critical" depending on the system state (String)
- `storage`: Returns bytes used for on-disk storage (uint64)
keyvalue:
generic:

@ -24,9 +24,12 @@
*
*/
use crate::corestore::booltable::BoolTable;
use crate::dbnet::connection::prelude::*;
use crate::protocol::{PROTOCOL_VERSION, PROTOCOL_VERSIONSTRING};
use crate::{
corestore::booltable::BoolTable,
dbnet::connection::prelude::*,
protocol::{PROTOCOL_VERSION, PROTOCOL_VERSIONSTRING},
storage::v1::interface::DIR_ROOT,
};
use ::libsky::VERSION;
const INFO: &[u8] = b"info";
@ -35,6 +38,7 @@ const INFO_PROTOCOL: &[u8] = b"protocol";
const INFO_PROTOVER: &[u8] = b"protover";
const INFO_VERSION: &[u8] = b"version";
const METRIC_HEALTH: &[u8] = b"health";
const METRIC_STORAGE_USAGE: &[u8] = b"storage";
const ERR_UNKNOWN_PROPERTY: &[u8] = b"!16\nunknown-property\n";
const ERR_UNKNOWN_METRIC: &[u8] = b"!14\nunknown-metric\n";
@ -64,6 +68,15 @@ action! {
METRIC_HEALTH => {
con.write_response(HEALTH_TABLE[registry::state_okay()]).await?
}
METRIC_STORAGE_USAGE => {
match util::os::dirsize(DIR_ROOT) {
Ok(size) => con.write_response(size).await?,
Err(e) => {
log::error!("Failed to get storage usage with: {e}");
con.write_response(groups::SERVER_ERR).await?
},
}
}
_ => return util::err(ERR_UNKNOWN_METRIC),
}
Ok(())

@ -42,7 +42,7 @@ mod snapshot;
mod tls {
use skytable::{query, Element};
#[sky_macros::dbtest_func(tls_cert = "cert.pem", port = 2004)]
async fn test_tls() {
async fn tls() {
runeq!(
con,
query!("heya", "abcd"),
@ -57,7 +57,7 @@ mod sys {
use sky_macros::dbtest_func as dbtest;
use skytable::{query, Element, RespCode};
#[dbtest]
async fn test_sys_info_aerr() {
async fn sys_info_aerr() {
runeq!(
con,
query!("sys", "info"),
@ -75,7 +75,7 @@ mod sys {
)
}
#[dbtest]
async fn test_sys_info_protocol() {
async fn sys_info_protocol() {
runeq!(
con,
query!("sys", "info", "protocol"),
@ -83,7 +83,7 @@ mod sys {
)
}
#[dbtest]
async fn test_sys_info_protover() {
async fn sys_info_protover() {
runeq!(
con,
query!("sys", "info", "protover"),
@ -91,7 +91,7 @@ mod sys {
)
}
#[dbtest]
async fn test_sys_info_version() {
async fn sys_info_version() {
runeq!(
con,
query!("sys", "info", "version"),
@ -99,7 +99,7 @@ mod sys {
)
}
#[dbtest]
async fn test_sys_metric_aerr() {
async fn sys_metric_aerr() {
runeq!(
con,
query!("sys", "metric"),
@ -107,21 +107,24 @@ mod sys {
);
runeq!(
con,
query!(
"sys",
"metric",
"this is cool",
"but why this extra argument?"
),
query!("sys", "metric", "health", "but why this extra argument?"),
Element::RespCode(RespCode::ActionError)
)
}
#[dbtest]
async fn test_sys_metric_health() {
async fn sys_metric_health() {
runeq!(
con,
query!("sys", "metric", "health"),
Element::String("good".to_owned())
)
}
#[dbtest]
async fn sys_storage_usage() {
runmatch!(
con,
query!("sys", "metric", "storage"),
Element::UnsignedInt
)
}
}

@ -273,3 +273,21 @@ fn rlistdir_inner(path: &Path, paths: &mut Vec<EntryKind>) -> crate::IoResult<()
}
Ok(())
}
fn dir_size_inner(dir: fs::ReadDir) -> IoResult<u64> {
let mut ret = 0;
for entry in dir {
let entry = entry?;
let size = match entry.metadata()? {
meta if meta.is_dir() => dir_size_inner(fs::read_dir(entry.path())?)?,
meta => meta.len(),
};
ret += size;
}
Ok(ret)
}
/// Returns the size of a directory by recursively scanning it
pub fn dirsize(path: impl AsRef<Path>) -> IoResult<u64> {
dir_size_inner(fs::read_dir(path.as_ref())?)
}

Loading…
Cancel
Save