agentsight_capture/view/
session_process_match.rs1use crate::model::SessionRow;
5use crate::sources::proc::ProcessKey;
6use serde_json::Value;
7use std::collections::{BTreeSet, HashMap};
8use std::path::{Path, PathBuf};
9
10pub use agent_session::{LiveProcessCandidate, SessionProcessMatch, SessionProcessMatches};
11
12#[derive(Default)]
13pub struct SessionProcessMatcher {
14 inner: agent_session::SessionProcessMatcher,
15}
16
17impl SessionProcessMatcher {
18 pub fn match_sessions(
19 &mut self,
20 sessions: &[SessionRow],
21 processes: &[LiveProcessCandidate],
22 fd_paths_by_process: &HashMap<ProcessKey, BTreeSet<PathBuf>>,
23 ebpf_path_by_process: &HashMap<ProcessKey, PathBuf>,
24 now_ms: u64,
25 ) -> SessionProcessMatches {
26 let inputs = sessions
27 .iter()
28 .filter_map(session_input)
29 .collect::<Vec<_>>();
30 self.inner.match_sessions(
31 &inputs,
32 processes,
33 fd_paths_by_process,
34 ebpf_path_by_process,
35 now_ms,
36 )
37 }
38}
39
40pub fn session_path_from_raw_path(path: &Path) -> Option<PathBuf> {
41 agent_session::session_log_path_from_str(&path.to_string_lossy())
42}
43
44fn session_input(session: &SessionRow) -> Option<agent_session::SessionProcessInput> {
45 Some(agent_session::SessionProcessInput {
46 id: session.id.clone(),
47 agent: session.agent_type.clone(),
48 path: session_path(session)?.to_path_buf(),
49 start_timestamp_ms: Some(session.start_timestamp_ms),
50 end_timestamp_ms: session.end_timestamp_ms,
51 cwd: session
52 .attributes
53 .get("cwd")
54 .and_then(Value::as_str)
55 .filter(|value| !value.is_empty())
56 .map(ToString::to_string),
57 })
58}
59
60fn session_path(session: &SessionRow) -> Option<&Path> {
61 session
62 .attributes
63 .get("path")
64 .and_then(Value::as_str)
65 .filter(|value| !value.is_empty())
66 .map(Path::new)
67}