add interface to query rocksdb properties w/ admin cmd
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
f261d44edb
commit
ac941a801a
4 changed files with 51 additions and 2 deletions
|
@ -828,3 +828,24 @@ pub(super) async fn list_dependencies(&self, names: bool) -> Result<RoomMessageE
|
||||||
|
|
||||||
Ok(RoomMessageEventContent::notice_markdown(out))
|
Ok(RoomMessageEventContent::notice_markdown(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[admin_command]
|
||||||
|
pub(super) async fn database_stats(
|
||||||
|
&self, property: Option<String>, map: Option<String>,
|
||||||
|
) -> Result<RoomMessageEventContent> {
|
||||||
|
let property = property.unwrap_or_else(|| "rocksdb.stats".to_owned());
|
||||||
|
let map_name = map.as_ref().map_or(utils::string::EMPTY, String::as_str);
|
||||||
|
|
||||||
|
let mut out = String::new();
|
||||||
|
for (name, map) in self.services.db.iter_maps() {
|
||||||
|
if !map_name.is_empty() && *map_name != *name {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = map.property(&property)?;
|
||||||
|
let res = res.trim();
|
||||||
|
writeln!(out, "##### {name}:\n```\n{res}\n```")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(RoomMessageEventContent::notice_markdown(out))
|
||||||
|
}
|
||||||
|
|
|
@ -184,6 +184,14 @@ pub(super) enum DebugCommand {
|
||||||
names: bool,
|
names: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// - Get database statistics
|
||||||
|
DatabaseStats {
|
||||||
|
property: Option<String>,
|
||||||
|
|
||||||
|
#[arg(short, long, alias("column"))]
|
||||||
|
map: Option<String>,
|
||||||
|
},
|
||||||
|
|
||||||
/// - Developer test stubs
|
/// - Developer test stubs
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeSet, HashMap},
|
collections::{BTreeSet, HashMap},
|
||||||
|
ffi::CStr,
|
||||||
fmt::Write,
|
fmt::Write,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{atomic::AtomicU32, Arc, Mutex, RwLock},
|
sync::{atomic::AtomicU32, Arc, Mutex, RwLock},
|
||||||
|
@ -9,7 +10,8 @@ use conduit::{debug, error, info, utils::time::rfc2822_from_seconds, warn, Err,
|
||||||
use rocksdb::{
|
use rocksdb::{
|
||||||
backup::{BackupEngine, BackupEngineOptions},
|
backup::{BackupEngine, BackupEngineOptions},
|
||||||
perf::get_memory_usage_stats,
|
perf::get_memory_usage_stats,
|
||||||
BoundColumnFamily, Cache, ColumnFamilyDescriptor, DBCommon, DBWithThreadMode, Env, MultiThreaded, Options,
|
AsColumnFamilyRef, BoundColumnFamily, Cache, ColumnFamilyDescriptor, DBCommon, DBWithThreadMode, Env,
|
||||||
|
MultiThreaded, Options,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -240,6 +242,20 @@ impl Engine {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Query for database property by null-terminated name which is expected to
|
||||||
|
/// have a result with an integer representation. This is intended for
|
||||||
|
/// low-overhead programmatic use.
|
||||||
|
pub(crate) fn property_integer(&self, cf: &impl AsColumnFamilyRef, name: &CStr) -> Result<u64> {
|
||||||
|
result(self.db.property_int_value_cf(cf, name))
|
||||||
|
.and_then(|val| val.map_or_else(|| Err!("Property {name:?} not found."), Ok))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Query for database property by name receiving the result in a string.
|
||||||
|
pub(crate) fn property(&self, cf: &impl AsColumnFamilyRef, name: &str) -> Result<String> {
|
||||||
|
result(self.db.property_value_cf(cf, name))
|
||||||
|
.and_then(|val| val.map_or_else(|| Err!("Property {name:?} not found."), Ok))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn repair(db_opts: &Options, path: &PathBuf) -> Result<()> {
|
pub(crate) fn repair(db_opts: &Options, path: &PathBuf) -> Result<()> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{future::Future, mem::size_of, pin::Pin, sync::Arc};
|
use std::{ffi::CStr, future::Future, mem::size_of, pin::Pin, sync::Arc};
|
||||||
|
|
||||||
use conduit::{utils, Result};
|
use conduit::{utils, Result};
|
||||||
use rocksdb::{
|
use rocksdb::{
|
||||||
|
@ -189,6 +189,10 @@ impl Map {
|
||||||
self.watchers.watch(prefix)
|
self.watchers.watch(prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn property_integer(&self, name: &CStr) -> Result<u64> { self.db.property_integer(&self.cf(), name) }
|
||||||
|
|
||||||
|
pub fn property(&self, name: &str) -> Result<String> { self.db.property(&self.cf(), name) }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn name(&self) -> &str { &self.name }
|
pub fn name(&self) -> &str { &self.name }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue