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