From c7f2d4da97993c2a3b6ffbacecd64c0fa2052937 Mon Sep 17 00:00:00 2001 From: Bruce Guenter Date: Thu, 19 Sep 2024 08:14:22 -0600 Subject: [PATCH] chore(new_relic sink)!: Drop event JSON parsing The `new_relic` sink has a feature when sending to the New Relic event API that it will look for a field named `message` and attempt to parse it as JSON. As this feature is not documented and duplicates functionality available through VRL, this change removes that complication. --- ...-relic-drop-event-json-parsing.breaking.md | 3 ++ src/sinks/new_relic/model.rs | 51 +------------------ src/sinks/new_relic/tests.rs | 22 -------- 3 files changed, 4 insertions(+), 72 deletions(-) create mode 100644 changelog.d/new-relic-drop-event-json-parsing.breaking.md diff --git a/changelog.d/new-relic-drop-event-json-parsing.breaking.md b/changelog.d/new-relic-drop-event-json-parsing.breaking.md new file mode 100644 index 0000000000000..cc04b0c727cc2 --- /dev/null +++ b/changelog.d/new-relic-drop-event-json-parsing.breaking.md @@ -0,0 +1,3 @@ +The `new_relic` sink, when sending logs to the `event` API, would try to parse a +field named `message` as JSON and insert the resulting data into the transmitted +event. This undocumented processing has been removed. diff --git a/src/sinks/new_relic/model.rs b/src/sinks/new_relic/model.rs index 0efc352449f2d..eae5b40c11416 100644 --- a/src/sinks/new_relic/model.rs +++ b/src/sinks/new_relic/model.rs @@ -1,15 +1,9 @@ -use std::{ - collections::{BTreeMap, HashMap}, - convert::TryFrom, - fmt::Debug, -}; +use std::{collections::BTreeMap, convert::TryFrom, fmt::Debug}; use chrono::Utc; -use ordered_float::NotNan; use serde::Serialize; use vector_lib::internal_event::{ComponentEventsDropped, INTENTIONAL, UNINTENTIONAL}; use vector_lib::{config::log_schema, event::ObjectMap}; -use vrl::event_path; use super::NewRelicSinkError; use crate::event::{Event, MetricKind, MetricValue, Value}; @@ -158,7 +152,6 @@ impl TryFrom> for EventsApiModel { fn try_from(buf_events: Vec) -> Result { let mut num_non_log_events = 0; - let mut num_nan_value = 0; let events_array: Vec = buf_events .into_iter() @@ -173,42 +166,6 @@ impl TryFrom> for EventsApiModel { event_model.insert(k, v.clone()); } - if let Some(message) = log.get(event_path!("message")) { - let message = message.to_string_lossy().replace("\\\"", "\""); - // If message contains a JSON string, parse it and insert all fields into self - if let serde_json::Result::Ok(json_map) = - serde_json::from_str::>(&message) - { - for (k, v) in json_map { - match v { - serde_json::Value::String(s) => { - event_model.insert(k.into(), Value::from(s)); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - event_model.insert( - k.into(), - Value::from(NotNan::new(f).ok().or_else(|| { - num_nan_value += 1; - None - })?), - ); - } else { - event_model.insert(k.into(), Value::from(n.as_i64())); - } - } - serde_json::Value::Bool(b) => { - event_model.insert(k.into(), Value::from(b)); - } - _ => { - // Note that arrays and nested objects are silently dropped. - } - } - } - event_model.remove("message"); - } - } - if !event_model.contains_key("eventType") { event_model.insert("eventType".into(), Value::from("VectorSink".to_owned())); } @@ -223,12 +180,6 @@ impl TryFrom> for EventsApiModel { reason: "non-log event" }); } - if num_nan_value > 0 { - emit!(ComponentEventsDropped:: { - count: num_nan_value, - reason: "NaN value not supported" - }); - } if !events_array.is_empty() { Ok(Self::new(events_array)) diff --git a/src/sinks/new_relic/tests.rs b/src/sinks/new_relic/tests.rs index 5fbd4f35fb54d..899ed07fdecbf 100644 --- a/src/sinks/new_relic/tests.rs +++ b/src/sinks/new_relic/tests.rs @@ -112,28 +112,6 @@ fn generates_event_api_model_with_message_field() { ); } -#[test] -fn generates_event_api_model_with_json_inside_message_field() { - let event = Event::Log(LogEvent::from(value!({ - "eventType": "TestEvent", - "user": "Joe", - "user_id": 123456, - "message": "{\"my_key\" : \"my_value\"}", - }))); - let model = - EventsApiModel::try_from(vec![event]).expect("Failed mapping events into API model"); - - assert_eq!( - to_value(&model).unwrap(), - json!([{ - "eventType": "TestEvent", - "user": "Joe", - "user_id": 123456, - "my_key": "my_value", - }]) - ); -} - #[test] fn generates_log_api_model_without_message_field() { let event = Event::Log(LogEvent::from(value!({"tag_key": "tag_value"})));