use super::events::{
AuthEvent, HttpRequestEvent, HttpRequestStartEvent, NetworkBytesEvent, QueryEvent, RpcEvent,
SessionEvent, StatementEvent, TransactionEvent,
};
pub trait ExecutionObserver: Send + Sync + 'static {
fn on_statement_complete(&self, _event: &StatementEvent) {}
fn on_query_complete(&self, _event: &QueryEvent) {}
fn on_transaction_complete(&self, _event: &TransactionEvent) {}
fn on_rpc_complete(&self, _event: &RpcEvent) {}
fn on_auth_event(&self, _event: &AuthEvent) {}
fn on_session_event(&self, _event: &SessionEvent) {}
fn on_network_bytes(&self, _event: &NetworkBytesEvent) {}
fn on_http_request_started(&self, _event: &HttpRequestStartEvent) {}
fn on_http_request_complete(&self, _event: &HttpRequestEvent) {}
fn is_noop(&self) -> bool {
false
}
fn needs_statement_text(&self) -> bool {
false
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct NoopObserver;
impl ExecutionObserver for NoopObserver {
fn is_noop(&self) -> bool {
true
}
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use super::super::events::{
AuthAction, AuthEvent, AuthEventCtx, AuthEventSafe, AuthScope, HttpMethod,
HttpRequestEvent, HttpRequestEventCtx, HttpRequestEventSafe, HttpRequestStartEvent,
HttpRequestStartEventSafe, HttpVersion, NetworkBytesEvent, NetworkBytesEventCtx,
NetworkBytesEventSafe, NetworkDirection, Outcome, QueryCounters, QueryEvent, QueryEventCtx,
QueryEventSafe, RpcEvent, RpcEventCtx, RpcEventSafe, SessionAction, SessionEvent,
SessionEventCtx, SessionEventSafe, SessionProtocol, StatementEvent, StatementEventCtx,
StatementEventSafe, StatementType, TransactionEvent, TransactionEventCtx,
TransactionEventSafe, TransactionMetricsSnapshot,
};
use super::*;
#[test]
fn noop_observer_accepts_every_event_kind() {
let obs = NoopObserver;
obs.on_statement_complete(&StatementEvent {
safe: StatementEventSafe {
kind: StatementType::Select,
outcome: Outcome::Success,
duration: Duration::from_millis(1),
read_only: true,
result_rows: 0,
error_class: None,
},
ctx: StatementEventCtx::default(),
});
obs.on_query_complete(&QueryEvent {
safe: QueryEventSafe {
outcome: Outcome::Error,
duration: Duration::from_millis(2),
counters: QueryCounters {
total: 1,
ok: 0,
err: 1,
},
error_class: None,
},
ctx: QueryEventCtx::default(),
});
obs.on_transaction_complete(&TransactionEvent {
safe: TransactionEventSafe {
outcome: Outcome::Success,
write: true,
duration: Duration::from_millis(3),
metrics: TransactionMetricsSnapshot::default(),
error_class: None,
},
ctx: TransactionEventCtx::default(),
});
obs.on_rpc_complete(&RpcEvent {
safe: RpcEventSafe {
method: crate::rpc::Method::Ping,
outcome: Outcome::Success,
duration: Duration::from_millis(4),
error_class: None,
},
ctx: RpcEventCtx::default(),
});
obs.on_auth_event(&AuthEvent {
safe: AuthEventSafe {
action: AuthAction::Signin,
scope: AuthScope::Root,
outcome: Outcome::Success,
error_class: None,
},
ctx: AuthEventCtx::default(),
});
obs.on_session_event(&SessionEvent {
safe: SessionEventSafe {
action: SessionAction::Connect,
protocol: SessionProtocol::Http,
duration: None,
},
ctx: SessionEventCtx::default(),
});
obs.on_network_bytes(&NetworkBytesEvent {
safe: NetworkBytesEventSafe {
direction: NetworkDirection::Sent,
protocol: SessionProtocol::Http,
bytes: 64,
},
ctx: NetworkBytesEventCtx::default(),
});
obs.on_http_request_started(&HttpRequestStartEvent {
safe: HttpRequestStartEventSafe {
method: HttpMethod::Get,
route: Some("/sql"),
version: HttpVersion::Http11,
},
ctx: HttpRequestEventCtx::default(),
});
obs.on_http_request_complete(&HttpRequestEvent {
safe: HttpRequestEventSafe {
method: HttpMethod::Get,
route: Some("/sql"),
status_code: Some(200),
version: HttpVersion::Http11,
outcome: Outcome::Success,
duration: Duration::from_millis(5),
request_size: Some(128),
response_size: Some(256),
error_class: None,
},
ctx: HttpRequestEventCtx::default(),
});
assert!(!obs.needs_statement_text());
assert!(obs.is_noop());
}
}