Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions console_backend/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ impl ConnectionState {
) -> JoinHandle<()> {
thread::spawn(move || {
let mut conn = None;
info!("Console started...");
while shared_state.clone().is_server_running() {
if let Ok(conn_option) = receiver.recv_timeout(Duration::from_secs_f64(
SERVER_STATE_CONNECTION_LOOP_TIMEOUT_SEC,
Expand All @@ -253,6 +254,7 @@ impl ConnectionState {
}
shared_state.set_running(false, client_send.clone());
}
log::logger().flush();
}
})
}
Expand Down
1 change: 1 addition & 0 deletions console_backend/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ pub(crate) const TCP_CONNECTION_PARSING_FAILURE: &str =
"unable to parse the provided string for ip string";
pub(crate) const SERVER_STATE_NEW_CONNECTION_FAILURE: &str = "server state new connection failure";
pub(crate) const SERVER_STATE_DISCONNECT_FAILURE: &str = "server state disconnect failure";
pub(crate) const CONSOLE_LOG_JSON_TO_STRING_FAILURE: &str = "unable to convert json to string";
56 changes: 43 additions & 13 deletions console_backend/src/log_panel.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
use async_logger_log::Logger;
use sbp::messages::logging::MsgLog;

use capnp::message::Builder;

use crate::common_constants as cc;
use crate::constants::LOG_WRITER_BUFFER_MESSAGE_COUNT;
use crate::errors::CONSOLE_LOG_JSON_TO_STRING_FAILURE;
use crate::types::*;
use crate::utils::serialize_capnproto_builder;

use async_logger::Writer;
use chrono::Local;
use log::{debug, error, info, warn, LevelFilter, Record};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct ConsoleLogPacket {
level: String,
timestamp: String,
msg: String,
}

const DEVICE: &str = "DEVICE";
const CONSOLE: &str = "CONSOLE";

pub type LogLevel = cc::LogLevel;
impl LogLevel {
Expand All @@ -24,13 +38,19 @@ impl LogLevel {

// Custom formatting of `log::Record` to account for SbpLog values
pub fn splitable_log_formatter(record: &Record) -> String {
// TODO (JV): CPP-117 Extract SbpLog timestamp and level from message
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this hasnt been finished afaics. the timestamps are always the Local::now() below

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no timestamp in the MsgLog nor the python message log and it doesn't look like piksi tools adds any remote timestamp. Can you show me what you were referring to?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I was thinking that the timestamp should be determined in handle_log_msg rather than here, but that is because I wasnt sure if there was the possibility of delays between warn!(etc) capturing the logging arguments and the formatter here being asked to render it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point. So I did a little digging and I believe the formatting function may get called when a new log message is made instead of when the flush occurs although I may be wrong seems this async_logger is wrapped around another async logger crate so its not the easiest for me to follow. That being said our logs are formatted out to the seconds and these delays are running in milliseconds so probably not a huge deal.

format!(
"{} {} {}",
Local::now().format("%Y-%m-%dT%H:%M:%S"),
record.level(),
record.args()
)
let level = if record.target() != DEVICE {
CONSOLE
} else {
record.level().as_str()
};
let timestamp = Local::now().format("%Y-%m-%dT%H:%M:%S");
let msg = record.args();
let msg_packet = ConsoleLogPacket {
level: level.to_string(),
timestamp: timestamp.to_string(),
msg: msg.to_string(),
};
serde_json::to_string(&msg_packet).expect(CONSOLE_LOG_JSON_TO_STRING_FAILURE)
}

enum SbpMsgLevel {
Expand Down Expand Up @@ -64,18 +84,29 @@ impl From<u8> for SbpMsgLevel {
pub fn handle_log_msg(msg: MsgLog) {
let text = msg.text.to_string();
let level: SbpMsgLevel = SbpMsgLevel::from(msg.level);
// TODO(JV): CPP-117 Include log level and remote timestamp in text message
match level {
SbpMsgLevel::Emergency
| SbpMsgLevel::Alert
| SbpMsgLevel::Critical
| SbpMsgLevel::Error => error!("{}", text),
SbpMsgLevel::Warn | SbpMsgLevel::Notice => warn!("{}", text),
SbpMsgLevel::Info => info!("{}", text),
_ => debug!("{}", text),
| SbpMsgLevel::Error => error!(target: DEVICE, "{}", text),
SbpMsgLevel::Warn | SbpMsgLevel::Notice => warn!(target: DEVICE, "{}", text),
SbpMsgLevel::Info => info!(target: DEVICE, "{}", text),
_ => debug!(target: DEVICE, "{}", text),
}
}

pub fn setup_logging(client_sender: ClientSender) {
let log_panel = LogPanelWriter::new(client_sender);
let logger = Logger::builder()
.buf_size(LOG_WRITER_BUFFER_MESSAGE_COUNT)
.formatter(splitable_log_formatter)
.writer(Box::new(log_panel))
.build()
.unwrap();

log::set_boxed_logger(Box::new(logger)).expect("Failed to set logger");
}

#[derive(Debug)]
pub struct LogPanelWriter<S: CapnProtoSender> {
pub client_sender: S,
Expand All @@ -102,7 +133,6 @@ impl<S: CapnProtoSender> Writer<Box<String>> for LogPanelWriter<S> {
for (idx, item) in slice.iter().enumerate() {
let mut entry = entries.reborrow().get(idx as u32);

//TODO: split line into timestamp, level and text
entry.set_line(&**item);
}

Expand Down
2 changes: 1 addition & 1 deletion console_backend/src/piksi_tools_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ pub const SMOOTHPOSE: i32 = 0;
pub const DR_RUNNER: i32 = 1;
lazy_static! {
pub static ref ins_type_dict: HashMap<i32, &'static str> =
[(SMOOTHPOSE, "SP"), (DR_RUNNER, "DR")]
[(SMOOTHPOSE, "SP-"), (DR_RUNNER, "")]
.iter()
.cloned()
.collect::<HashMap<_, _>>();
Expand Down
Loading