Skip to content

Commit

Permalink
memfaultd 1.15.0 (Build 2534584)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Oct 7, 2024
1 parent 3a9e0c5 commit ba4c2cd
Show file tree
Hide file tree
Showing 115 changed files with 2,890 additions and 809 deletions.
173 changes: 70 additions & 103 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
BUILD ID: 2370319
GIT COMMIT: 41269b2621
VERSION: 1.14.0
BUILD ID: 2534584
GIT COMMIT: e2c67955b9
VERSION: 1.15.0
2 changes: 1 addition & 1 deletion memfault-ssf/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "memfault-ssf"
version = "1.14.0"
version = "1.15.0"
edition = "2021"
description = "Supporting crate for the Memfault memfaultd embedded Linux agent"
homepage = "https://github.com/memfault/memfaultd"
Expand Down
Empty file added memfault-ssf/VERSION
Empty file.
2 changes: 1 addition & 1 deletion memfaultc-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "memfaultc-sys"
version = "1.14.0"
version = "1.15.0"
edition = "2021"
autobins = false
description = "Supporting crate for the Memfault memfaultd embedded Linux agent"
Expand Down
Empty file added memfaultc-sys/VERSION
Empty file.
19 changes: 12 additions & 7 deletions memfaultd/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "memfaultd"
version = "1.14.0"
version = "1.15.0"
edition = "2021"
autobins = false
rust-version = "1.72"
Expand Down Expand Up @@ -28,8 +28,8 @@ name= "mfw"
path= "src/bin/mfw.rs"

[dependencies]
memfaultc-sys = { path= "../memfaultc-sys", version = "1.14.0" }
ssf = { package = "memfault-ssf", path= "../memfault-ssf", version = "1.14.0" }
memfaultc-sys = { path= "../memfaultc-sys", version = "1.15.0" }
ssf = { package = "memfault-ssf", path= "../memfault-ssf", version = "1.15.0" }
argh = "0.1.10"
cfg-if = "1.0.0"
chrono = { version = "0.4.23", features = ["serde"]}
Expand All @@ -50,7 +50,7 @@ serde_json = "1.0.89"
serde_repr = "0.1"
shuteye = "0.3.3"
signal-hook = "0.3.14"
stderrlog = "0.5.4"
stderrlog = "0.6.0"
strum = { version = "0.24", features = ["derive"] }
strum_macros = "0.24"
tempfile = "3.3.0"
Expand All @@ -73,6 +73,7 @@ regex= { version = "1.10.2", optional = true}
nom = "7.1.3"
sealed_test = "1.1.0"
zip = { version = "1.1.4", default-features = false, features = ["deflate"]}
lazy_static = "1.5.0"

[target.'cfg(target_os = "linux")'.dependencies]
procfs = { version = "0.15.1", optional = true }
Expand All @@ -95,8 +96,12 @@ nom = "7.1.3"
name = "logs_to_metrics"
harness = false

[[bench]]
name = "log_level_mapper"
harness = false

[features]
default = ["coredump", "collectd", "logging", "log-to-metrics", "systemd", "rust-tls" ]
default = ["coredump", "logging", "regex", "systemd", "rust-tls"]
coredump = [
"memfaultc-sys/coredump",
"dep:prctl",
Expand All @@ -107,13 +112,13 @@ coredump = [
"dep:goblin",
"dep:scroll"
]
collectd = []
swupdate = ["memfaultc-sys/swupdate"]
logging = ["dep:governor", "dep:rmp-serde", "dep:rmpv"]
systemd = ["memfaultc-sys/systemd"]
rust-tls = ["reqwest/rustls-tls"]
openssl-tls = ["reqwest/native-tls"]
openssl-vendored-tls = ["reqwest/native-tls-vendored"]
log-to-metrics = ["dep:regex"]
regex = ["dep:regex"]
log-to-metrics = ["regex"]
experimental = ["mfw"]
mfw = []
2 changes: 1 addition & 1 deletion memfaultd/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ apt install libsystemd-dev libconfig-dev
#### macOS

```sh
brew install libconfig
brew install pkg-config libconfig
```

(note: `libsystemd` is not available on macOS and the build system will not try
Expand Down
Empty file added memfaultd/VERSION
Empty file.
84 changes: 84 additions & 0 deletions memfaultd/benches/log_level_mapper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// Copyright (c) Memfault, Inc.
// See License.txt for details
use chrono::Utc;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use memfaultd::config::{LevelMappingConfig, LevelMappingRegex};
use memfaultd::logs::log_entry::{LogData, LogEntry};
use memfaultd::logs::log_level_mapper::LogLevelMapper;

const BENCH_LEVELS: &[&str] = &[
"EMERG", "ALERT", "CRIT", "ERROR", "WARN", "NOTICE", "INFO", "DEBUG",
];

fn build_log_line(level: &str, message: &str) -> LogEntry {
let data = LogData {
message: message.to_string(),
pid: None,
systemd_unit: None,
priority: Some(level.to_string()),
original_priority: None,
extra_fields: Default::default(),
};

LogEntry {
ts: Utc::now(),
data,
}
}

fn build_regex_string(level: &str) -> String {
format!(r"\[.*\] \[{}\]:", level)
}

fn build_log_mapper() -> LogLevelMapper {
let regex = BENCH_LEVELS
.iter()
.map(|level| build_regex_string(level))
.collect::<Vec<_>>();

let regex = LevelMappingRegex {
emergency: Some(regex[0].clone()),
alert: Some(regex[1].clone()),
critical: Some(regex[2].clone()),
error: Some(regex[3].clone()),
warning: Some(regex[4].clone()),
notice: Some(regex[5].clone()),
info: Some(regex[6].clone()),
debug: Some(regex[7].clone()),
};
let level_config = LevelMappingConfig {
enable: true,
regex: Some(regex),
};

LogLevelMapper::try_from(&level_config).expect("Failed to build log level mapper")
}

fn map_logs(num_log_lines: u64, mapper: &LogLevelMapper) {
for i in 0..num_log_lines {
let cur_level_idx = i % BENCH_LEVELS.len() as u64;
let cur_level = BENCH_LEVELS[cur_level_idx as usize];
let mut log_line = build_log_line(cur_level, "This is a test log message");
mapper.map_log(&mut log_line).expect("Error mapping log");
}
}

fn log_mapper_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("Log Level Mapper");
let num_log_lines = [100, 1000];
let level_mapper = build_log_mapper();

for num in num_log_lines {
group.throughput(Throughput::Elements(num));
group.bench_with_input(BenchmarkId::new("Log Level Mapper", num), &num, |b, num| {
// Send metrics to preallocate the metrics hashmap
b.iter(|| {
map_logs(*num, &level_mapper);
})
});
}
}

criterion_group!(benches, log_mapper_benchmark);
criterion_main!(benches);
24 changes: 16 additions & 8 deletions memfaultd/benches/logs_to_metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@ use std::{collections::HashMap, iter::repeat};

use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use memfaultd::config::LogToMetricRule;
use memfaultd::logs::log_entry::{LogData, LogEntry};
use memfaultd::logs::log_to_metrics::LogToMetrics;
use memfaultd::metrics::MetricReportManager;
use serde_json::{json, Value};
use ssf::ServiceJig;

fn log_line_from_str(line: &str) -> Value {
json!({
"data": {
"MESSAGE": line,
}
})
fn log_line_from_str(line: &str) -> LogEntry {
let data = LogData {
message: line.to_string(),
pid: None,
systemd_unit: None,
priority: None,
original_priority: None,
extra_fields: HashMap::new(),
};

LogEntry {
ts: chrono::Utc::now(),
data,
}
}

fn send_logs(num_log_lines: u64) {
Expand All @@ -31,7 +39,7 @@ fn send_logs(num_log_lines: u64) {
let log_lines = repeat("eager evaluation is bad")
.take(num_log_lines as usize)
.map(log_line_from_str)
.collect::<Vec<Value>>();
.collect::<Vec<LogEntry>>();

let mut logs_to_metrics = LogToMetrics::new(rules, report_service.mailbox.into());
log_lines.iter().for_each(|log_line| {
Expand Down
10 changes: 8 additions & 2 deletions memfaultd/builtin.conf
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ parameters.
"rotate_size_kib": 10240,
"rotate_after_seconds": 3600,
"storage": "persist",
"source": "fluent-bit"
"source": "journald",
"level_mapping": {
"enable": false
}
},
"mar": {
"mar_file_max_size_kib": 10240,
Expand All @@ -59,7 +62,10 @@ parameters.
"enable_daily_heartbeats": false,
"system_metric_collection": {
"poll_interval_seconds": 10,
"enable": false
"enable": true
},
"statsd_server": {
"bind_address": "127.0.0.1:8125"
}
}
}
12 changes: 10 additions & 2 deletions memfaultd/src/cli/memfault_core_handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ pub type ElfPtrSize = u32;
/// called by users directly. memfaultd is expected to set up the handler with the kernel by writing
/// the appropriate configuration to /proc/sys/kernel/core_pattern.
/// See https://mflt.io/linux-coredumps for more information.
/// `core` man page:
/// https://man7.org/linux/man-pages/man5/core.5.html
struct MemfaultCoreHandlerArgs {
/// use configuration file
#[argh(option, short = 'c')]
Expand All @@ -78,6 +80,12 @@ struct MemfaultCoreHandlerArgs {
#[argh(positional)]
pid: i32,

/// populated by the %e in the core_pattern
/// This is the value stored in /proc/<pid>/comm
/// for the crashing process's PID
#[argh(positional)]
comm: String,

/// verbose output
#[argh(switch, short = 'V')]
verbose: bool,
Expand Down Expand Up @@ -121,7 +129,7 @@ pub fn main() -> Result<()> {
let client = MemfaultdClient::from_config(&config);
match client {
Ok(client) => {
if let Err(e) = client.notify_crash() {
if let Err(e) = client.notify_crash(args.comm) {
debug!("Failed to notify memfaultd of crash: {:?}", e);
}

Expand Down Expand Up @@ -231,7 +239,7 @@ pub fn process_corefile(
let network_config = NetworkConfig::from(config);
let mar_entry = mar_builder
.set_metadata(Metadata::new_coredump(output_file_name, compression.into()))
.add_attachment(output_file_path)
.add_attachment(output_file_path)?
.save(&network_config)?;

debug!("Coredump MAR entry generated: {}", mar_entry.path.display());
Expand Down
5 changes: 3 additions & 2 deletions memfaultd/src/cli/memfault_watch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,16 @@ fn run_from_args(args: MemfaultWatchArgs) -> Result<i32> {
let mar_builder = MarEntryBuilder::new(&mar_staging_path)?;
let mar_entry = mar_builder
.set_metadata(metadata)
.add_attachment(stdio_log_file_path)
.add_attachment(stdio_log_file_path)?
.save(&network_config)?;

info!("MFW MAR entry generated: {}", mar_entry.path.display());

let client = MemfaultdClient::from_config(&config)
.map_err(|report| eyre!("Failed to create Memfaultd client from config! {report}"))?;

if client.notify_crash().is_err() {
// TODO: Add /proc/comm value for the crashing process here
if client.notify_crash("TODO".to_string()).is_err() {
error!("Unable to contact memfaultd. Is it running?");
} else {
debug!("Notified memfaultd about crash!");
Expand Down
2 changes: 1 addition & 1 deletion memfaultd/src/cli/memfaultctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ pub fn main() -> Result<()> {
reason,
file_name,
))
.add_copied_attachment(file_path)
.add_copied_attachment(file_path)?
.save(&network_config)
.map(|_entry| ())
}
Expand Down
9 changes: 8 additions & 1 deletion memfaultd/src/cli/memfaultd_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use reqwest::{
header::ACCEPT,
StatusCode,
};
use serde::{Deserialize, Serialize};

use crate::{
config::Config,
Expand All @@ -23,6 +24,11 @@ pub struct MemfaultdClient {
client: Client,
}

#[derive(Serialize, Deserialize)]
pub struct NotifyCrashRequest {
pub process_name: String,
}

pub struct DeleteToken(String);

pub enum ExportGetResponse {
Expand Down Expand Up @@ -111,9 +117,10 @@ impl MemfaultdClient {
}
}

pub fn notify_crash(&self) -> Result<()> {
pub fn notify_crash(&self, comm: String) -> Result<()> {
self.client
.post(format!("{}{}", self.base_url, "/v1/crash/report"))
.json(&NotifyCrashRequest { process_name: comm })
.send()?;
Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions memfaultd/src/cli/show_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ pub fn show_settings(config_path: Option<&Path>) -> Result<()> {
"coredump",
#[cfg(feature = "logging")]
"logging",
#[cfg(feature = "log-to-metrics")]
"log-to-metrics",
#[cfg(feature = "regex")]
"regex",
#[cfg(feature = "systemd")]
"systemd",
];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: memfaultd/src/collectd/collectd_handler.rs
expression: metrics
expression: mock.take_metrics().unwrap()
---
{
"cpufreq/0/cpu/idle": 0.0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: memfaultd/src/collectd/collectd_handler.rs
expression: "serde_json::to_string_pretty(&metrics).expect(\"metric_store should be serializable\")"
expression: fixture.mock.take_metrics().unwrap()
---
{
"cpu/0/cpu/idle": 0.0
Expand Down
Loading

0 comments on commit ba4c2cd

Please sign in to comment.