improve debug memory-stats options

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2025-01-18 01:32:37 +00:00
parent 8141ca3444
commit f9e76d6239
5 changed files with 35 additions and 23 deletions

View file

@ -843,19 +843,27 @@ pub(super) async fn resolve_true_destination(
} }
#[admin_command] #[admin_command]
pub(super) async fn memory_stats(&self) -> Result<RoomMessageEventContent> { pub(super) async fn memory_stats(&self, opts: Option<String>) -> Result<RoomMessageEventContent> {
let html_body = conduwuit::alloc::memory_stats(); const OPTS: &str = "abcdefghijklmnopqrstuvwxyz";
if html_body.is_none() { let opts: String = OPTS
return Ok(RoomMessageEventContent::text_plain( .chars()
"malloc stats are not supported on your compiled malloc.", .filter(|&c| {
)); let allow_any = opts.as_ref().is_some_and(|opts| opts == "*");
}
Ok(RoomMessageEventContent::text_html( let allow = allow_any || opts.as_ref().is_some_and(|opts| opts.contains(c));
"This command's output can only be viewed by clients that render HTML.".to_owned(),
html_body.expect("string result"), !allow
)) })
.collect();
let stats = conduwuit::alloc::memory_stats(&opts).unwrap_or_default();
self.write_str("```\n").await?;
self.write_str(&stats).await?;
self.write_str("\n```").await?;
Ok(RoomMessageEventContent::text_plain(""))
} }
#[cfg(tokio_unstable)] #[cfg(tokio_unstable)]

View file

@ -191,7 +191,13 @@ pub(super) enum DebugCommand {
}, },
/// - Print extended memory usage /// - Print extended memory usage
MemoryStats, ///
/// Optional argument is a character mask (a sequence of characters in any
/// order) which enable additional extended statistics. Known characters are
/// "abdeglmx". For convenience, a '*' will enable everything.
MemoryStats {
opts: Option<String>,
},
/// - Print general tokio runtime metric totals. /// - Print general tokio runtime metric totals.
RuntimeMetrics, RuntimeMetrics,

View file

@ -5,7 +5,7 @@ pub fn trim() -> crate::Result { Ok(()) }
/// Always returns None /// Always returns None
#[must_use] #[must_use]
pub fn memory_stats() -> Option<String> { None } pub fn memory_stats(_opts: &str) -> Option<String> { None }
/// Always returns None /// Always returns None
#[must_use] #[must_use]

View file

@ -7,9 +7,9 @@ pub fn trim() -> crate::Result { Ok(()) }
#[must_use] #[must_use]
//TODO: get usage //TODO: get usage
pub fn memory_usage() -> Option<string> { None } pub fn memory_usage() -> Option<String> { None }
#[must_use] #[must_use]
pub fn memory_stats() -> Option<String> { pub fn memory_stats(_opts: &str) -> Option<String> {
Some("Extended statistics are not available from hardened_malloc.".to_owned()) Some("Extended statistics are not available from hardened_malloc.".to_owned())
} }

View file

@ -3,7 +3,7 @@
use std::{ use std::{
cell::OnceCell, cell::OnceCell,
ffi::{c_char, c_void}, ffi::{c_char, c_void},
fmt::{Debug, Write}, fmt::Debug,
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
@ -66,15 +66,12 @@ pub fn memory_usage() -> Option<String> {
#[cfg(not(feature = "jemalloc_stats"))] #[cfg(not(feature = "jemalloc_stats"))]
pub fn memory_usage() -> Option<String> { None } pub fn memory_usage() -> Option<String> { None }
#[must_use] pub fn memory_stats(opts: &str) -> Option<String> {
pub fn memory_stats() -> Option<String> { const MAX_LENGTH: usize = 1_048_576;
const MAX_LENGTH: usize = 65536 - 4096;
let opts_s = "d";
let mut str = String::new(); let mut str = String::new();
let opaque = std::ptr::from_mut(&mut str).cast::<c_void>(); let opaque = std::ptr::from_mut(&mut str).cast::<c_void>();
let opts_p: *const c_char = std::ffi::CString::new(opts_s) let opts_p: *const c_char = std::ffi::CString::new(opts)
.expect("cstring") .expect("cstring")
.into_raw() .into_raw()
.cast_const(); .cast_const();
@ -84,7 +81,8 @@ pub fn memory_stats() -> Option<String> {
unsafe { ffi::malloc_stats_print(Some(malloc_stats_cb), opaque, opts_p) }; unsafe { ffi::malloc_stats_print(Some(malloc_stats_cb), opaque, opts_p) };
str.truncate(MAX_LENGTH); str.truncate(MAX_LENGTH);
Some(format!("<pre><code>{str}</code></pre>"))
Some(str)
} }
unsafe extern "C" fn malloc_stats_cb(opaque: *mut c_void, msg: *const c_char) { unsafe extern "C" fn malloc_stats_cb(opaque: *mut c_void, msg: *const c_char) {