1use controller::Controller;
2use receiver::Receiver;
3use std::fmt::Display;
4use std::hash::Hash;
5use std::net::ToSocketAddrs;
6use tiny_http::{Response, Server};
7
8pub struct HttpReporter<T> {
10 server: Server,
11 controller: Controller<T>,
12}
13
14impl<T: Eq + Hash + Send + Clone + Display> HttpReporter<T> {
15 pub fn new<U: ToSocketAddrs>(receiver: &Receiver<T>, listen: U) -> HttpReporter<T> {
17 let address = listen
18 .to_socket_addrs()
19 .expect("SocketAddr lookup failed")
20 .next()
21 .expect("SocketAddr resolved to empty set");
22
23 let controller = receiver.get_controller();
24 let server = Server::http(address).unwrap();
25
26 HttpReporter {
27 server: server,
28 controller: controller,
29 }
30 }
31
32 pub fn run(&mut self) {
36 for request in self.server.incoming_requests() {
37 let response = match self.controller.get_meters() {
38 Ok(meters) => {
39 let mut output = "".to_owned();
40 match request.url() {
41 "/vars" | "/metrics" => {
42 for (stat, value) in &meters.data {
43 output = output + &format!("{} {}\n", stat, value);
44 }
45 for (stat, value) in &meters.data_float {
46 output = output + &format!("{} {}\n", stat, value);
47 }
48 }
49 _ => {
50 output += "{";
51 for (stat, value) in &meters.data {
52 output = output + &format!("\"{}\":{},", stat, value);
53 }
54 for (stat, value) in &meters.data_float {
55 output = output + &format!("\"{}\":{},", stat, value);
56 }
57 if output.len() > 1 {
58 output.pop();
59 }
60 output += "}";
61 }
62 }
63
64 Response::from_string(output)
65 }
66 Err(_) => {
67 let response = Response::from_string("failed to read meters from receiver");
68 response.with_status_code(500)
69 }
70 };
71
72 let _ = request.respond(response);
73 }
74 }
75}