Merge pull request #152 from fuad1502/dmesg

Implement program `dmesg` with support for `--kmsg-file` and `--json` option.
This commit is contained in:
Daniel Hofstetter
2024-11-18 10:25:32 +01:00
committed by GitHub
11 changed files with 1017 additions and 1 deletions

12
Cargo.lock generated
View File

@@ -880,6 +880,7 @@ dependencies = [
"tempfile", "tempfile",
"textwrap", "textwrap",
"uu_ctrlaltdel", "uu_ctrlaltdel",
"uu_dmesg",
"uu_last", "uu_last",
"uu_lscpu", "uu_lscpu",
"uu_lsmem", "uu_lsmem",
@@ -898,6 +899,17 @@ dependencies = [
"uucore", "uucore",
] ]
[[package]]
name = "uu_dmesg"
version = "0.0.1"
dependencies = [
"clap",
"regex",
"serde",
"serde_json",
"uucore",
]
[[package]] [[package]]
name = "uu_last" name = "uu_last"
version = "0.0.1" version = "0.0.1"

View File

@@ -32,7 +32,8 @@ feat_common_core = [
"ctrlaltdel", "ctrlaltdel",
"rev", "rev",
"setsid", "setsid",
"last" "last",
"dmesg"
] ]
[workspace.dependencies] [workspace.dependencies]
@@ -72,6 +73,7 @@ ctrlaltdel = { optional = true, version = "0.0.1", package = "uu_ctrlaltdel", pa
rev = { optional = true, version = "0.0.1", package = "uu_rev", path = "src/uu/rev" } rev = { optional = true, version = "0.0.1", package = "uu_rev", path = "src/uu/rev" }
setsid = { optional = true, version = "0.0.1", package = "uu_setsid", path ="src/uu/setsid" } setsid = { optional = true, version = "0.0.1", package = "uu_setsid", path ="src/uu/setsid" }
last = { optional = true, version = "0.0.1", package = "uu_last", path = "src/uu/last" } last = { optional = true, version = "0.0.1", package = "uu_last", path = "src/uu/last" }
dmesg = { optional = true, version = "0.0.1", package = "uu_dmesg", path = "src/uu/dmesg" }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1" pretty_assertions = "1"

18
src/uu/dmesg/Cargo.toml Normal file
View File

@@ -0,0 +1,18 @@
[package]
name = "uu_dmesg"
version = "0.0.1"
edition = "2021"
[lib]
path = "src/dmesg.rs"
[[bin]]
name = "dmesg"
path = "src/main.rs"
[dependencies]
clap = { workspace = true }
uucore = { workspace = true }
regex = { workspace = true }
serde_json = { workspace = true }
serde = { workspace = true }

7
src/uu/dmesg/dmesg.md Normal file
View File

@@ -0,0 +1,7 @@
# dmesg
```
dmesg [options]
```
Display or control the kernel ring buffer.

153
src/uu/dmesg/src/dmesg.rs Normal file
View File

@@ -0,0 +1,153 @@
// This file is part of the uutils util-linux package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use clap::{crate_version, Arg, ArgAction, Command};
use regex::Regex;
use std::fs;
use uucore::{
error::{FromIo, UResult, USimpleError},
format_usage, help_about, help_usage,
};
mod json;
const ABOUT: &str = help_about!("dmesg.md");
const USAGE: &str = help_usage!("dmesg.md");
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let mut dmesg = Dmesg::new();
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
if let Some(kmsg_file) = matches.get_one::<String>(options::KMSG_FILE) {
dmesg.kmsg_file = kmsg_file;
}
if matches.get_flag(options::JSON) {
dmesg.output_format = OutputFormat::Json;
}
dmesg.parse()?.print();
Ok(())
}
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.override_usage(format_usage(USAGE))
.about(ABOUT)
.version(crate_version!())
.arg(
Arg::new(options::KMSG_FILE)
.short('K')
.long("kmsg-file")
.help("use the file in kmsg format")
.action(ArgAction::Set),
)
.arg(
Arg::new(options::JSON)
.short('J')
.long("json")
.help("use JSON output format")
.action(ArgAction::SetTrue),
)
}
mod options {
pub const KMSG_FILE: &str = "kmsg-file";
pub const JSON: &str = "json";
}
struct Dmesg<'a> {
kmsg_file: &'a str,
output_format: OutputFormat,
records: Option<Vec<Record>>,
}
impl Dmesg<'_> {
fn new() -> Self {
Dmesg {
kmsg_file: "/dev/kmsg",
output_format: OutputFormat::Normal,
records: None,
}
}
fn parse(mut self) -> UResult<Self> {
let mut records = vec![];
let re = Self::record_regex();
let lines = self.read_lines_from_kmsg_file()?;
for line in lines {
for (_, [pri_fac, seq, time, msg]) in re.captures_iter(&line).map(|c| c.extract()) {
records.push(Record::from_str_fields(
pri_fac,
seq,
time,
msg.to_string(),
)?);
}
}
self.records = Some(records);
Ok(self)
}
fn record_regex() -> Regex {
let valid_number_pattern = "0|[1-9][0-9]*";
let additional_fields_pattern = ",^[,;]*";
let record_pattern = format!(
"(?m)^({0}),({0}),({0}),.(?:{1})*;(.*)$",
valid_number_pattern, additional_fields_pattern
);
Regex::new(&record_pattern).expect("invalid regex.")
}
fn read_lines_from_kmsg_file(&self) -> UResult<Vec<String>> {
let kmsg_bytes = fs::read(self.kmsg_file)
.map_err_context(|| format!("cannot open {}", self.kmsg_file))?;
let lines = kmsg_bytes
.split(|&byte| byte == 0)
.map(|line| String::from_utf8_lossy(line).to_string())
.collect();
Ok(lines)
}
fn print(&self) {
match self.output_format {
OutputFormat::Json => self.print_json(),
OutputFormat::Normal => unimplemented!(),
}
}
fn print_json(&self) {
if let Some(records) = &self.records {
println!("{}", json::serialize_records(records));
}
}
}
enum OutputFormat {
Normal,
Json,
}
struct Record {
priority_facility: u32,
_sequence: u64,
timestamp_us: u64,
message: String,
}
impl Record {
fn from_str_fields(pri_fac: &str, seq: &str, time: &str, msg: String) -> UResult<Record> {
let pri_fac = str::parse(pri_fac);
let seq = str::parse(seq);
let time = str::parse(time);
match (pri_fac, seq, time) {
(Ok(pri_fac), Ok(seq), Ok(time)) => Ok(Record {
priority_facility: pri_fac,
_sequence: seq,
timestamp_us: time,
message: msg,
}),
_ => Err(USimpleError::new(1, "Failed to parse record field(s)")),
}
}
}

142
src/uu/dmesg/src/json.rs Normal file
View File

@@ -0,0 +1,142 @@
// This file is part of the uutils util-linux package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use serde::Serialize;
use std::io;
pub fn serialize_records(records: &Vec<crate::Record>) -> String {
let json = Dmesg::from(records);
let formatter = DmesgFormatter::new();
let mut buf = vec![];
let mut serializer = serde_json::Serializer::with_formatter(&mut buf, formatter);
json.serialize(&mut serializer).unwrap();
String::from_utf8_lossy(&buf).to_string()
}
#[derive(serde::Serialize)]
struct Dmesg<'a> {
dmesg: Vec<Record<'a>>,
}
#[derive(serde::Serialize)]
struct Record<'a> {
pri: u32,
time: u64,
msg: &'a str,
}
impl<'a> From<&'a Vec<crate::Record>> for Dmesg<'a> {
fn from(value: &'a Vec<crate::Record>) -> Self {
let mut dmesg_json = Dmesg { dmesg: vec![] };
for record in value {
let record_json = Record {
pri: record.priority_facility,
time: record.timestamp_us,
msg: &record.message,
};
dmesg_json.dmesg.push(record_json);
}
dmesg_json
}
}
struct DmesgFormatter {
nesting_depth: i32,
}
impl DmesgFormatter {
const SINGLE_INDENTATION: &[u8] = b" ";
fn new() -> Self {
DmesgFormatter { nesting_depth: 0 }
}
fn write_indentation<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
for _ in 0..self.nesting_depth {
writer.write_all(Self::SINGLE_INDENTATION)?;
}
Ok(())
}
}
impl serde_json::ser::Formatter for DmesgFormatter {
fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.nesting_depth += 1;
writer.write_all(b"{\n")
}
fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
writer.write_all(b"\n")?;
self.nesting_depth -= 1;
self.write_indentation(writer)?;
writer.write_all(b"}")
}
fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.nesting_depth += 1;
writer.write_all(b"[\n")
}
fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
writer.write_all(b"\n")?;
self.nesting_depth -= 1;
self.write_indentation(writer)?;
writer.write_all(b"]")
}
fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + io::Write,
{
if !first {
writer.write_all(b",\n")?;
}
self.write_indentation(writer)
}
fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
writer.write_all(b": ")
}
fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + io::Write,
{
if first {
self.write_indentation(writer)
} else {
writer.write_all(b",")
}
}
fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
where
W: ?Sized + io::Write,
{
// The only u64 field in Dmesg is time, which requires a specific format
let seconds = value / 1000000;
let sub_seconds = value % 1000000;
let repr = format!("{:>5}.{:0>6}", seconds, sub_seconds);
writer.write_all(repr.as_bytes())
}
}

1
src/uu/dmesg/src/main.rs Normal file
View File

@@ -0,0 +1 @@
uucore::bin!(uu_dmesg);

View File

@@ -0,0 +1,32 @@
// This file is part of the uutils util-linux package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use crate::common::util::TestScenario;
#[test]
fn test_invalid_arg() {
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
}
#[test]
fn test_kmsg_nonexistent_file() {
new_ucmd!()
.arg("--kmsg-file")
.arg("definitely-nonexistent-file")
.fails()
.code_is(1)
.no_stdout()
.stderr_is("dmesg: cannot open definitely-nonexistent-file: No such file or directory\n");
}
#[test]
fn test_kmsg_json() {
new_ucmd!()
.arg("--kmsg-file")
.arg("kmsg.input")
.arg("--json")
.run()
.no_stderr()
.stdout_is_templated_fixture("test_kmsg_json.expected", &[("\r\n", "\n")]);
}

BIN
tests/fixtures/dmesg/kmsg.input vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,645 @@
{
"dmesg": [
{
"pri": 32,
"time": 0.000000,
"msg": "LOG_EMERG LOG_AUTH"
},{
"pri": 80,
"time": 1000.000000,
"msg": "LOG_EMERG LOG_AUTHPRIV"
},{
"pri": 72,
"time": 2000.000000,
"msg": "LOG_EMERG LOG_CRON"
},{
"pri": 24,
"time": 3000.000000,
"msg": "LOG_EMERG LOG_DAEMON"
},{
"pri": 88,
"time": 4000.000000,
"msg": "LOG_EMERG LOG_FTP"
},{
"pri": 0,
"time": 5000.000000,
"msg": "LOG_EMERG LOG_KERN"
},{
"pri": 128,
"time": 6000.000000,
"msg": "LOG_EMERG LOG_LOCAL0"
},{
"pri": 136,
"time": 7000.000000,
"msg": "LOG_EMERG LOG_LOCAL1"
},{
"pri": 144,
"time": 8000.000000,
"msg": "LOG_EMERG LOG_LOCAL2"
},{
"pri": 152,
"time": 9000.000000,
"msg": "LOG_EMERG LOG_LOCAL3"
},{
"pri": 160,
"time": 10000.000000,
"msg": "LOG_EMERG LOG_LOCAL4"
},{
"pri": 168,
"time": 11000.000000,
"msg": "LOG_EMERG LOG_LOCAL5"
},{
"pri": 176,
"time": 12000.000000,
"msg": "LOG_EMERG LOG_LOCAL6"
},{
"pri": 184,
"time": 13000.000000,
"msg": "LOG_EMERG LOG_LOCAL7"
},{
"pri": 48,
"time": 14000.000000,
"msg": "LOG_EMERG LOG_LPR"
},{
"pri": 16,
"time": 15000.000000,
"msg": "LOG_EMERG LOG_MAIL"
},{
"pri": 56,
"time": 16000.000000,
"msg": "LOG_EMERG LOG_NEWS"
},{
"pri": 40,
"time": 17000.000000,
"msg": "LOG_EMERG LOG_SYSLOG"
},{
"pri": 8,
"time": 18000.000000,
"msg": "LOG_EMERG LOG_USER"
},{
"pri": 64,
"time": 19000.000000,
"msg": "LOG_EMERG LOG_UUCP"
},{
"pri": 33,
"time": 20000.000000,
"msg": "LOG_ALERT LOG_AUTH"
},{
"pri": 81,
"time": 21000.000000,
"msg": "LOG_ALERT LOG_AUTHPRIV"
},{
"pri": 73,
"time": 22000.000000,
"msg": "LOG_ALERT LOG_CRON"
},{
"pri": 25,
"time": 23000.000000,
"msg": "LOG_ALERT LOG_DAEMON"
},{
"pri": 89,
"time": 24000.000000,
"msg": "LOG_ALERT LOG_FTP"
},{
"pri": 1,
"time": 25000.000000,
"msg": "LOG_ALERT LOG_KERN"
},{
"pri": 129,
"time": 26000.000000,
"msg": "LOG_ALERT LOG_LOCAL0"
},{
"pri": 137,
"time": 27000.000000,
"msg": "LOG_ALERT LOG_LOCAL1"
},{
"pri": 145,
"time": 28000.000000,
"msg": "LOG_ALERT LOG_LOCAL2"
},{
"pri": 153,
"time": 29000.000000,
"msg": "LOG_ALERT LOG_LOCAL3"
},{
"pri": 161,
"time": 30000.000000,
"msg": "LOG_ALERT LOG_LOCAL4"
},{
"pri": 169,
"time": 31000.000000,
"msg": "LOG_ALERT LOG_LOCAL5"
},{
"pri": 177,
"time": 32000.000000,
"msg": "LOG_ALERT LOG_LOCAL6"
},{
"pri": 185,
"time": 33000.000000,
"msg": "LOG_ALERT LOG_LOCAL7"
},{
"pri": 49,
"time": 34000.000000,
"msg": "LOG_ALERT LOG_LPR"
},{
"pri": 17,
"time": 35000.000000,
"msg": "LOG_ALERT LOG_MAIL"
},{
"pri": 57,
"time": 36000.000000,
"msg": "LOG_ALERT LOG_NEWS"
},{
"pri": 41,
"time": 37000.000000,
"msg": "LOG_ALERT LOG_SYSLOG"
},{
"pri": 9,
"time": 38000.000000,
"msg": "LOG_ALERT LOG_USER"
},{
"pri": 65,
"time": 39000.000000,
"msg": "LOG_ALERT LOG_UUCP"
},{
"pri": 34,
"time": 40000.000000,
"msg": "LOG_CRIT LOG_AUTH"
},{
"pri": 82,
"time": 41000.000000,
"msg": "LOG_CRIT LOG_AUTHPRIV"
},{
"pri": 74,
"time": 42000.000000,
"msg": "LOG_CRIT LOG_CRON"
},{
"pri": 26,
"time": 43000.000000,
"msg": "LOG_CRIT LOG_DAEMON"
},{
"pri": 90,
"time": 44000.000000,
"msg": "LOG_CRIT LOG_FTP"
},{
"pri": 2,
"time": 45000.000000,
"msg": "LOG_CRIT LOG_KERN"
},{
"pri": 130,
"time": 46000.000000,
"msg": "LOG_CRIT LOG_LOCAL0"
},{
"pri": 138,
"time": 47000.000000,
"msg": "LOG_CRIT LOG_LOCAL1"
},{
"pri": 146,
"time": 48000.000000,
"msg": "LOG_CRIT LOG_LOCAL2"
},{
"pri": 154,
"time": 49000.000000,
"msg": "LOG_CRIT LOG_LOCAL3"
},{
"pri": 162,
"time": 50000.000000,
"msg": "LOG_CRIT LOG_LOCAL4"
},{
"pri": 170,
"time": 51000.000000,
"msg": "LOG_CRIT LOG_LOCAL5"
},{
"pri": 178,
"time": 52000.000000,
"msg": "LOG_CRIT LOG_LOCAL6"
},{
"pri": 186,
"time": 53000.000000,
"msg": "LOG_CRIT LOG_LOCAL7"
},{
"pri": 50,
"time": 54000.000000,
"msg": "LOG_CRIT LOG_LPR"
},{
"pri": 18,
"time": 55000.000000,
"msg": "LOG_CRIT LOG_MAIL"
},{
"pri": 58,
"time": 56000.000000,
"msg": "LOG_CRIT LOG_NEWS"
},{
"pri": 42,
"time": 57000.000000,
"msg": "LOG_CRIT LOG_SYSLOG"
},{
"pri": 10,
"time": 58000.000000,
"msg": "LOG_CRIT LOG_USER"
},{
"pri": 66,
"time": 59000.000000,
"msg": "LOG_CRIT LOG_UUCP"
},{
"pri": 35,
"time": 60000.000000,
"msg": "LOG_ERR LOG_AUTH"
},{
"pri": 83,
"time": 61000.000000,
"msg": "LOG_ERR LOG_AUTHPRIV"
},{
"pri": 75,
"time": 62000.000000,
"msg": "LOG_ERR LOG_CRON"
},{
"pri": 27,
"time": 63000.000000,
"msg": "LOG_ERR LOG_DAEMON"
},{
"pri": 91,
"time": 64000.000000,
"msg": "LOG_ERR LOG_FTP"
},{
"pri": 3,
"time": 65000.000000,
"msg": "LOG_ERR LOG_KERN"
},{
"pri": 131,
"time": 66000.000000,
"msg": "LOG_ERR LOG_LOCAL0"
},{
"pri": 139,
"time": 67000.000000,
"msg": "LOG_ERR LOG_LOCAL1"
},{
"pri": 147,
"time": 68000.000000,
"msg": "LOG_ERR LOG_LOCAL2"
},{
"pri": 155,
"time": 69000.000000,
"msg": "LOG_ERR LOG_LOCAL3"
},{
"pri": 163,
"time": 70000.000000,
"msg": "LOG_ERR LOG_LOCAL4"
},{
"pri": 171,
"time": 71000.000000,
"msg": "LOG_ERR LOG_LOCAL5"
},{
"pri": 179,
"time": 72000.000000,
"msg": "LOG_ERR LOG_LOCAL6"
},{
"pri": 187,
"time": 73000.000000,
"msg": "LOG_ERR LOG_LOCAL7"
},{
"pri": 51,
"time": 74000.000000,
"msg": "LOG_ERR LOG_LPR"
},{
"pri": 19,
"time": 75000.000000,
"msg": "LOG_ERR LOG_MAIL"
},{
"pri": 59,
"time": 76000.000000,
"msg": "LOG_ERR LOG_NEWS"
},{
"pri": 43,
"time": 77000.000000,
"msg": "LOG_ERR LOG_SYSLOG"
},{
"pri": 11,
"time": 78000.000000,
"msg": "LOG_ERR LOG_USER"
},{
"pri": 67,
"time": 79000.000000,
"msg": "LOG_ERR LOG_UUCP"
},{
"pri": 36,
"time": 80000.000000,
"msg": "LOG_WARNING LOG_AUTH"
},{
"pri": 84,
"time": 81000.000000,
"msg": "LOG_WARNING LOG_AUTHPRIV"
},{
"pri": 76,
"time": 82000.000000,
"msg": "LOG_WARNING LOG_CRON"
},{
"pri": 28,
"time": 83000.000000,
"msg": "LOG_WARNING LOG_DAEMON"
},{
"pri": 92,
"time": 84000.000000,
"msg": "LOG_WARNING LOG_FTP"
},{
"pri": 4,
"time": 85000.000000,
"msg": "LOG_WARNING LOG_KERN"
},{
"pri": 132,
"time": 86000.000000,
"msg": "LOG_WARNING LOG_LOCAL0"
},{
"pri": 140,
"time": 87000.000000,
"msg": "LOG_WARNING LOG_LOCAL1"
},{
"pri": 148,
"time": 88000.000000,
"msg": "LOG_WARNING LOG_LOCAL2"
},{
"pri": 156,
"time": 89000.000000,
"msg": "LOG_WARNING LOG_LOCAL3"
},{
"pri": 164,
"time": 90000.000000,
"msg": "LOG_WARNING LOG_LOCAL4"
},{
"pri": 172,
"time": 91000.000000,
"msg": "LOG_WARNING LOG_LOCAL5"
},{
"pri": 180,
"time": 92000.000000,
"msg": "LOG_WARNING LOG_LOCAL6"
},{
"pri": 188,
"time": 93000.000000,
"msg": "LOG_WARNING LOG_LOCAL7"
},{
"pri": 52,
"time": 94000.000000,
"msg": "LOG_WARNING LOG_LPR"
},{
"pri": 20,
"time": 95000.000000,
"msg": "LOG_WARNING LOG_MAIL"
},{
"pri": 60,
"time": 96000.000000,
"msg": "LOG_WARNING LOG_NEWS"
},{
"pri": 44,
"time": 97000.000000,
"msg": "LOG_WARNING LOG_SYSLOG"
},{
"pri": 12,
"time": 98000.000000,
"msg": "LOG_WARNING LOG_USER"
},{
"pri": 68,
"time": 99000.000000,
"msg": "LOG_WARNING LOG_UUCP"
},{
"pri": 37,
"time": 100000.000000,
"msg": "LOG_NOTICE LOG_AUTH"
},{
"pri": 85,
"time": 101000.000000,
"msg": "LOG_NOTICE LOG_AUTHPRIV"
},{
"pri": 77,
"time": 102000.000000,
"msg": "LOG_NOTICE LOG_CRON"
},{
"pri": 29,
"time": 103000.000000,
"msg": "LOG_NOTICE LOG_DAEMON"
},{
"pri": 93,
"time": 104000.000000,
"msg": "LOG_NOTICE LOG_FTP"
},{
"pri": 5,
"time": 105000.000000,
"msg": "LOG_NOTICE LOG_KERN"
},{
"pri": 133,
"time": 106000.000000,
"msg": "LOG_NOTICE LOG_LOCAL0"
},{
"pri": 141,
"time": 107000.000000,
"msg": "LOG_NOTICE LOG_LOCAL1"
},{
"pri": 149,
"time": 108000.000000,
"msg": "LOG_NOTICE LOG_LOCAL2"
},{
"pri": 157,
"time": 109000.000000,
"msg": "LOG_NOTICE LOG_LOCAL3"
},{
"pri": 165,
"time": 110000.000000,
"msg": "LOG_NOTICE LOG_LOCAL4"
},{
"pri": 173,
"time": 111000.000000,
"msg": "LOG_NOTICE LOG_LOCAL5"
},{
"pri": 181,
"time": 112000.000000,
"msg": "LOG_NOTICE LOG_LOCAL6"
},{
"pri": 189,
"time": 113000.000000,
"msg": "LOG_NOTICE LOG_LOCAL7"
},{
"pri": 53,
"time": 114000.000000,
"msg": "LOG_NOTICE LOG_LPR"
},{
"pri": 21,
"time": 115000.000000,
"msg": "LOG_NOTICE LOG_MAIL"
},{
"pri": 61,
"time": 116000.000000,
"msg": "LOG_NOTICE LOG_NEWS"
},{
"pri": 45,
"time": 117000.000000,
"msg": "LOG_NOTICE LOG_SYSLOG"
},{
"pri": 13,
"time": 118000.000000,
"msg": "LOG_NOTICE LOG_USER"
},{
"pri": 69,
"time": 119000.000000,
"msg": "LOG_NOTICE LOG_UUCP"
},{
"pri": 38,
"time": 120000.000000,
"msg": "LOG_INFO LOG_AUTH"
},{
"pri": 86,
"time": 121000.000000,
"msg": "LOG_INFO LOG_AUTHPRIV"
},{
"pri": 78,
"time": 122000.000000,
"msg": "LOG_INFO LOG_CRON"
},{
"pri": 30,
"time": 123000.000000,
"msg": "LOG_INFO LOG_DAEMON"
},{
"pri": 94,
"time": 124000.000000,
"msg": "LOG_INFO LOG_FTP"
},{
"pri": 6,
"time": 125000.000000,
"msg": "LOG_INFO LOG_KERN"
},{
"pri": 134,
"time": 126000.000000,
"msg": "LOG_INFO LOG_LOCAL0"
},{
"pri": 142,
"time": 127000.000000,
"msg": "LOG_INFO LOG_LOCAL1"
},{
"pri": 150,
"time": 128000.000000,
"msg": "LOG_INFO LOG_LOCAL2"
},{
"pri": 158,
"time": 129000.000000,
"msg": "LOG_INFO LOG_LOCAL3"
},{
"pri": 166,
"time": 130000.000000,
"msg": "LOG_INFO LOG_LOCAL4"
},{
"pri": 174,
"time": 131000.000000,
"msg": "LOG_INFO LOG_LOCAL5"
},{
"pri": 182,
"time": 132000.000000,
"msg": "LOG_INFO LOG_LOCAL6"
},{
"pri": 190,
"time": 133000.000000,
"msg": "LOG_INFO LOG_LOCAL7"
},{
"pri": 54,
"time": 134000.000000,
"msg": "LOG_INFO LOG_LPR"
},{
"pri": 22,
"time": 135000.000000,
"msg": "LOG_INFO LOG_MAIL"
},{
"pri": 62,
"time": 136000.000000,
"msg": "LOG_INFO LOG_NEWS"
},{
"pri": 46,
"time": 137000.000000,
"msg": "LOG_INFO LOG_SYSLOG"
},{
"pri": 14,
"time": 138000.000000,
"msg": "LOG_INFO LOG_USER"
},{
"pri": 70,
"time": 139000.000000,
"msg": "LOG_INFO LOG_UUCP"
},{
"pri": 39,
"time": 140000.000000,
"msg": "LOG_DEBUG LOG_AUTH"
},{
"pri": 87,
"time": 141000.000000,
"msg": "LOG_DEBUG LOG_AUTHPRIV"
},{
"pri": 79,
"time": 142000.000000,
"msg": "LOG_DEBUG LOG_CRON"
},{
"pri": 31,
"time": 143000.000000,
"msg": "LOG_DEBUG LOG_DAEMON"
},{
"pri": 95,
"time": 144000.000000,
"msg": "LOG_DEBUG LOG_FTP"
},{
"pri": 7,
"time": 145000.000000,
"msg": "LOG_DEBUG LOG_KERN"
},{
"pri": 135,
"time": 146000.000000,
"msg": "LOG_DEBUG LOG_LOCAL0"
},{
"pri": 143,
"time": 147000.000000,
"msg": "LOG_DEBUG LOG_LOCAL1"
},{
"pri": 151,
"time": 148000.000000,
"msg": "LOG_DEBUG LOG_LOCAL2"
},{
"pri": 159,
"time": 149000.000000,
"msg": "LOG_DEBUG LOG_LOCAL3"
},{
"pri": 167,
"time": 150000.000000,
"msg": "LOG_DEBUG LOG_LOCAL4"
},{
"pri": 175,
"time": 151000.000000,
"msg": "LOG_DEBUG LOG_LOCAL5"
},{
"pri": 183,
"time": 152000.000000,
"msg": "LOG_DEBUG LOG_LOCAL6"
},{
"pri": 191,
"time": 153000.000000,
"msg": "LOG_DEBUG LOG_LOCAL7"
},{
"pri": 55,
"time": 154000.000000,
"msg": "LOG_DEBUG LOG_LPR"
},{
"pri": 23,
"time": 155000.000000,
"msg": "LOG_DEBUG LOG_MAIL"
},{
"pri": 63,
"time": 156000.000000,
"msg": "LOG_DEBUG LOG_NEWS"
},{
"pri": 47,
"time": 157000.000000,
"msg": "LOG_DEBUG LOG_SYSLOG"
},{
"pri": 15,
"time": 158000.000000,
"msg": "LOG_DEBUG LOG_USER"
},{
"pri": 71,
"time": 159000.000000,
"msg": "LOG_DEBUG LOG_UUCP"
}
]
}

View File

@@ -32,3 +32,7 @@ mod test_setsid;
#[cfg(feature = "last")] #[cfg(feature = "last")]
#[path = "by-util/test_last.rs"] #[path = "by-util/test_last.rs"]
mod test_last; mod test_last;
#[cfg(feature = "dmesg")]
#[path = "by-util/test_dmesg.rs"]
mod test_dmesg;