vector/internal_events/
parser.rs1#![allow(dead_code)] use std::borrow::Cow;
4
5use metrics::counter;
6use vector_lib::NamedInternalEvent;
7use vector_lib::internal_event::{
8 ComponentEventsDropped, InternalEvent, UNINTENTIONAL, error_stage, error_type,
9};
10
11fn truncate_string_at(s: &str, maxlen: usize) -> Cow<'_, str> {
12 let ellipsis: &str = "[...]";
13 if s.len() >= maxlen {
14 let mut len = maxlen - ellipsis.len();
15 while !s.is_char_boundary(len) {
16 len -= 1;
17 }
18 format!("{}{}", &s[..len], ellipsis).into()
19 } else {
20 s.into()
21 }
22}
23
24#[derive(Debug, NamedInternalEvent)]
25pub struct ParserMatchError<'a> {
26 pub value: &'a [u8],
27}
28
29impl InternalEvent for ParserMatchError<'_> {
30 fn emit(self) {
31 error!(
32 message = "Pattern failed to match.",
33 error_code = "no_match_found",
34 error_type = error_type::CONDITION_FAILED,
35 stage = error_stage::PROCESSING,
36 field = &truncate_string_at(&String::from_utf8_lossy(self.value), 60)[..]
37 );
38 counter!(
39 "component_errors_total",
40 "error_code" => "no_match_found",
41 "error_type" => error_type::CONDITION_FAILED,
42 "stage" => error_stage::PROCESSING,
43 )
44 .increment(1);
45 }
46}
47
48#[allow(dead_code)]
49pub const DROP_EVENT: bool = true;
50#[allow(dead_code)]
51pub const RETAIN_EVENT: bool = false;
52
53#[derive(Debug, NamedInternalEvent)]
54pub struct ParserMissingFieldError<'a, const DROP_EVENT: bool> {
55 pub field: &'a str,
56}
57
58impl<const DROP_EVENT: bool> InternalEvent for ParserMissingFieldError<'_, DROP_EVENT> {
59 fn emit(self) {
60 let reason = "Field does not exist.";
61 error!(
62 message = reason,
63 field = %self.field,
64 error_code = "field_not_found",
65 error_type = error_type::CONDITION_FAILED,
66 stage = error_stage::PROCESSING
67 );
68 counter!(
69 "component_errors_total",
70 "error_code" => "field_not_found",
71 "error_type" => error_type::CONDITION_FAILED,
72 "stage" => error_stage::PROCESSING,
73 "field" => self.field.to_string(),
74 )
75 .increment(1);
76
77 if DROP_EVENT {
78 emit!(ComponentEventsDropped::<UNINTENTIONAL> { count: 1, reason });
79 }
80 }
81}
82
83#[derive(Debug, NamedInternalEvent)]
84pub struct ParserConversionError<'a> {
85 pub name: &'a str,
86 pub error: crate::types::Error,
87}
88
89impl InternalEvent for ParserConversionError<'_> {
90 fn emit(self) {
91 error!(
92 message = "Could not convert types.",
93 name = %self.name,
94 error = ?self.error,
95 error_code = "type_conversion",
96 error_type = error_type::CONVERSION_FAILED,
97 stage = error_stage::PROCESSING
98 );
99 counter!(
100 "component_errors_total",
101 "error_code" => "type_conversion",
102 "error_type" => error_type::CONVERSION_FAILED,
103 "stage" => error_stage::PROCESSING,
104 "name" => self.name.to_string(),
105 )
106 .increment(1);
107 }
108}
109
110#[cfg(test)]
111mod test {
112 #[test]
113 fn truncate_utf8() {
114 let message = "Hello 😁 this is test.";
115 assert_eq!("Hello [...]", super::truncate_string_at(message, 13));
116 }
117}