mirror of
https://github.com/storytold/voder-proxy.git
synced 2026-10-19 07:43:12 +00:00
add newrelic logging capability
This commit is contained in:
Generated
+17
@@ -420,6 +420,22 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "newrelic"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7ec1eb312ccd33c2d88ff317d59164465a41014ad465ba8a67e2c062343e3a8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"newrelic-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "newrelic-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a9b9030b5f433ac2afb956eeaf89020e07d3cb9b0561cd07f1737c97a4af93a"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
@@ -835,6 +851,7 @@ dependencies = [
|
||||
"hyper",
|
||||
"hyper-reverse-proxy",
|
||||
"log",
|
||||
"newrelic",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
||||
@@ -19,6 +19,7 @@ futures = "0.1"
|
||||
hyper = "0.12"
|
||||
hyper-reverse-proxy = "0.4"
|
||||
log = "0.4.8"
|
||||
newrelic = "0.2.2"
|
||||
rand = "0.7.3"
|
||||
serde = "1.0.104"
|
||||
serde_derive = "1.0.104"
|
||||
|
||||
+28
-6
@@ -2,6 +2,8 @@
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
pub mod newrelic_logger;
|
||||
|
||||
use anyhow::Result as AnyhowResult;
|
||||
use futures::future::{self, Future};
|
||||
use hyper::Method;
|
||||
@@ -19,18 +21,22 @@ use std::sync::Arc;
|
||||
use rand::seq::IteratorRandom;
|
||||
use hyper::http::header::HeaderName;
|
||||
use hyper::header::HeaderValue;
|
||||
use newrelic::App;
|
||||
use crate::newrelic_logger::NewRelicLogger;
|
||||
|
||||
type BoxFut = Box<dyn Future<Item=Response<Body>, Error=hyper::Error> + Send>;
|
||||
|
||||
const ENV_DEFAULT_ROUTE : &'static str = "DEFAULT_ROUTE";
|
||||
const ENV_NEWRELIC_API_KEY : &'static str = "NEWRELIC_API_KEY";
|
||||
const ENV_PROXY_CONFIG_FILE : &'static str = "PROXY_CONFIG_FILE";
|
||||
const ENV_RUST_LOG : &'static str = "RUST_LOG";
|
||||
const ENV_SERVICE_PORT : &'static str = "SERVICE_PORT";
|
||||
|
||||
const DEFAULT_DEFAULT_ROUTE : &'static str = "http://127.0.0.1:12345";
|
||||
const DEFAULT_NEWRELIC_API_KEY : &'static str = "";
|
||||
const DEFAULT_PROXY_CONFIG_FILE : &'static str = "proxy_configs.toml";
|
||||
const DEFAULT_RUST_LOG: &'static str = "tokio_reactor=warn,hyper=info,debug";
|
||||
const DEFAULT_SERVICE_PORT: u16 = 5555;
|
||||
const DEFAULT_RUST_LOG : &'static str = "tokio_reactor=warn,hyper=info,debug";
|
||||
const DEFAULT_SERVICE_PORT : u16 = 5555;
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
struct ProxyConfigs {
|
||||
@@ -198,6 +204,7 @@ fn main() -> AnyhowResult<()> {
|
||||
|
||||
let default_route = get_env_string(ENV_DEFAULT_ROUTE, DEFAULT_DEFAULT_ROUTE);
|
||||
let service_port = get_env_num::<u16>(ENV_SERVICE_PORT, DEFAULT_SERVICE_PORT)?;
|
||||
let newrelic_api_key = get_env_string(ENV_NEWRELIC_API_KEY, DEFAULT_NEWRELIC_API_KEY);
|
||||
|
||||
info!("Default route: {}", default_route);
|
||||
|
||||
@@ -219,23 +226,38 @@ fn main() -> AnyhowResult<()> {
|
||||
default_route: default_route,
|
||||
});
|
||||
|
||||
let newrelic_logger = if newrelic_api_key.is_empty() {
|
||||
NewRelicLogger::null_instance()
|
||||
} else {
|
||||
NewRelicLogger::try_new_or_null("voder-proxy", &newrelic_api_key)
|
||||
};
|
||||
|
||||
let newrelic_logger = Arc::new(newrelic_logger);
|
||||
|
||||
let make_service = make_service_fn(move |socket: &AddrStream| {
|
||||
let remote_addr = socket.remote_addr();
|
||||
info!("Got a request from: {:?}", remote_addr);
|
||||
|
||||
let router2 = router.clone();
|
||||
let newrelic_logger2 = newrelic_logger.clone();
|
||||
|
||||
service_fn(move |req: Request<Body>| {
|
||||
let router3 = router2.clone();
|
||||
let newrelic_logger3 = newrelic_logger2.clone();
|
||||
|
||||
match (req.method(), req.uri().path()) {
|
||||
(&Method::POST, "/speak") =>
|
||||
speak_proxy(req, remote_addr.clone(), router3, "/speak"),
|
||||
(&Method::POST, "/speak_spectrogram") =>
|
||||
speak_proxy(req, remote_addr.clone(), router3, "/speak_spectrogram"),
|
||||
(&Method::POST, "/speak") => {
|
||||
let _droppable_transaction = newrelic_logger3.web_transaction("proxy /speak");
|
||||
speak_proxy(req, remote_addr.clone(), router3, "/speak")
|
||||
},
|
||||
(&Method::POST, "/speak_spectrogram") => {
|
||||
let _droppable_transaction = newrelic_logger3.web_transaction("proxy /speak_spectrogram");
|
||||
speak_proxy(req, remote_addr.clone(), router3, "/speak_spectrogram")
|
||||
},
|
||||
(&Method::GET, "/proxy_health") =>
|
||||
health_check_response(req),
|
||||
_ => {
|
||||
let _droppable_transaction = newrelic_logger3.web_transaction("unmatched endpoint");
|
||||
let forward = router3.get_random_host();
|
||||
info!("Forwarding to `{}` random host: {}", &forward, req.uri());
|
||||
hyper_reverse_proxy::call(remote_addr.ip(), &forward, req)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
use anyhow::Result as AnyhowResult;
|
||||
use newrelic::{App, Transaction};
|
||||
|
||||
pub struct NewRelicLogger {
|
||||
newrelic_api: Option<App>,
|
||||
}
|
||||
|
||||
impl NewRelicLogger {
|
||||
pub fn new(app_name: &str, api_key: &str) -> AnyhowResult<Self> {
|
||||
let newrelic_api = App::new(app_name, api_key)?;
|
||||
Ok(Self {
|
||||
newrelic_api: Some(newrelic_api),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn null_instance() -> Self {
|
||||
Self {
|
||||
newrelic_api: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_new_or_null(app_name: &str, api_key: &str) -> Self {
|
||||
match Self::new(app_name, api_key) {
|
||||
Ok(instance) => instance,
|
||||
Err(_) => Self::null_instance(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn web_transaction(&self, transaction_name: &str) -> Option<Transaction> {
|
||||
if let Some(ref newrelic_api) = self.newrelic_api {
|
||||
info!("Logging request to NewRelic");
|
||||
return newrelic_api.web_transaction(transaction_name).ok();
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user