Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

Commit

Permalink
(Needlessly) optimise logging
Browse files Browse the repository at this point in the history
Before this commit, the caller of log_impl() (= the macro log!())
already did a memory allocation for constructing a String containing the
message to log. This was then borrowed when calling log_impl(). This
function then did another memory allocation plus copy to prepend
"virtme-ng-init:" to the message. Then, if /dev/kmsg exists, another
allocation is done to add a kernel log level tag at the beginning and a
newline at the end.

This commit starts by changing log!() from format!() to format_args!()
which constructs an instance of std::fmt::Arguments. This is just a
specification of how to do the formatting, but nothing was actually done
yet. This is then used in log_impl() to directly construct a string with
"virtme-ng-init:" prepended to the message to log.

Since I wanted to avoid memory allocations, this then replaces
.trim_end_matches('\n') with a manual loop. That way, we still have a
String and do not switch over to a &str for the following code.

Additionally, the "is the message to log empty?"-check was reformulated
to "was there nothing appended to my prefix?". This makes things
slightly more unreadable, but I couldn't find a better way to check
whether the Arguments instance is empty.

There is a slight change in behaviour here: Previously, log!("\n") would
log an empty line since the code first checked if the message is empty
and only afterwards trimmed trailing newlines. This is now done the
other way around.

Finally, when writing to /dev/kmsg, the String that we already have is
mutated in places instead of allocating another one and copying all data
to it.

Why? Just because. I doubt that this will have any measurable
performance benefits, but somehow it felt like the right thing to do.

Signed-off-by: Uli Schlachter <psychon@znc.in>
  • Loading branch information
psychon committed Nov 18, 2023
1 parent 9944faa commit 602529a
Showing 1 changed file with 25 additions and 12 deletions.
37 changes: 25 additions & 12 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,47 @@ use nix::mount::{mount, MsFlags};
use nix::sys::stat::Mode;
use nix::unistd::{chown, Gid, Uid};
use std::ffi::{CString, OsStr};
use std::fmt::Arguments;
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::os::unix::fs;
use std::os::unix::fs::PermissionsExt;
use std::process::{Command, Stdio};
use users::get_user_by_name;

static PROG_NAME: &str = "virtme-ng-init";

macro_rules! log {
($($arg:tt)*) => {
$crate::utils::log_impl(&std::format!($($arg)*))
$crate::utils::log_impl(std::format_args!($($arg)*))
};
}

pub fn log_impl(msg: &str) {
if msg.is_empty() {
pub fn log_impl(msg: Arguments<'_>) {
static PREFIX: &str = "<6>virtme-ng-init: ";
static LOG_LEVEL: &str = "<6>";

let mut msg = format!("{}{}", PREFIX, msg);

// Remove all trailing \n
while msg.ends_with('\n') {
msg.pop();
}

// Was the message empty? If so, do not log anything
if PREFIX == msg {
return;
}
let msg = format!("{}: {}", PROG_NAME, msg.trim_end_matches('\n'));
let mut file = OpenOptions::new().write(true).open("/dev/kmsg").ok();
match &mut file {
Some(file) => {
let msg = format!("<6>{}\n", msg);

match OpenOptions::new().write(true).open("/dev/kmsg") {
Ok(mut file) => {
msg.push('\n');
file.write(msg.as_bytes()).ok();
}
None => {
println!("{}", msg);
Err(_) => {
println!(
"{}",
msg.strip_prefix(LOG_LEVEL)
.expect("The message should always start with the log level")
);
}
}
}
Expand Down

0 comments on commit 602529a

Please sign in to comment.