Skip to main content

http_collator/
traits.rs

1//! Traits for abstracting data event sources
2//!
3//! These traits allow the collator to work with any data source that provides
4//! the necessary information about network traffic direction and payload.
5
6use bytes::Bytes;
7
8/// Direction of data flow for a network event.
9///
10/// `Read` and `Write` correspond to the socket operation (recv/send) observed
11/// by the tracing layer. Whether Read or Write carries requests vs. responses
12/// depends on the vantage point: on a client, Write = outgoing requests and
13/// Read = incoming responses; on a server the mapping is reversed. The
14/// collator classifies messages by inspecting content (pseudo-headers), not
15/// by assuming a fixed direction-to-role mapping.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum Direction {
18    /// Data received via a socket read (recv) operation
19    Read,
20    /// Data sent via a socket write (send) operation
21    Write,
22    /// Non-data events (ignored by collator)
23    Other,
24}
25
26/// Trait for data events that can be collated into HTTP exchanges.
27///
28/// Implement this trait for your data source (e.g., eBPF events, pcap packets)
29/// to enable HTTP collation.
30pub trait DataEvent {
31    /// The raw payload bytes of this event
32    fn payload(&self) -> &[u8];
33
34    /// Timestamp in nanoseconds (monotonic, for latency calculation)
35    fn timestamp_ns(&self) -> u64;
36
37    /// Direction of the data flow
38    fn direction(&self) -> Direction;
39
40    /// Connection identifier (0 if unavailable, falls back to process_id)
41    fn connection_id(&self) -> u64;
42
43    /// Process ID for connection tracking
44    fn process_id(&self) -> u32;
45
46    /// Remote port (0 if unknown)
47    fn remote_port(&self) -> u16;
48
49    /// Consume self and return the payload as `Bytes`.
50    ///
51    /// The default implementation copies via `payload().to_vec()`. Implementors
52    /// that already own a `Bytes` (or `Vec<u8>`) should override this to avoid
53    /// the copy.
54    fn into_payload(self) -> Bytes
55    where
56        Self: Sized,
57    {
58        Bytes::from(self.payload().to_vec())
59    }
60}