retis-org / retis

Tracing packets in the Linux networking stack & friends
https://retis.readthedocs.io/en/stable/
100 stars 14 forks source link

[RFC] Unified api #108

Closed atenart closed 1 year ago

atenart commented 1 year ago

Following our discussion on how to unify and consolidate the API, here are 3 patches based on top of #102 to start the discussion. The design for this initial work is as follow:

atenart commented 1 year ago

In general, having a unified API seems an interesting idea that we should explore. However, right now retis::Retis is "just" encapsulating a EventFactory (which actually has to be constructed externally), and a ProbeManager, which in fact, is only used on certain cases (only on retis collect). Do you think we'll add more things to it?

I'd like to move the kernel inspector here too, and at some point we'll probably add the ability to retrieve information about kernel modules. Also if we allow access to the tracking info this will land in there.

I agree the current scope is not that big, but I'm thinking it has two advantages:

  1. It allows easy future additions w/o reworking all the APIs + modules.
  2. It enables access to the whole API from all modules functions, which IMHO is quite nice. (It does not enforce what one can do though, but that is true regardless of this).

If the goal is to unify, why not put modules inside as well?

See below,

We keep 3 high level objects: core::Retis, cli::* and module::Modules. It makes sense as those represent the 3 main elements we are dealing with and their separation helps in multiple ways:

  • They can't be grouped in Rust: we need to iterate over modules or over cli arguments while using the main API object (Retis).

  • Depending on the consumer, only a combination of those 3 objects is required.

To sum up, there are two main points:

  1. At the logical level, those are three distinct and top level elements of the tool: the API (what the tool can do), the cli (what the user requested) and the modules (what actual implementation is being used) and those are bundled in a top level obj, the current command (collect, post-process, etc) aka what we actual do atm.
  2. There is an implementation limitation. We can't loop over modules and give them a mutable reference to the API if both the API and the modules are in the same object. The following can't work:
for module in retis.modules.collectors() {
    module.init(&mut retis)?;
}

Thoughts?