diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2019-01-10 16:09:50 -0800 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2019-01-10 16:09:50 -0800 | 
| commit | 60d39b2f9923bf1b9d659f2f4dad223ec565466a (patch) | |
| tree | b992730fe230bec74744db4babd3f1eff83f180b /rust | |
| parent | 5a31f1181e9a86aa91e95be87ac386731ce219cd (diff) | |
| download | fatcat-60d39b2f9923bf1b9d659f2f4dad223ec565466a.tar.gz fatcat-60d39b2f9923bf1b9d659f2f4dad223ec565466a.zip | |
crude metrics integration (only a handful for now)
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/env.example | 3 | ||||
| -rw-r--r-- | rust/src/bin/fatcatd.rs | 29 | ||||
| -rw-r--r-- | rust/src/endpoints.rs | 55 | ||||
| -rw-r--r-- | rust/src/server.rs | 12 | 
4 files changed, 79 insertions, 20 deletions
| diff --git a/rust/env.example b/rust/env.example index 482f2400..bee653c2 100644 --- a/rust/env.example +++ b/rust/env.example @@ -5,3 +5,6 @@ AUTH_KEY_IDENT="20190101-dev-dummy-key"  AUTH_SECRET_KEY="5555555555555555555555555555555555555555xms="  AUTH_ALT_KEYS="20181220-dev:6666666666666666666666666666666666666666xms=,20181210-dev:7777777777777777777777777777777777777777xms="  #SENTRY_DSN= +# should be localhost IP, not 'localhost' +#FATCAT_STATSD_HOST="127.0.0.1" +#FATCAT_STATSD_PORT="8125" diff --git a/rust/src/bin/fatcatd.rs b/rust/src/bin/fatcatd.rs index 388c6e61..df5c390e 100644 --- a/rust/src/bin/fatcatd.rs +++ b/rust/src/bin/fatcatd.rs @@ -15,6 +15,9 @@ use iron_slog::{DefaultLogFormatter, LoggerMiddleware};  use sentry::integrations::panic;  use slog::{Drain, Logger};  use std::env; +use cadence::{StatsdClient, QueuingMetricSink, BufferedUdpMetricSink}; +use cadence::prelude::*; +use std::net::UdpSocket;  // HTTP header middleware  header! { (XClacksOverhead, "X-Clacks-Overhead") => [String] } @@ -29,6 +32,7 @@ impl AfterMiddleware for XClacksOverheadMiddleware {      }  } +  /// Create custom server, wire it to the autogenerated router,  /// and pass it to the web server.  fn main() -> Result<()> { @@ -60,7 +64,30 @@ fn main() -> Result<()> {          None      }; -    let server = create_server()?; +    let mut server = create_server()?; + +    // metrics reporting +    match env::var("FATCAT_STATSD_HOST") { +        Err(_) => { +            info!(logger, "no metrics recipient configured"); +        }, +        Ok(host) => { +            let port: u16 = match env::var("FATCAT_STATSD_PORT") { +                Err(_) => cadence::DEFAULT_PORT, +                Ok(var) => var.parse::<u16>()?, // "expect FATCAT_STATSD_PORT to be null or an integer +            }; +            let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); +            socket.set_nonblocking(true).unwrap(); +            let udp_sink = BufferedUdpMetricSink::from((host.as_ref(), port), socket).unwrap(); +            let queuing_sink = QueuingMetricSink::from(udp_sink); +            info!(logger, "sending statsd metrics via UDP to: {}:{}", host, port); +            server.metrics = StatsdClient::from_sink("fatcat.api", queuing_sink); +            //server.metrics = StatsdClient::from_udp_host("fatcat.api", (host.as_ref(), port))?; +            server.metrics.incr("restart").unwrap(); +        } +    }; +    info!(logger, "{:#?}", server.metrics); +      info!(          logger,          "using primary auth key: {}", server.auth_confectionary.identifier, diff --git a/rust/src/endpoints.rs b/rust/src/endpoints.rs index 1bed3c56..027e25bc 100644 --- a/rust/src/endpoints.rs +++ b/rust/src/endpoints.rs @@ -22,6 +22,7 @@ use futures::{self, Future};  use sentry::integrations::failure::capture_fail;  use std::str::FromStr;  use uuid::{self, Uuid}; +use cadence::prelude::*;  // This makes response matching below *much* more terse  use crate::errors::FatcatError::*; @@ -121,8 +122,10 @@ macro_rules! wrap_entity_handlers {                  edit_context.check(&conn)?;                  entity.db_create(&conn, &edit_context)?.into_model()              }).map_err(|e| FatcatError::from(e)) { -                Ok(edit) => -                    $post_resp::CreatedEntity(edit), +                Ok(edit) => { +                    self.metrics.incr("entities.created").ok(); +                    $post_resp::CreatedEntity(edit) +                },                  Err(fe) => generic_auth_err_responses!(fe, $post_resp),              };              Box::new(futures::done(Ok(ret))) @@ -146,8 +149,14 @@ macro_rules! wrap_entity_handlers {                  } else { None };                  self.$post_batch_handler(&conn, entity_list, autoaccept.unwrap_or(false), auth_context.editor_id, editgroup_id)              }).map_err(|e| FatcatError::from(e)) { -                Ok(edit) => -                    $post_batch_resp::CreatedEntities(edit), +                Ok(edits) => { +                    self.metrics.count("entities.created", edits.len() as i64).ok(); +                    if let Some(true) = autoaccept { +                        self.metrics.incr("editgroup.created").ok(); +                        self.metrics.incr("editgroup.accepted").ok(); +                    }; +                    $post_batch_resp::CreatedEntities(edits) +                },                  Err(fe) => generic_auth_err_responses!(fe, $post_batch_resp),              };              Box::new(futures::done(Ok(ret))) @@ -171,8 +180,10 @@ macro_rules! wrap_entity_handlers {                  edit_context.check(&conn)?;                  entity.db_update(&conn, &edit_context, entity_id)?.into_model()              }).map_err(|e| FatcatError::from(e)) { -                Ok(edit) => -                    $update_resp::UpdatedEntity(edit), +                Ok(edit) => { +                    self.metrics.incr("entities.updated").ok(); +                    $update_resp::UpdatedEntity(edit) +                },                  Err(fe) => generic_auth_err_responses!(fe, $update_resp),              };              Box::new(futures::done(Ok(ret))) @@ -195,8 +206,10 @@ macro_rules! wrap_entity_handlers {                  edit_context.check(&conn)?;                  $model::db_delete(&conn, &edit_context, entity_id)?.into_model()              }).map_err(|e| FatcatError::from(e)) { -                Ok(edit) => -                    $delete_resp::DeletedEntity(edit), +                Ok(edit) => { +                    self.metrics.incr("entities.deleted").ok(); +                    $delete_resp::DeletedEntity(edit) +                },                  Err(fe) => generic_auth_err_responses!(fe, $delete_resp),              };              Box::new(futures::done(Ok(ret))) @@ -745,10 +758,13 @@ impl Api for Server {              })              .map_err(|e| FatcatError::from(e))          { -            Ok(()) => AcceptEditgroupResponse::MergedSuccessfully(Success { -                success: true, -                message: "horray!".to_string(), -            }), +            Ok(()) => { +                self.metrics.incr("editgroup.accepted").ok(); +                AcceptEditgroupResponse::MergedSuccessfully(Success { +                    success: true, +                    message: "horray!".to_string(), +                }) +            },              Err(fe) => generic_auth_err_responses!(fe, AcceptEditgroupResponse),          };          Box::new(futures::done(Ok(ret))) @@ -804,7 +820,10 @@ impl Api for Server {              })              .map_err(|e| FatcatError::from(e))          { -            Ok(eg) => CreateEditgroupResponse::SuccessfullyCreated(eg), +            Ok(eg) => { +                self.metrics.incr("editgroup.created").ok(); +                CreateEditgroupResponse::SuccessfullyCreated(eg) +            },              Err(fe) => match fe {                  NotFound(_, _) => CreateEditgroupResponse::NotFound(fe.into()),                  DatabaseError(_) | InternalError(_) => { @@ -884,8 +903,14 @@ impl Api for Server {              })              .map_err(|e: Error| FatcatError::from(e))          { -            Ok((result, true)) => AuthOidcResponse::Created(result), -            Ok((result, false)) => AuthOidcResponse::Found(result), +            Ok((result, true)) => { +                self.metrics.incr("account.signup").ok(); +                AuthOidcResponse::Created(result) +            }, +            Ok((result, false)) => { +                self.metrics.incr("account.login").ok(); +                AuthOidcResponse::Found(result) +            },              Err(fe) => match fe {                  DatabaseError(_) | InternalError(_) => {                      error!("{}", fe); diff --git a/rust/src/server.rs b/rust/src/server.rs index 6b389a97..66b215fc 100644 --- a/rust/src/server.rs +++ b/rust/src/server.rs @@ -8,6 +8,7 @@ use diesel::pg::PgConnection;  use diesel::r2d2::ConnectionManager;  use dotenv::dotenv;  use std::env; +use cadence::{StatsdClient, NopMetricSink};  #[cfg(feature = "postgres")]  embed_migrations!("../migrations/"); @@ -32,6 +33,7 @@ pub fn database_worker_pool() -> Result<ConnectionPool> {  pub struct Server {      pub db_pool: ConnectionPool,      pub auth_confectionary: AuthConfectionary, +    pub metrics: StatsdClient,  }  /// Instantiate a new API server with a pooled database connection @@ -39,13 +41,15 @@ pub fn create_server() -> Result<Server> {      dotenv().ok();      let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");      let manager = ConnectionManager::<PgConnection>::new(database_url); -    let pool = diesel::r2d2::Pool::builder() +    let db_pool = diesel::r2d2::Pool::builder()          .build(manager)          .expect("Failed to create database pool."); -    let confectionary = env_confectionary()?; +    let auth_confectionary = env_confectionary()?; +    let metrics = StatsdClient::from_sink("blackhole", NopMetricSink);      Ok(Server { -        db_pool: pool, -        auth_confectionary: confectionary, +        db_pool, +        auth_confectionary, +        metrics,      })  } | 
