0

I am trying to send tracing data to newrelic using opentelemetry-otlp via http

Below is code snippet that I am using

fn main() -> {
   let result = init_tracer_provider();
   
   globa::set_tracer_provider(result.unwrap().clone());

   let tracer = tracer_provider.tracer("my-service-tracer");
   let telemetry_layer = tracing_opentelemetry::layer().with_tracer(tracer);

   let subscriber = Registry:default()
                      .with(telemetry_layer);
   subscriber::set_global_default(subscriber).expect("Some message");
}


fn init_tracer_provider() -> Result<sdktrace::TracerProvider, TraceError> {
    let http_client = hyper_client_config::HyperClient::default();
    opentelemetry_otlp::new_pipeline()
        .tracing()
        .with_exporter(
            http_exporter()
                .with_protocol(Protocol::HttpJson)
                .with_endpoint("https://trace-api.newrelic.com/v1/traces")
                .with_headers(get_http_headers(api_key)
                .with_http_client(http_client),
        )
        .with_trace_config(Config::default().with_resource(RESOURCE.clone()))
        .install_batch(opentelemetry_sdk::runtime::Tokio)
}

fn get_http_headers(api_key : &String) -> HashMap<String,String> {
    let mut headers = HashMap::new();
    headers.insert(String::from_str("Api-Key"), String::from_str(api_key); 
    headers.insert(String::from_str("Content-Type"), String::from_str("application/json");
    headers.insert(String::from_str("Data-Format"), String::from_str("newrelic);  
    headers
}

Another file that maintains hyper_client_config.rs. This I am referring to for implementing trait HttpClient required by with_http_client

use async_trait::async_trait;
use bytes::Bytes;
use http::{Request, Response};
use http_body_util::{BodyExt, Full};
use hyper_util::{
    client::legacy::{
        connect::{Connect, HttpConnector},
        Client,
    },
    rt::TokioExecutor,
};
use opentelemetry_http::{HttpClient, HttpError, ResponseExt};

pub struct HyperClient<C> {
    inner: hyper_util::client::legacy::Client<C, Full<Bytes>>,
}

impl Default for HyperClient<HttpConnector> {
    fn default() -> Self {
        Self {
            inner: Client::builder(TokioExecutor::new()).build_http(),
        }
    }
}

impl<C> std::fmt::Debug for HyperClient<C> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("HyperClient")
            .field("inner", &self.inner)
            .finish()
    }
}

#[async_trait]
impl<C: Connect + Clone + Send + Sync + 'static> HttpClient for HyperClient<C> {
    async fn send(&self, request: Request<Vec<u8>>) -> Result<Response<Bytes>, HttpError> {
        let request = request.map(|body| Full::new(Bytes::from(body)));

        let (parts, body) = self
            .inner
            .request(request)
            .await?
            .error_for_status()?
            .into_parts();
        let body = body.collect().await?.to_bytes();

        Ok(Response::from_parts(parts, body))
    }
}

But I get this error in the logs

Opentelemetry trace error occurred. client error (Connect)

https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs

I am referring to this github code. Can someone help. Is there anything I am missing

0

1 Answer 1

0

.with_endpoint("https://trace-api.newrelic.com/v1/traces") looks wrong, for otlp newrelic end point

Environment gRPC HTTP Endpoint Supported ports
US OTLP https://otlp.nr-data.net 443, 4317, 4318
EU OTLP https://otlp.eu01.nr-data.net 443, 4317, 4318
US FedRAMP OTLP https://gov-otlp.nr-data.net 443, 4317, 4318
(See FedRAMP compliance for more information)
Infinite tracing https://{trace-observer} 443

Example rust code

fn init_tracer() -> Result<trace::Tracer, TraceError> {
    opentelemetry_otlp::new_pipeline()
        .tracing()
        .with_exporter(
            opentelemetry_otlp::new_exporter()
                .http()
                .with_endpoint("https://otlp.nr-data.net/v1/traces")
                .with_headers(HashMap::from([(
                    "api-key".to_string(),
                    "LICENSEKEY".to_string(),
                )]))
        )
        .with_trace_config(
            trace::config().with_resource(Resource::new(vec![KeyValue::new(
                opentelemetry_semantic_conventions::resource::SERVICE_NAME,
                "rust-otlp-newrelic-tracing",
            )])),
        )
        .install_batch(runtime::Tokio)
}

Check the git repo in the reference

Reference:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.