vector_common/internal_event/
mod.rs

1mod bytes_received;
2mod bytes_sent;
3pub mod cached_event;
4pub mod component_events_dropped;
5pub mod component_events_timed_out;
6mod events_received;
7mod events_sent;
8mod optional_tag;
9mod prelude;
10pub mod service;
11
12use std::ops::{Add, AddAssign};
13
14pub use bytes_received::{BytesReceived, BytesReceivedHandle};
15pub use bytes_sent::BytesSent;
16#[allow(clippy::module_name_repetitions)]
17pub use cached_event::{RegisterTaggedInternalEvent, RegisteredEventCache};
18pub use component_events_dropped::{ComponentEventsDropped, INTENTIONAL, UNINTENTIONAL};
19pub use component_events_timed_out::ComponentEventsTimedOut;
20pub use events_received::{EventsReceived, EventsReceivedHandle};
21pub use events_sent::{DEFAULT_OUTPUT, EventsSent, TaggedEventsSent};
22pub use metrics::SharedString;
23pub use optional_tag::OptionalTag;
24pub use prelude::{error_stage, error_type};
25pub use service::{CallError, PollReadyError};
26
27use crate::json_size::JsonSize;
28
29pub trait NamedInternalEvent {
30    fn name(&self) -> &'static str;
31}
32
33pub trait InternalEvent: NamedInternalEvent + Sized {
34    fn emit(self);
35}
36
37#[allow(clippy::module_name_repetitions)]
38pub trait RegisterInternalEvent: NamedInternalEvent + Sized {
39    type Handle: InternalEventHandle;
40
41    fn register(self) -> Self::Handle;
42}
43
44#[allow(clippy::module_name_repetitions)]
45pub trait InternalEventHandle: Sized {
46    type Data: Sized;
47    fn emit(&self, data: Self::Data);
48}
49
50#[cfg(any(test, feature = "test"))]
51pub fn emit(event: impl InternalEvent) {
52    super::event_test_util::record_internal_event(event.name());
53    event.emit();
54}
55
56#[cfg(not(any(test, feature = "test")))]
57pub fn emit(event: impl InternalEvent) {
58    event.emit();
59}
60
61#[cfg(any(test, feature = "test"))]
62pub fn register<E: RegisterInternalEvent>(event: E) -> E::Handle {
63    super::event_test_util::record_internal_event(event.name());
64    event.register()
65}
66
67#[cfg(not(any(test, feature = "test")))]
68pub fn register<E: RegisterInternalEvent>(event: E) -> E::Handle {
69    event.register()
70}
71
72pub type Registered<T> = <T as RegisterInternalEvent>::Handle;
73
74// Wrapper types used to hold data emitted by registered events
75
76#[derive(Clone, Copy)]
77pub struct ByteSize(pub usize);
78
79#[derive(Clone, Copy)]
80pub struct Count(pub usize);
81
82/// Holds the tuple `(count_of_events, estimated_json_size_of_events)`.
83#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
84pub struct CountByteSize(pub usize, pub JsonSize);
85
86impl AddAssign for CountByteSize {
87    fn add_assign(&mut self, rhs: Self) {
88        self.0 += rhs.0;
89        self.1 += rhs.1;
90    }
91}
92
93impl Add<CountByteSize> for CountByteSize {
94    type Output = CountByteSize;
95
96    fn add(self, rhs: CountByteSize) -> Self::Output {
97        CountByteSize(self.0 + rhs.0, self.1 + rhs.1)
98    }
99}
100
101// Wrapper types used to hold parameters for registering events
102
103pub struct Output(pub Option<SharedString>);
104
105pub struct Protocol(pub SharedString);
106
107impl Protocol {
108    pub const HTTP: Protocol = Protocol(SharedString::const_str("http"));
109    pub const HTTPS: Protocol = Protocol(SharedString::const_str("https"));
110    pub const NONE: Protocol = Protocol(SharedString::const_str("none"));
111    pub const TCP: Protocol = Protocol(SharedString::const_str("tcp"));
112    pub const UDP: Protocol = Protocol(SharedString::const_str("udp"));
113    pub const UNIX: Protocol = Protocol(SharedString::const_str("unix"));
114    pub const INTERNAL: Protocol = Protocol(SharedString::const_str("internal"));
115    pub const STATIC: Protocol = Protocol(SharedString::const_str("static"));
116}
117
118impl From<&'static str> for Protocol {
119    fn from(s: &'static str) -> Self {
120        Self(SharedString::const_str(s))
121    }
122}
123
124impl From<Protocol> for SharedString {
125    fn from(value: Protocol) -> Self {
126        value.0
127    }
128}
129
130/// Macro to take care of some of the repetitive boilerplate in implementing a registered event. See
131/// the other events in this module for examples of how to use this.
132///
133/// ## Usage
134///
135/// ```ignore
136/// registered_event!(
137///     Event {
138///         event_field: &'static str,
139///     } => {
140///         handle_field: Counter = counter!("name", "tag" => self.event_field),
141///     }
142///     fn emit(&self, data: DataType) {
143///         self.handle_field.increment(data.0);
144///     }
145/// );
146///
147/// let handle = register!(Event { event_field: "message" });
148///
149/// handle.emit(DataType(123));
150/// ```
151///
152/// In this example, the first set of fields describes the data required to register the event. This
153/// is what would be used by the `register!` macro. For example, `register!(Event { event_field:
154/// "something" })`. The second set of fields describes the data required to store the registered
155/// handle, namely the `Counter`s and `Gauge`s that record the handle from `metrics` as well as any
156/// associated data for emitting traces or debug messages, followed by an initialization assignment
157/// value. The `emit` function is the code required to update the metrics and generate any log
158/// messages.
159#[macro_export]
160macro_rules! registered_event {
161    // A registered event struct with no fields (zero-sized type).
162    ($event:ident => $($tail:tt)*) => {
163        #[derive(Debug, Clone, Eq, Hash, $crate::NamedInternalEvent, Ord, PartialEq, PartialOrd)]
164        pub struct $event;
165
166        $crate::registered_event!(=> $event $($tail)*);
167    };
168
169    // A normal registered event struct.
170    ($event:ident { $( $field:ident: $type:ty, )* } => $($tail:tt)*) => {
171        #[derive(Debug, Clone, Eq, Hash, $crate::NamedInternalEvent, Ord, PartialEq, PartialOrd)]
172        pub struct $event {
173            $( pub $field: $type, )*
174        }
175
176        $crate::registered_event!(=> $event $($tail)*);
177    };
178
179    // Sub-matcher to implement the common bits in the above two cases.
180    (
181        => $event:ident {
182            $( $field:ident: $type:ty = $value:expr, )*
183        }
184
185        fn emit(&$slf:ident, $data_name:ident: $data:ident)
186            $emit_body:block
187
188        $(fn register($fixed_name:ident: $fixed_tags:ty, $tags_name:ident: $tags:ty)
189            $register_body:block)?
190    ) => {
191        paste::paste!{
192            #[derive(Clone)]
193            pub struct [<$event Handle>] {
194                $( $field: $type, )*
195            }
196
197            impl $crate::internal_event::RegisterInternalEvent for $event {
198                type Handle = [<$event Handle>];
199
200                fn register($slf) -> Self::Handle {
201                    Self::Handle {
202                        $( $field: $value, )*
203                    }
204                }
205            }
206
207            impl $crate::internal_event::InternalEventHandle for [<$event Handle>] {
208                type Data = $data;
209
210                fn emit(&$slf, $data_name: $data)
211                    $emit_body
212            }
213
214            $(impl $crate::internal_event::cached_event::RegisterTaggedInternalEvent for $event {
215                type Tags = $tags;
216                type Fixed = $fixed_tags;
217
218                fn register(
219                    $fixed_name: $fixed_tags,
220                    $tags_name: $tags,
221                ) -> <Self as $crate::internal_event::RegisterInternalEvent>::Handle {
222                    $register_body
223                }
224            })?
225
226        }
227    };
228}