vector/sources/nginx_metrics/
parser.rs1use std::convert::TryFrom;
2
3use nom::{
4 bytes::complete::{tag, take_while_m_n},
5 combinator::{all_consuming, map_res},
6 error::ErrorKind,
7 sequence::{preceded, terminated},
8 Parser,
9};
10use snafu::Snafu;
11
12#[derive(Debug, Snafu, PartialEq, Eq)]
13pub enum ParseError {
14 #[snafu(display("failed to parse NginxStubStatus, kind: `{:?}`", kind))]
15 NginxStubStatusParseError { kind: ErrorKind },
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct NginxStubStatus {
20 pub active: usize,
21 pub accepts: usize,
22 pub handled: usize,
23 pub requests: usize,
24 pub reading: usize,
25 pub writing: usize,
26 pub waiting: usize,
27}
28
29fn get_usize(input: &str) -> nom::IResult<&str, usize, nom::error::Error<&str>> {
30 map_res(
31 take_while_m_n(1, 20, |c: char| c.is_ascii_digit()),
32 |s: &str| s.parse::<usize>(),
33 )
34 .parse(input)
35}
36
37impl<'a> TryFrom<&'a str> for NginxStubStatus {
38 type Error = ParseError;
39
40 fn try_from(input: &'a str) -> Result<Self, Self::Error> {
43 match all_consuming((
45 preceded(tag("Active connections: "), get_usize),
46 preceded(tag(" \nserver accepts handled requests\n "), get_usize),
47 preceded(tag(" "), get_usize),
48 preceded(tag(" "), get_usize),
49 preceded(tag(" \nReading: "), get_usize),
50 preceded(tag(" Writing: "), get_usize),
51 terminated(preceded(tag(" Waiting: "), get_usize), tag(" \n")),
52 ))
53 .parse(input)
54 {
55 Ok((_, (active, accepts, handled, requests, reading, writing, waiting))) => {
56 Ok(NginxStubStatus {
57 active,
58 accepts,
59 handled,
60 requests,
61 reading,
62 writing,
63 waiting,
64 })
65 }
66 Err(error) => match error {
67 nom::Err::Error(error) => {
68 Err(ParseError::NginxStubStatusParseError { kind: error.code })
69 }
70 nom::Err::Incomplete(_) | nom::Err::Failure(_) => unreachable!(),
71 },
72 }
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn nginx_stub_status_try_from() {
82 let data = "Active connections: 291 \n\
83 server accepts handled requests\n \
84 16630948 16630948 31070465 \n\
85 Reading: 6 Writing: 179 Waiting: 106 \n";
86
87 assert_eq!(
88 NginxStubStatus::try_from(data).expect("valid data"),
89 NginxStubStatus {
90 active: 291,
91 accepts: 16630948,
92 handled: 16630948,
93 requests: 31070465,
94 reading: 6,
95 writing: 179,
96 waiting: 106
97 }
98 );
99 }
100}