Commit Diff


commit - 9b2d8449e0a874205a43b2752ed4f2db78fa1990
commit + 494084c5ac76057d8bc76837244b6e350ca247ca
blob - 856a68ca0df76057a544c91ef5a0b6a2d93da61f
blob + c58c1bc412b83b3fa7cabbcc6b500f807b2e5ea1
--- src/metrics.rs
+++ src/metrics.rs
@@ -1,10 +1,10 @@
 use std::{
     borrow::Cow,
-    io::{Result, Write},
+    io::{self, Write},
     iter::FusedIterator,
 };
 
-use crate::s6::{ServiceDir, Status};
+use crate::s6::{ServiceDir, Status, SupervisedStatus};
 
 fn escape(string: &str) -> Cow<str> {
     let escapes = string
@@ -34,6 +34,20 @@ pub struct Writer<'w, W: Write, I: Iterator<Item = Ser
     fused: bool,
 }
 
+static DESCRIPTORS: &[u8] = concat!(
+    "# TYPE s6_service_status stateset\n",
+    "# HELP s6_service_status Status of the service.\n",
+    "# TYPE s6_service_pid gauge\n",
+    "# HELP s6_service_pid Process id of the service.\n",
+    "# TYPE s6_service_exitcode stateset\n",
+    "# HELP s6_service_exitcode Exit code of the service.\n",
+    "# TYPE s6_service_signum stateset\n",
+    "# HELP s6_service_signum Signal number of the service.\n",
+)
+.as_bytes();
+
+static EOF: &[u8] = b"# EOF\n";
+
 impl<'w, W: Write, I: Iterator<Item = ServiceDir>> Writer<'w, W, I> {
     pub fn new(writer: &'w mut W, iter: I) -> Self {
         Self {
@@ -43,86 +57,95 @@ impl<'w, W: Write, I: Iterator<Item = ServiceDir>> Wri
             fused: false,
         }
     }
+
+    fn write_descriptors(&mut self) -> io::Result<()> {
+        self.writer.write_all(DESCRIPTORS)
+    }
+
+    fn write_status(&mut self, service: &str, status: &Status) -> io::Result<()> {
+        match status {
+            Status::Unsupervised => self.write_unsupervised_status(service),
+            Status::Supervised(status) => self.write_supervised_status(service, status),
+        }
+    }
+
+    fn write_unsupervised_status(&mut self, service: &str) -> io::Result<()> {
+        writeln!(
+            self.writer,
+            "s6_service_status{{service=\"{service}\",s6_service_status=\"supervised\"}} 0"
+        )
+    }
+
+    fn write_supervised_status(
+        &mut self,
+        service: &str,
+        status: &SupervisedStatus,
+    ) -> io::Result<()> {
+        write!(
+            self.writer,
+            concat!(
+                "s6_service_status{{service=\"{}\",s6_service_status=\"supervised\"}} 1\n",
+                "s6_service_status{{service=\"{0}\",s6_service_status=\"up\"}} {}\n",
+                "s6_service_status{{service=\"{0}\",s6_service_status=\"wantedup\"}} {}\n",
+                "s6_service_status{{service=\"{0}\",s6_service_status=\"ready\"}} {}\n",
+                "s6_service_status{{service=\"{0}\",s6_service_status=\"paused\"}} {}\n",
+                "s6_service_status{{service=\"{0}\",s6_service_status=\"normallyup\"}} {}\n",
+                "s6_service_pid{{service=\"{0}\"}} {}\n",
+            ),
+            service,
+            if status.up { 1 } else { 0 },
+            if status.wantedup { 1 } else { 0 },
+            if status.ready { 1 } else { 0 },
+            if status.paused { 1 } else { 0 },
+            if status.normallyup { 1 } else { 0 },
+            status.pid,
+        )?;
+        if let Some(exitcode) = status.exitcode {
+            writeln!(
+                self.writer,
+                concat!("s6_service_exitcode{{service=\"{}\",s6_service_exitcode=\"{}\"}} 1"),
+                service, exitcode
+            )?
+        }
+        if let Some(signum) = status.signum {
+            writeln!(
+                self.writer,
+                concat!("s6_service_signum{{service=\"{}\",s6_service_signum=\"{}\"}} 1"),
+                service, signum
+            )?
+        }
+        Ok(())
+    }
+
+    fn write_eof(&mut self) -> io::Result<()> {
+        self.writer.write_all(EOF)
+    }
 }
 
 impl<'w, W: Write, I: Iterator<Item = ServiceDir>> Iterator for Writer<'w, W, I> {
-    type Item = Result<()>;
+    type Item = io::Result<()>;
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.fused {
-            return None;
-        }
-        self.iter
-            .next()
-            .map(|service_dir| {
-                let unescaped = service_dir.name().to_string_lossy();
-                let service = escape(&unescaped);
-                let status = service_dir.status()?;
-                if self.first {
-                    self.first = false;
-                    self.writer.write_all(
-                        concat!(
-                            "# TYPE s6_service_status stateset\n",
-                            "# HELP s6_service_status Status of the service.\n",
-                            "# TYPE s6_service_pid gauge\n",
-                            "# HELP s6_service_pid Process id of the service.\n",
-                            "# TYPE s6_service_exitcode stateset\n",
-                            "# HELP s6_service_exitcode Exit code of the service.\n",
-                            "# TYPE s6_service_signum stateset\n",
-                            "# HELP s6_service_signum Signal number of the service.\n",
-                        )
-                        .as_bytes(),
-                    )?
-                }
-                match status {
-                    Status::Unsupervised => writeln!(
-                        self.writer,
-                        "s6_service_status{{service=\"{service}\",s6_service_status=\"supervised\"}} 0"
-                    ),
-                    Status::Supervised(supervised_status) => {
-                        write!(
-                            self.writer,
-                            concat!(
-                                "s6_service_status{{service=\"{}\",s6_service_status=\"supervised\"}} 1\n",
-                                "s6_service_status{{service=\"{0}\",s6_service_status=\"up\"}} {}\n",
-                                "s6_service_status{{service=\"{0}\",s6_service_status=\"wantedup\"}} {}\n",
-                                "s6_service_status{{service=\"{0}\",s6_service_status=\"ready\"}} {}\n",
-                                "s6_service_status{{service=\"{0}\",s6_service_status=\"paused\"}} {}\n",
-                                "s6_service_status{{service=\"{0}\",s6_service_status=\"normallyup\"}} {}\n",
-                                "s6_service_pid{{service=\"{0}\"}} {}\n",
-                            ),
-                            service,
-                            if supervised_status.up { 1 } else { 0 },
-                            if supervised_status.wantedup { 1 } else { 0 },
-                            if supervised_status.ready { 1 } else { 0 },
-                            if supervised_status.paused { 1 } else { 0 },
-                            if supervised_status.normallyup { 1 } else { 0 },
-                            supervised_status.pid,
-                        )?;
-                        if let Some(exitcode) = supervised_status.exitcode {
-                            writeln!(
-                                self.writer,
-                                concat!("s6_service_exitcode{{service=\"{}\",s6_service_exitcode=\"{}\"}} 1"),
-                                service,
-                                exitcode
-                            )?
-                        }
-                        if let Some(signum) = supervised_status.signum {
-                            writeln!(
-                                self.writer,
-                                concat!("s6_service_signum{{service=\"{}\",s6_service_signum=\"{}\"}} 1"),
-                                service,
-                                signum
-                            )?
-                        }
-                        Ok(())
+            None
+        } else {
+            self.iter
+                .next()
+                .map(|service_dir| {
+                    let unescaped = service_dir.name().to_string_lossy();
+                    let service = escape(&unescaped);
+                    let status = service_dir.status()?;
+                    if self.first {
+                        self.first = false;
+                        self.write_descriptors()?;
                     }
-                }
-            })
-            .or_else(|| {
-                self.fused = true;
-                Some(self.writer.write_all(b"# EOF\n"))
-            })
+                    self.write_status(&service, &status)
+                })
+                .or_else(|| {
+                    self.fused = true;
+                    Some(self.write_eof())
+                })
+        }
     }
 }