app: use the channel to receive other logs

Add another logger to receive message, events or GST logs
This commit is contained in:
Stéphane Cerveau 2023-11-28 17:00:13 +01:00
parent e410289a13
commit 24121856ee
6 changed files with 138 additions and 18 deletions

8
Cargo.lock generated
View file

@ -529,11 +529,13 @@ name = "gst_pipeline_studio"
version = "0.3.4" version = "0.3.4"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono",
"futures-channel", "futures-channel",
"futures-executor", "futures-executor",
"gst-plugin-gtk4", "gst-plugin-gtk4",
"gstreamer", "gstreamer",
"gtk4", "gtk4",
"lazy_static",
"log 0.4.14", "log 0.4.14",
"once_cell", "once_cell",
"serde", "serde",
@ -764,6 +766,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.137" version = "0.2.137"

View file

@ -18,6 +18,8 @@ serde = "1.0"
serde_any = "0.5" serde_any = "0.5"
simplelog = "0.11.2" simplelog = "0.11.2"
futures-channel = "0.3" futures-channel = "0.3"
lazy_static = "1.4"
chrono = "0.4"
[dev-dependencies] [dev-dependencies]
futures-executor = "0.3" futures-executor = "0.3"

View file

@ -457,15 +457,18 @@ impl GPSApp {
let (ready_tx, ready_rx) = glib::MainContext::channel(glib::Priority::DEFAULT); let (ready_tx, ready_rx) = glib::MainContext::channel(glib::Priority::DEFAULT);
let app_weak = self.downgrade(); let app_weak = self.downgrade();
logger::init_logger( logger::init_logger(
ready_tx, ready_tx.clone(),
Settings::log_file_path() Settings::log_file_path()
.to_str() .to_str()
.expect("Unable to convert log file path to a string"), .expect("Unable to convert log file path to a string"),
); );
GPSUI::logger::setup_logger_list(self); logger::init_msg_logger(ready_tx);
let _ = ready_rx.attach(None, move |msg: String| { GPSUI::logger::setup_logger_list(self, "treeview-app-logger", logger::LogType::App);
GPSUI::logger::setup_logger_list(self, "treeview-msg-logger", logger::LogType::Message);
GPSUI::logger::setup_logger_list(self, "treeview-gst-logger", logger::LogType::Gst);
let _ = ready_rx.attach(None, move |msg: (logger::LogType, String)| {
let app = upgrade_weak!(app_weak, glib::ControlFlow::Break); let app = upgrade_weak!(app_weak, glib::ControlFlow::Break);
GPSUI::logger::add_to_logger_list(&app, &msg); GPSUI::logger::add_to_logger_list(&app, msg.0, &msg.1);
glib::ControlFlow::Continue glib::ControlFlow::Continue
}); });

View file

@ -279,6 +279,7 @@ impl Player {
fn on_pipeline_message(&self, msg: &gst::MessageRef) { fn on_pipeline_message(&self, msg: &gst::MessageRef) {
use gst::MessageView; use gst::MessageView;
GPS_MSG!("{:?}", msg.structure());
match msg.view() { match msg.view() {
MessageView::Eos(_) => { MessageView::Eos(_) => {
GPS_INFO!("EOS received"); GPS_INFO!("EOS received");

View file

@ -14,6 +14,13 @@ use std::io;
use std::fs::File; use std::fs::File;
use chrono::Local;
use std::sync::Mutex;
lazy_static::lazy_static! {
static ref MSG_LOGGER: Mutex<Option<MessageLogger>> = Mutex::new(None);
}
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LogLevel { pub enum LogLevel {
@ -25,6 +32,13 @@ pub enum LogLevel {
Trace, Trace,
} }
#[derive(Debug, Clone, PartialEq)]
pub enum LogType {
App,
Gst,
Message,
}
impl LogLevel { impl LogLevel {
pub fn from_u32(value: u32) -> LogLevel { pub fn from_u32(value: u32) -> LogLevel {
match value { match value {
@ -77,6 +91,22 @@ macro_rules! GPS_DEBUG (
}) })
); );
#[macro_export]
macro_rules! GPS_MSG (
() => ($crate::print!("\n"));
($($arg:tt)*) => ({
logger::pring_msg_logger(logger::LogType::Message, format_args!($($arg)*).to_string());
})
);
#[macro_export]
macro_rules! GPS_GST_LOG (
() => ($crate::print!("\n"));
($($arg:tt)*) => ({
logger::pring_msg_logger(logger::LogType::Gst, format_args!($($arg)*).to_string());
})
);
#[macro_export] #[macro_export]
macro_rules! GPS_TRACE ( macro_rules! GPS_TRACE (
() => ($crate::print!("\n")); () => ($crate::print!("\n"));
@ -86,7 +116,7 @@ macro_rules! GPS_TRACE (
); );
struct WriteAdapter { struct WriteAdapter {
sender: Sender<String>, sender: Sender<(LogType, String)>,
buffer: String, buffer: String,
} }
@ -97,7 +127,9 @@ impl io::Write for WriteAdapter {
.push_str(&String::from_utf8(buf.to_vec()).unwrap()); .push_str(&String::from_utf8(buf.to_vec()).unwrap());
if self.buffer.ends_with('\n') { if self.buffer.ends_with('\n') {
self.buffer.pop(); self.buffer.pop();
self.sender.send(self.buffer.clone()).unwrap(); self.sender
.send((LogType::App, self.buffer.clone()))
.unwrap();
self.buffer = String::from(""); self.buffer = String::from("");
} }
@ -120,7 +152,7 @@ fn translate_to_simple_logger(log_level: LogLevel) -> LevelFilter {
} }
} }
pub fn init_logger(sender: Sender<String>, log_file: &str) { pub fn init_logger(sender: Sender<(LogType, String)>, log_file: &str) {
simplelog::CombinedLogger::init(vec![ simplelog::CombinedLogger::init(vec![
WriteLogger::new( WriteLogger::new(
translate_to_simple_logger(LogLevel::Trace), translate_to_simple_logger(LogLevel::Trace),
@ -169,3 +201,34 @@ pub fn print_log(log_level: LogLevel, msg: String) {
_ => {} _ => {}
}; };
} }
#[derive(Debug, Clone)]
pub struct MessageLogger {
sender: Sender<(LogType, String)>,
}
impl MessageLogger {
pub fn new(sender: Sender<(LogType, String)>) -> Self {
Self { sender }
}
pub fn print_log(&self, log_type: LogType, msg: String) {
let to_send = format!("{}\t{}", Local::now().format("%H:%M:%S"), msg);
self.sender.send((log_type.clone(), to_send)).unwrap();
}
}
pub fn init_msg_logger(sender: Sender<(LogType, String)>) {
let mut msg_logger = MSG_LOGGER.lock().unwrap();
if msg_logger.is_none() {
// Initialize the variable
*msg_logger = Some(MessageLogger::new(sender));
}
}
pub fn pring_msg_logger(log_type: LogType, msg: String) {
let msg_logger = MSG_LOGGER.lock().unwrap();
if let Some(logger) = msg_logger.as_ref() {
logger.print_log(log_type, msg);
}
}

View file

@ -7,6 +7,7 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::app::GPSApp; use crate::app::GPSApp;
use crate::logger;
use crate::ui::treeview; use crate::ui::treeview;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};
@ -18,18 +19,37 @@ fn reset_logger_list(logger_list: &TreeView) {
String::static_type(), String::static_type(),
String::static_type(), String::static_type(),
String::static_type(), String::static_type(),
String::static_type(),
String::static_type(),
]); ]);
logger_list.set_model(Some(&model)); logger_list.set_model(Some(&model));
} }
pub fn setup_logger_list(app: &GPSApp) { pub fn setup_logger_list(app: &GPSApp, logger_name: &str, log_type: logger::LogType) {
treeview::add_column_to_treeview(app, "treeview-logger", "TIME", 0, false); match log_type {
treeview::add_column_to_treeview(app, "treeview-logger", "LEVEL", 1, false); logger::LogType::App => {
treeview::add_column_to_treeview(app, "treeview-logger", "LOG", 2, true); treeview::add_column_to_treeview(app, logger_name, "TIME", 0, false);
treeview::add_column_to_treeview(app, logger_name, "LEVEL", 1, false);
treeview::add_column_to_treeview(app, logger_name, "LOG", 2, true);
}
logger::LogType::Gst => {
treeview::add_column_to_treeview(app, logger_name, "TIME", 0, false);
treeview::add_column_to_treeview(app, logger_name, "LEVEL", 1, false);
treeview::add_column_to_treeview(app, logger_name, "CATEGORY", 2, false);
treeview::add_column_to_treeview(app, logger_name, "FILE", 3, false);
treeview::add_column_to_treeview(app, logger_name, "LOG", 4, true);
}
logger::LogType::Message => {
treeview::add_column_to_treeview(app, logger_name, "TIME", 0, false);
treeview::add_column_to_treeview(app, logger_name, "LEVEL", 1, false);
treeview::add_column_to_treeview(app, logger_name, "LOG", 2, true);
}
}
let logger_list: TreeView = app let logger_list: TreeView = app
.builder .builder
.object("treeview-logger") .object(logger_name)
.expect("Couldn't get treeview-logger"); .expect("Couldn't get treeview-app-logger");
reset_logger_list(&logger_list); reset_logger_list(&logger_list);
let gesture = gtk::GestureClick::new(); let gesture = gtk::GestureClick::new();
@ -59,17 +79,40 @@ pub fn setup_logger_list(app: &GPSApp) {
logger_list.add_controller(gesture); logger_list.add_controller(gesture);
} }
pub fn add_to_logger_list(app: &GPSApp, log_entry: &str) { fn log_tree_id_from_log_type(log_type: logger::LogType) -> String {
match log_type {
logger::LogType::App => String::from("treeview-app-logger"),
logger::LogType::Gst => String::from("treeview-gst-logger"),
logger::LogType::Message => String::from("treeview-msg-logger"),
}
}
pub fn add_to_logger_list(app: &GPSApp, log_type: logger::LogType, log_entry: &str) {
let log_tree_name = log_tree_id_from_log_type(log_type.clone());
let logger_list: TreeView = app let logger_list: TreeView = app
.builder .builder
.object("treeview-logger") .object(log_tree_name.as_str())
.expect("Couldn't get treeview-logger"); .expect("Couldn't get treeview");
if let Some(model) = logger_list.model() { if let Some(model) = logger_list.model() {
let list_store = model let list_store = model
.dynamic_cast::<ListStore>() .dynamic_cast::<ListStore>()
.expect("Could not cast to ListStore"); .expect("Could not cast to ListStore");
let log: Vec<&str> = log_entry.splitn(3, ' ').collect(); if log_type == logger::LogType::Gst {
list_store.insert_with_values(Some(0), &[(0, &log[0]), (1, &log[1]), (2, &log[2])]); let log: Vec<&str> = log_entry.splitn(5, '\t').collect();
list_store.insert_with_values(
Some(0),
&[
(0, &log[0]),
(1, &log[1]),
(2, &log[2]),
(3, &log[3]),
(4, &log[4]),
],
);
} else {
let log: Vec<&str> = log_entry.splitn(3, ' ').collect();
list_store.insert_with_values(Some(0), &[(0, &log[0]), (1, &log[1]), (2, &log[2])]);
}
// Scroll to the first element. // Scroll to the first element.
if let Some(model) = logger_list.model() { if let Some(model) = logger_list.model() {
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {