mirror of
https://github.com/openai/codex.git
synced 2026-04-27 18:01:04 +03:00
feat: add --search to just log (#11995)
Summary - extend the log client to accept an optional `--search` substring filter when querying codex-state logs - propagate the filter through `LogQuery` and apply it in `push_log_filters` via `INSTR(message, ...)` - add an integration test that exercises the new search filtering behavior Testing - Not run (not requested)
This commit is contained in:
@@ -46,6 +46,10 @@ struct Args {
|
||||
#[arg(long = "thread-id")]
|
||||
thread_id: Vec<String>,
|
||||
|
||||
/// Substring match against the log message.
|
||||
#[arg(long)]
|
||||
search: Option<String>,
|
||||
|
||||
/// Include logs that do not have a thread id.
|
||||
#[arg(long)]
|
||||
threadless: bool,
|
||||
@@ -67,6 +71,7 @@ struct LogFilter {
|
||||
module_like: Vec<String>,
|
||||
file_like: Vec<String>,
|
||||
thread_ids: Vec<String>,
|
||||
search: Option<String>,
|
||||
include_threadless: bool,
|
||||
}
|
||||
|
||||
@@ -154,6 +159,7 @@ fn build_filter(args: &Args) -> anyhow::Result<LogFilter> {
|
||||
module_like,
|
||||
file_like,
|
||||
thread_ids,
|
||||
search: args.search.clone(),
|
||||
include_threadless: args.threadless,
|
||||
})
|
||||
}
|
||||
@@ -233,6 +239,7 @@ fn to_log_query(
|
||||
module_like: filter.module_like.clone(),
|
||||
file_like: filter.file_like.clone(),
|
||||
thread_ids: filter.thread_ids.clone(),
|
||||
search: filter.search.clone(),
|
||||
include_threadless: filter.include_threadless,
|
||||
after_id,
|
||||
limit,
|
||||
|
||||
@@ -37,6 +37,7 @@ pub struct LogQuery {
|
||||
pub module_like: Vec<String>,
|
||||
pub file_like: Vec<String>,
|
||||
pub thread_ids: Vec<String>,
|
||||
pub search: Option<String>,
|
||||
pub include_threadless: bool,
|
||||
pub after_id: Option<i64>,
|
||||
pub limit: Option<usize>,
|
||||
|
||||
@@ -711,6 +711,11 @@ fn push_log_filters<'a>(builder: &mut QueryBuilder<'a, Sqlite>, query: &'a LogQu
|
||||
if let Some(after_id) = query.after_id {
|
||||
builder.push(" AND id > ").push_bind(after_id);
|
||||
}
|
||||
if let Some(search) = query.search.as_ref() {
|
||||
builder.push(" AND INSTR(message, ");
|
||||
builder.push_bind(search.as_str());
|
||||
builder.push(") > 0");
|
||||
}
|
||||
}
|
||||
|
||||
fn push_like_filters<'a>(
|
||||
@@ -906,6 +911,8 @@ mod tests {
|
||||
use super::StateRuntime;
|
||||
use super::ThreadMetadata;
|
||||
use super::state_db_filename;
|
||||
use crate::LogEntry;
|
||||
use crate::LogQuery;
|
||||
use crate::STATE_DB_FILENAME;
|
||||
use crate::STATE_DB_VERSION;
|
||||
use crate::model::Phase2JobClaimOutcome;
|
||||
@@ -2495,6 +2502,57 @@ VALUES (?, ?, ?, ?, ?)
|
||||
let _ = tokio::fs::remove_dir_all(codex_home).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn query_logs_with_search_matches_substring() {
|
||||
let codex_home = unique_temp_dir();
|
||||
let runtime = StateRuntime::init(codex_home.clone(), "test-provider".to_string(), None)
|
||||
.await
|
||||
.expect("initialize runtime");
|
||||
|
||||
runtime
|
||||
.insert_logs(&[
|
||||
LogEntry {
|
||||
ts: 1_700_000_001,
|
||||
ts_nanos: 0,
|
||||
level: "INFO".to_string(),
|
||||
target: "cli".to_string(),
|
||||
message: Some("alpha".to_string()),
|
||||
thread_id: Some("thread-1".to_string()),
|
||||
process_uuid: None,
|
||||
file: Some("main.rs".to_string()),
|
||||
line: Some(42),
|
||||
module_path: None,
|
||||
},
|
||||
LogEntry {
|
||||
ts: 1_700_000_002,
|
||||
ts_nanos: 0,
|
||||
level: "INFO".to_string(),
|
||||
target: "cli".to_string(),
|
||||
message: Some("alphabet".to_string()),
|
||||
thread_id: Some("thread-1".to_string()),
|
||||
process_uuid: None,
|
||||
file: Some("main.rs".to_string()),
|
||||
line: Some(43),
|
||||
module_path: None,
|
||||
},
|
||||
])
|
||||
.await
|
||||
.expect("insert test logs");
|
||||
|
||||
let rows = runtime
|
||||
.query_logs(&LogQuery {
|
||||
search: Some("alphab".to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.expect("query matching logs");
|
||||
|
||||
assert_eq!(rows.len(), 1);
|
||||
assert_eq!(rows[0].message.as_deref(), Some("alphabet"));
|
||||
|
||||
let _ = tokio::fs::remove_dir_all(codex_home).await;
|
||||
}
|
||||
|
||||
fn test_thread_metadata(
|
||||
codex_home: &Path,
|
||||
thread_id: ThreadId,
|
||||
|
||||
Reference in New Issue
Block a user