#rocket #transaction #fairing #requests #name #guard #request

nightly rocket_newrelic

使用New Relic对Rocket应用程序的请求进行仪器化。将公平带附加到您的Rocket应用程序,并且任何包含请求保护中的Transaction的请求都将使用处理程序基本路径和名称作为事务名称进行仪器化。

1个不稳定版本

0.1.0 2019年5月31日

#1867 in 数据库接口

MIT/Apache

30KB
353

Rocket NewRelic

Build Status docs.rs crates.io

使用New Relic对Rocket应用程序的请求进行仪器化。

将公平带附加到您的Rocket应用程序,并且任何包含请求保护中的Transaction的请求都将使用处理程序基本路径和名称作为事务名称进行仪器化。

用法

重要 - 此公平带仍需要以某种方式与您的应用程序一起运行New Relic守护进程,并且底层的newrelicnewrelic-sys Crates有一些额外的构建要求。确保在尝试使用此Crates时满足这些要求。

关键的是,libnewrelic C SDK需要一些musl不提供的函数(至少是qsort_rbacktrace),因此目前无法与musl构建。


将Crates添加到您的Cargo.toml

[dependencies]
rocket_newrelic = { git = "https://github.com/sd2k/rocket_newrelic" }

然后添加一个&Transaction请求保护到您希望仪器化的任何处理程序

use rocket_newrelic::Transaction;

#[get("/user/me")]
pub fn get_me(_transaction: &Transaction) -> &'static str {
    "It's me!"
}

最后,将公平带附加到您的Rocket应用程序

use rocket_newrelic::NewRelic;

fn main() -> {
    let newrelic = NewRelic::new("MY_APP_NAME", "MY_LICENSE_KEY")
        .expect("Could not register with New Relic");
    rocket::ignite()
        .manage(newrelic)
        .mount("/root", routes![get_me])
        .launch();
}

在上面的示例中,我们可以在/root/get_me下看到这些事务。

高级用法

在请求保护中使用的Transaction对象提供了一些方法,允许进一步的仪器化,例如自定义属性和事务段。下面的示例演示了一些此功能;有关更多详细信息,请参阅Transaction的方法。

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket;

use newrelic::{Datastore, ExternalParamsBuilder};
use rocket_contrib::json::Json;
use rocket_newrelic::{NewRelic, Transaction};
use serde_json::Value;

struct User;

// This would normally connect to a database and perhaps return some data.
fn insert_into_db(_: &Json<Value>) -> Result<User, ()> {
    Ok(User {})
}

#[post("/users", data = "<user>")]
fn create_user(transaction: &Transaction, user: Json<Value>) {
    // Add attributes to a transaction
    if let Some(Value::String(name)) = user.get("name") {
        transaction.add_attribute("user name", name);
    }
    if let Some(Some(age)) = user.get("age").map(|a| a.as_i64()) {
        transaction.add_attribute("user age", age);
    }

    // Executing a query in a datastore segment
    let query = "INSERT INTO users VALUES (%s, %s);";
    match transaction.datastore_segment(Datastore::Postgres, "users", "insert", query, |_| {
        insert_into_db(&user)
    }) {
        Ok(_) => println!("Created user"),
        Err(_) => println!("Could not create user"),
    }

    // Doing expensive operations in a custom segment
    let _expensive_value: Result<reqwest::Response, reqwest::Error> =
        transaction.custom_segment("process user", "process", |s| {
            // Nesting an external segment within the custom segment
            let url = "https://logging-thing";
            let external_params = ExternalParamsBuilder::new(url)
                .procedure("set")
                .library("reqwest")
                .build()
                .unwrap();
            s.external_nested(&external_params, |_| {
                reqwest::Client::new().post(url).send()
            })
        });
}

fn main() {
    let newrelic = NewRelic::from_env();
    rocket::ignite()
        .manage(newrelic)
        .mount("/", routes![create_user])
        .launch();
}

Diesel查询

启用diesel功能后,可以将Diesel查询以及&Connection传递到diesel_segment_loaddiesel_segment_first方法。这将记录SQL查询并分别返回所有结果或第一个结果。

依赖项

~14MB
~303K SLoC