mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-22 10:06:29 +00:00
tracers: queue-levels: Add a signal to force writing log file
This way applications can write the queue levels info whenever it wants and does not need to wait for the application to quite. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1912>
This commit is contained in:
parent
def8a29cc6
commit
153d4c7ac5
1 changed files with 71 additions and 43 deletions
|
@ -44,7 +44,7 @@
|
|||
*
|
||||
* By default this is not set.
|
||||
*/
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
@ -179,6 +179,7 @@ struct State {
|
|||
queues: HashMap<usize, Arc<glib::GString>>,
|
||||
log: Vec<LogLine>,
|
||||
settings: Settings,
|
||||
logs_written: HashSet<PathBuf>,
|
||||
}
|
||||
|
||||
struct LogLine {
|
||||
|
@ -239,49 +240,26 @@ impl ObjectImpl for QueueLevels {
|
|||
self.register_hook(TracerHook::PadPushEventPre);
|
||||
}
|
||||
|
||||
fn signals() -> &'static [glib::subclass::Signal] {
|
||||
static SIGNALS: LazyLock<Vec<glib::subclass::Signal>> = LazyLock::new(|| {
|
||||
vec![glib::subclass::Signal::builder("write-log")
|
||||
.action()
|
||||
.param_types([Option::<String>::static_type()])
|
||||
.class_handler(|_, args| {
|
||||
let obj = args[0].get::<super::QueueLevels>().unwrap();
|
||||
|
||||
obj.imp().write_log(args[1].get::<Option<&str>>().unwrap());
|
||||
|
||||
None
|
||||
})
|
||||
.build()]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
}
|
||||
|
||||
fn dispose(&self) {
|
||||
use std::io::prelude::*;
|
||||
|
||||
let state = self.state.lock().unwrap();
|
||||
|
||||
let mut file = match std::fs::File::create(&state.settings.file) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
gst::error!(CAT, imp = self, "Failed to create file: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
gst::debug!(
|
||||
CAT,
|
||||
imp = self,
|
||||
"Writing file {}",
|
||||
state.settings.file.display()
|
||||
);
|
||||
|
||||
for LogLine {
|
||||
timestamp,
|
||||
name,
|
||||
idx,
|
||||
ptr,
|
||||
cur_level_bytes,
|
||||
cur_level_time,
|
||||
cur_level_buffers,
|
||||
max_size_bytes,
|
||||
max_size_time,
|
||||
max_size_buffers,
|
||||
} in &state.log
|
||||
{
|
||||
let res = if let Some(idx) = idx {
|
||||
writeln!(&mut file, "{timestamp},{name}:{idx},0x{ptr:08x},{cur_level_bytes},{cur_level_time},{cur_level_buffers},{max_size_bytes},{max_size_time},{max_size_buffers}")
|
||||
} else {
|
||||
writeln!(&mut file, "{timestamp},{name},0x{ptr:08x},{cur_level_bytes},{cur_level_time},{cur_level_buffers},{max_size_bytes},{max_size_time},{max_size_buffers}")
|
||||
};
|
||||
if let Err(err) = res {
|
||||
gst::error!(CAT, imp = self, "Failed to write to file: {err}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.write_log(None);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,4 +523,54 @@ impl QueueLevels {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn write_log(&self, file_path: Option<&str>) {
|
||||
use std::io::prelude::*;
|
||||
|
||||
let mut state = self.state.lock().unwrap();
|
||||
let path = file_path.map_or_else(|| state.settings.file.clone(), PathBuf::from);
|
||||
let first_write = state.logs_written.contains(&path);
|
||||
|
||||
let mut file = match std::fs::OpenOptions::new()
|
||||
.append(!first_write)
|
||||
.create(true)
|
||||
.open(path.clone())
|
||||
{
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
gst::error!(CAT, imp = self, "Failed to create file: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let log = std::mem::take(&mut state.log);
|
||||
state.logs_written.insert(path);
|
||||
drop(state);
|
||||
|
||||
gst::debug!(CAT, imp = self, "Writing file {:?}", file);
|
||||
|
||||
for LogLine {
|
||||
timestamp,
|
||||
name,
|
||||
idx,
|
||||
ptr,
|
||||
cur_level_bytes,
|
||||
cur_level_time,
|
||||
cur_level_buffers,
|
||||
max_size_bytes,
|
||||
max_size_time,
|
||||
max_size_buffers,
|
||||
} in &log
|
||||
{
|
||||
let res = if let Some(idx) = idx {
|
||||
writeln!(&mut file, "{timestamp},{name}:{idx},0x{ptr:08x},{cur_level_bytes},{cur_level_time},{cur_level_buffers},{max_size_bytes},{max_size_time},{max_size_buffers}")
|
||||
} else {
|
||||
writeln!(&mut file, "{timestamp},{name},0x{ptr:08x},{cur_level_bytes},{cur_level_time},{cur_level_buffers},{max_size_bytes},{max_size_time},{max_size_buffers}")
|
||||
};
|
||||
if let Err(err) = res {
|
||||
gst::error!(CAT, imp = self, "Failed to write to file: {err}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue