use std::{convert::TryFrom, time::Duration};
use regex::bytes::Regex;
use serde_with::serde_as;
use snafu::{ResultExt, Snafu};
use vector_lib::configurable::configurable_component;
use crate::line_agg;
#[serde_as]
#[configurable_component]
#[derive(Clone, Debug, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct MultilineConfig {
#[configurable(metadata(docs::examples = "^[\\s]+"))]
#[configurable(metadata(docs::examples = "\\\\$"))]
#[configurable(metadata(docs::examples = "^(INFO|ERROR) "))]
#[configurable(metadata(docs::examples = ";$"))]
pub start_pattern: String,
#[configurable(metadata(docs::examples = "^[\\s]+"))]
#[configurable(metadata(docs::examples = "\\\\$"))]
#[configurable(metadata(docs::examples = "^(INFO|ERROR) "))]
#[configurable(metadata(docs::examples = ";$"))]
pub condition_pattern: String,
#[configurable(derived)]
pub mode: line_agg::Mode,
#[serde_as(as = "serde_with::DurationMilliSeconds<u64>")]
#[configurable(metadata(docs::examples = 1000))]
#[configurable(metadata(docs::examples = 600000))]
#[configurable(metadata(docs::human_name = "Timeout"))]
pub timeout_ms: Duration,
}
impl TryFrom<&MultilineConfig> for line_agg::Config {
type Error = Error;
fn try_from(config: &MultilineConfig) -> Result<Self, Self::Error> {
let MultilineConfig {
start_pattern,
condition_pattern,
mode,
timeout_ms,
} = config;
let start_pattern = Regex::new(start_pattern)
.with_context(|_| InvalidMultilineStartPatternSnafu { start_pattern })?;
let condition_pattern = Regex::new(condition_pattern)
.with_context(|_| InvalidMultilineConditionPatternSnafu { condition_pattern })?;
let timeout = *timeout_ms;
Ok(Self {
start_pattern,
condition_pattern,
mode: *mode,
timeout,
})
}
}
#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(display(
"unable to parse multiline start pattern from {:?}: {}",
start_pattern,
source
))]
InvalidMultilineStartPattern {
start_pattern: String,
source: regex::Error,
},
#[snafu(display(
"unable to parse multiline condition pattern from {:?}: {}",
condition_pattern,
source
))]
InvalidMultilineConditionPattern {
condition_pattern: String,
source: regex::Error,
},
}