Verified Commit 0bb1f331 authored by Martin Petráček's avatar Martin Petráček
Browse files

experiment: export RemoteHalf statistics

parent d1e47f1c
Pipeline #5297 passed with stages
in 14 minutes and 19 seconds
......@@ -63,14 +63,14 @@ pub struct Id(pub String);
///
/// This counts discrete items. It is a newtype to distinguish it from just plain int.
#[derive(Add, AddAssign, Clone, Copy, Debug, Default, Deserialize, Eq, From, Hash, Into, Ord,
PartialEq, PartialOrd, Sub, SubAssign)]
PartialEq, PartialOrd, Sub, SubAssign, Serialize)]
pub struct Count(pub u64);
/// Amount of data.
///
/// This counts amount of data in bytes. It is a newtype to distinguish it from just plain int.
#[derive(Add, AddAssign, Clone, Copy, Debug, Default, Deserialize, Eq, From, Hash, Into, Ord,
PartialEq, PartialOrd, Sub, SubAssign)]
PartialEq, PartialOrd, Sub, SubAssign, Serialize)]
pub struct Bytes(pub u64);
/// The direction the flow was initiated.
......
......@@ -30,10 +30,10 @@ use std::time::{Duration, SystemTime};
use slog::Logger;
use flow::data::{Endpoint, FlowStatus, Globals, Id, Stats, Status};
use flow::data::{Endpoint, FlowStatus, Globals, Id, Stats, Status, HalfAmount};
use flow::snapshot::{Snapshot, Split as SplitSnapshot};
use keeper::aggregable::{Container, InTimeInterval, PreFilterResult, ResultStat, ValueSrc};
use keeper::column::{EndpointIdent, EndpointValue, FlowIdent, FlowValue};
use keeper::column::{EndpointIdent, EndpointValue, HalfAmountIdent, HalfAmountValue, FlowIdent, FlowValue};
use keeper::query::Query;
use tunable::{SLICE_INACTIVE_LIMIT, SLICE_LENGTH_SECONDS};
......@@ -91,6 +91,14 @@ fn endpoint_value(e: &Endpoint, ident: &EndpointIdent) -> EndpointValue {
}
}
fn halfamount_value(e: &HalfAmount, ident: &HalfAmountIdent) -> HalfAmountValue {
match *ident {
HalfAmountIdent::Packets => HalfAmountValue::Packets(e.packets),
HalfAmountIdent::Payload => HalfAmountValue::Payload(e.payload),
HalfAmountIdent::Total => HalfAmountValue::Total(e.total)
}
}
// Note that we implement the trait on the reference, because the iterator from `Time` returns
// references.
impl<'a> ValueSrc for &'a Flow {
......@@ -105,6 +113,7 @@ impl<'a> ValueSrc for &'a Flow {
},
FlowIdent::Local(ref id) => FlowValue::Local(endpoint_value(&self.globals.local, id)),
FlowIdent::Remote(ref id) => FlowValue::Remote(endpoint_value(&self.globals.remote, id)),
FlowIdent::RemoteHalfAmount(ref id) => FlowValue::RemoteHalfAmount(halfamount_value(&self.stats.out_half, id)),
}
}
}
......
......@@ -32,7 +32,7 @@ use std::net::IpAddr;
use eui48::MacAddress;
use flow::data::{Direction, IpProto, Name};
use flow::data::{Direction, IpProto, Name, Count, Bytes};
/// This macro generates the type tripple.
///
......@@ -357,6 +357,64 @@ column! {
name Port u16;
}
column! {
/// Identifier of an address inside an endpoint.
///
/// This is usually used to specify aggregation by a value in queries.
///
/// # JSON Representation
///
/// Things like `"port"` or `"name-any"`.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub enum HalfAmountIdent;
/// A value of an address (of some kind) inside an endpoint.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum HalfAmountValue;
/// A value of a column inside an endpoint.
///
/// This selects a column inside an endpoint and carries a set of values with each.
/// This can be used to filter the flows according to some criteria. The values in the sets are
/// considered as alternatives ‒ a flow that matches one of the values is matched.
///
/// This is similar to [`EndpointIdent`](enum.EndpointIdent.html), but with the bunded data.
///
/// # JSON Representation
///
/// As an object, tag is the choosen variant and each set is an array.
///
/// * `{"mac": ["00:11:22:33:44:55", null]}` (some endpoint don't have a known MAC address,
/// these are selected by the `null`.
/// * `{"name-set": [["a", "b"], ["a", "b", "c"]]}`
/// * `{"port": [22, 25]}`
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub enum HalfAmountSet;
simple
/// A MAC address.
///
/// Note that we don't necessarily have a MAC address for each endpoint. Unlike other variants,
/// it is possible to consider `None` as a first-class member of the domain and query for it.
name Packets Count;
simple
/// A MAC address.
///
/// Note that we don't necessarily have a MAC address for each endpoint. Unlike other variants,
/// it is possible to consider `None` as a first-class member of the domain and query for it.
name Payload Bytes;
simple
/// A MAC address.
///
/// Note that we don't necessarily have a MAC address for each endpoint. Unlike other variants,
/// it is possible to consider `None` as a first-class member of the domain and query for it.
name Total Bytes;
}
column! {
/// A selector for column of a flow.
///
......@@ -484,6 +542,26 @@ column! {
contains (&FlowSet::Local(ref container), &FlowValue::Local(ref value)) => {
container.contains(value)
};
full
/// An option inside the remote endpoint.
///
/// The sub-option is specified inside.
name RemoteHalfAmount id (HalfAmountIdent) val (HalfAmountValue) set (HalfAmountSet),
list |result: &mut Vec<FlowIdent>| {
result.extend(HalfAmountIdent::list().into_iter().map(FlowIdent::RemoteHalfAmount))
},
empty FlowValue::RemoteHalfAmount(ref remote) => remote.is_empty(),
upgrade FlowValue::RemoteHalfAmount(remote) => FlowSet::RemoteHalfAmount(remote.into()),
append (&mut FlowSet::RemoteHalfAmount(ref mut into), FlowSet::RemoteHalfAmount(ref mut src)) => {
let mut tmp = HalfAmountSet::Packets(BTreeSet::new());
mem::swap(src, &mut tmp);
into.append(tmp)
},
ident FlowSet::RemoteHalfAmount(ref remote) => FlowIdent::RemoteHalfAmount(remote.ident()),
contains (&FlowSet::RemoteHalfAmount(ref container), &FlowValue::RemoteHalfAmount(ref value)) => {
container.contains(value)
};
}
#[cfg(test)]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment