v0.25.5
This commit is contained in:
1 parent
1dea7f55c8
commit
c819f0a335
151 files changed
+7610
-4264
No files matched your search
+99
-24
@@ -169,7 +169,10 @@ struct LiveLogFilters {
|
||||
}
|
||||
|
||||
fn log_string<'a>(entry: &'a serde_json::Value, key: &str) -> &'a str {
|
||||
entry.get(key).and_then(|value| value.as_str()).unwrap_or("-")
|
||||
entry
|
||||
.get(key)
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or("-")
|
||||
}
|
||||
|
||||
fn log_optional_string<'a>(entry: &'a serde_json::Value, key: &str) -> Option<&'a str> {
|
||||
@@ -178,7 +181,10 @@ fn log_optional_string<'a>(entry: &'a serde_json::Value, key: &str) -> Option<&'
|
||||
|
||||
fn live_status_matches(filter: &str, status: u64) -> bool {
|
||||
if let Some(prefix) = filter.strip_suffix("xx") {
|
||||
return prefix.parse::<u64>().ok().is_some_and(|class| status / 100 == class);
|
||||
return prefix
|
||||
.parse::<u64>()
|
||||
.ok()
|
||||
.is_some_and(|class| status / 100 == class);
|
||||
}
|
||||
filter.parse::<u64>().ok() == Some(status)
|
||||
}
|
||||
@@ -205,7 +211,10 @@ fn live_log_matches(entry: &serde_json::Value, filters: &LiveLogFilters) -> bool
|
||||
return false;
|
||||
}
|
||||
}
|
||||
let status = entry.get("status").and_then(|value| value.as_u64()).unwrap_or(0);
|
||||
let status = entry
|
||||
.get("status")
|
||||
.and_then(|value| value.as_u64())
|
||||
.unwrap_or(0);
|
||||
if filters
|
||||
.status
|
||||
.as_ref()
|
||||
@@ -234,7 +243,10 @@ fn live_log_matches(entry: &serde_json::Value, filters: &LiveLogFilters) -> bool
|
||||
}
|
||||
|
||||
fn live_time(entry: &serde_json::Value) -> String {
|
||||
let ms = entry.get("time_ms").and_then(|value| value.as_u64()).unwrap_or(0);
|
||||
let ms = entry
|
||||
.get("time_ms")
|
||||
.and_then(|value| value.as_u64())
|
||||
.unwrap_or(0);
|
||||
let seconds = (ms / 1000) % 86_400;
|
||||
format!(
|
||||
"{:02}:{:02}:{:02}.{:03}Z",
|
||||
@@ -246,8 +258,14 @@ fn live_time(entry: &serde_json::Value) -> String {
|
||||
}
|
||||
|
||||
fn print_live_entry(entry: &serde_json::Value, detail: bool) {
|
||||
let id = entry.get("id").and_then(|value| value.as_u64()).unwrap_or(0);
|
||||
let status = entry.get("status").and_then(|value| value.as_u64()).unwrap_or(0);
|
||||
let id = entry
|
||||
.get("id")
|
||||
.and_then(|value| value.as_u64())
|
||||
.unwrap_or(0);
|
||||
let status = entry
|
||||
.get("status")
|
||||
.and_then(|value| value.as_u64())
|
||||
.unwrap_or(0);
|
||||
let duration = entry
|
||||
.get("duration_ms")
|
||||
.and_then(|value| value.as_u64())
|
||||
@@ -304,7 +322,9 @@ fn live_filters_summary(filters: &LiveLogFilters) -> String {
|
||||
let mut values = Vec::new();
|
||||
macro_rules! add {
|
||||
($name:literal, $value:expr) => {
|
||||
if let Some(value) = $value.as_ref() { values.push(format!("{}={}", $name, value)); }
|
||||
if let Some(value) = $value.as_ref() {
|
||||
values.push(format!("{}={}", $name, value));
|
||||
}
|
||||
};
|
||||
}
|
||||
add!("host", filters.host);
|
||||
@@ -317,11 +337,23 @@ fn live_filters_summary(filters: &LiveLogFilters) -> String {
|
||||
add!("cache", filters.cache);
|
||||
add!("status", filters.status);
|
||||
add!("path", filters.path_prefix);
|
||||
if filters.errors_only { values.push("errors=on".into()); }
|
||||
if let Some(ms) = filters.slow_ms { values.push(format!("slow>={ms}ms")); }
|
||||
if filters.detail { values.push("detail=on".into()); }
|
||||
if filters.paused { values.push("paused".into()); }
|
||||
if values.is_empty() { "none".into() } else { values.join(" ") }
|
||||
if filters.errors_only {
|
||||
values.push("errors=on".into());
|
||||
}
|
||||
if let Some(ms) = filters.slow_ms {
|
||||
values.push(format!("slow>={ms}ms"));
|
||||
}
|
||||
if filters.detail {
|
||||
values.push("detail=on".into());
|
||||
}
|
||||
if filters.paused {
|
||||
values.push("paused".into());
|
||||
}
|
||||
if values.is_empty() {
|
||||
"none".into()
|
||||
} else {
|
||||
values.join(" ")
|
||||
}
|
||||
}
|
||||
|
||||
fn live_help() {
|
||||
@@ -356,20 +388,44 @@ fn handle_live_command(
|
||||
match command.as_str() {
|
||||
"help" | "?" => live_help(),
|
||||
"filters" => println!("filters: {}", live_filters_summary(filters)),
|
||||
"reset" => { *filters = LiveLogFilters::default(); println!("filters cleared"); }
|
||||
"pause" => { filters.paused = true; println!("paused"); }
|
||||
"resume" => { filters.paused = false; println!("resumed"); }
|
||||
"clear" => { print!("\x1b[2J\x1b[H"); io::stdout().flush()?; }
|
||||
"reset" => {
|
||||
*filters = LiveLogFilters::default();
|
||||
println!("filters cleared");
|
||||
}
|
||||
"pause" => {
|
||||
filters.paused = true;
|
||||
println!("paused");
|
||||
}
|
||||
"resume" => {
|
||||
filters.paused = false;
|
||||
println!("resumed");
|
||||
}
|
||||
"clear" => {
|
||||
print!("\x1b[2J\x1b[H");
|
||||
io::stdout().flush()?;
|
||||
}
|
||||
"quit" | "exit" | "q" => return Ok(false),
|
||||
"detail" => filters.detail = matches!(value, "on" | "1" | "true"),
|
||||
"errors" => filters.errors_only = matches!(value, "on" | "1" | "true"),
|
||||
"slow" => {
|
||||
filters.slow_ms = if matches!(value, "" | "off" | "*") { None } else { Some(value.parse().context("slow expects milliseconds or off")?) };
|
||||
filters.slow_ms = if matches!(value, "" | "off" | "*") {
|
||||
None
|
||||
} else {
|
||||
Some(value.parse().context("slow expects milliseconds or off")?)
|
||||
};
|
||||
}
|
||||
"status" => {
|
||||
if matches!(value, "" | "*" | "off") { filters.status = None; }
|
||||
else {
|
||||
ensure!(matches!(value, "1xx" | "2xx" | "3xx" | "4xx" | "5xx") || value.parse::<u16>().ok().is_some_and(|v| (100..=599).contains(&v)), "status expects 100..599 or 1xx..5xx");
|
||||
if matches!(value, "" | "*" | "off") {
|
||||
filters.status = None;
|
||||
} else {
|
||||
ensure!(
|
||||
matches!(value, "1xx" | "2xx" | "3xx" | "4xx" | "5xx")
|
||||
|| value
|
||||
.parse::<u16>()
|
||||
.ok()
|
||||
.is_some_and(|v| (100..=599).contains(&v)),
|
||||
"status expects 100..599 or 1xx..5xx"
|
||||
);
|
||||
filters.status = Some(value.to_ascii_lowercase());
|
||||
}
|
||||
}
|
||||
@@ -378,9 +434,19 @@ fn handle_live_command(
|
||||
"backend" => set_live_filter(&mut filters.backend, value),
|
||||
"route" => set_live_filter(&mut filters.route, value),
|
||||
"client" => set_live_filter(&mut filters.client, value),
|
||||
"method" => { set_live_filter(&mut filters.method, value); if let Some(v) = filters.method.as_mut() { *v = v.to_ascii_uppercase(); } },
|
||||
"method" => {
|
||||
set_live_filter(&mut filters.method, value);
|
||||
if let Some(v) = filters.method.as_mut() {
|
||||
*v = v.to_ascii_uppercase();
|
||||
}
|
||||
}
|
||||
"transport" => set_live_filter(&mut filters.transport, value),
|
||||
"cache" => { set_live_filter(&mut filters.cache, value); if let Some(v) = filters.cache.as_mut() { *v = v.to_ascii_uppercase(); } },
|
||||
"cache" => {
|
||||
set_live_filter(&mut filters.cache, value);
|
||||
if let Some(v) = filters.cache.as_mut() {
|
||||
*v = v.to_ascii_uppercase();
|
||||
}
|
||||
}
|
||||
"path" => set_live_filter(&mut filters.path_prefix, value),
|
||||
"show" => {
|
||||
let id: u64 = value.parse().context("show expects a request id")?;
|
||||
@@ -391,7 +457,10 @@ fn handle_live_command(
|
||||
}
|
||||
_ => bail!("unknown live-log command '{command}' (type help)"),
|
||||
}
|
||||
if !matches!(command.as_str(), "help" | "?" | "filters" | "show" | "clear") {
|
||||
if !matches!(
|
||||
command.as_str(),
|
||||
"help" | "?" | "filters" | "show" | "clear"
|
||||
) {
|
||||
println!("filters: {}", live_filters_summary(filters));
|
||||
}
|
||||
Ok(true)
|
||||
@@ -406,7 +475,13 @@ fn take_sse_event(buffer: &mut Vec<u8>) -> Option<Vec<u8>> {
|
||||
let lf = find(b"\n\n").map(|index| (index, 2));
|
||||
let crlf = find(b"\r\n\r\n").map(|index| (index, 4));
|
||||
let (index, delimiter) = match (lf, crlf) {
|
||||
(Some(a), Some(b)) => if a.0 <= b.0 { a } else { b },
|
||||
(Some(a), Some(b)) => {
|
||||
if a.0 <= b.0 {
|
||||
a
|
||||
} else {
|
||||
b
|
||||
}
|
||||
}
|
||||
(Some(a), None) => a,
|
||||
(None, Some(b)) => b,
|
||||
(None, None) => return None,
|
||||
|
||||
Reference in new issue
Block a user