0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-07 23:06:50 -05:00

feat(unstable): support https otlp endpoints (#27743)

Support HTTPS protocol for otel exporting. Includes support for
`OTEL_EXPORTER_OTLP_CERTIFICATE`, `OTEL_EXPORTER_OTLP_CLIENT_KEY`, and
`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE`

Fixes: https://github.com/denoland/deno/issues/27703
This commit is contained in:
snek 2025-01-22 14:07:04 +01:00 committed by GitHub
parent f175b5b50f
commit 32eb991ef8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 48 additions and 7 deletions

2
Cargo.lock generated
View file

@ -2421,8 +2421,10 @@ dependencies = [
"async-trait",
"deno_core",
"deno_error",
"deno_tls",
"http-body-util",
"hyper 1.4.1",
"hyper-rustls",
"hyper-util",
"log",
"once_cell",

View file

@ -17,8 +17,10 @@ path = "lib.rs"
async-trait.workspace = true
deno_core.workspace = true
deno_error.workspace = true
deno_tls.workspace = true
http-body-util.workspace = true
hyper.workspace = true
hyper-rustls.workspace = true
hyper-util.workspace = true
log.workspace = true
once_cell.workspace = true

View file

@ -477,10 +477,17 @@ mod hyper_client {
use std::task::Poll;
use std::task::{self};
use deno_tls::create_client_config;
use deno_tls::load_certs;
use deno_tls::load_private_keys;
use deno_tls::SocketUse;
use deno_tls::TlsKey;
use deno_tls::TlsKeys;
use http_body_util::BodyExt;
use http_body_util::Full;
use hyper::body::Body as HttpBody;
use hyper::body::Frame;
use hyper_rustls::HttpsConnector;
use hyper_util::client::legacy::connect::HttpConnector;
use hyper_util::client::legacy::Client;
use opentelemetry_http::Bytes;
@ -494,14 +501,41 @@ mod hyper_client {
// same as opentelemetry_http::HyperClient except it uses OtelSharedRuntime
#[derive(Debug, Clone)]
pub struct HyperClient {
inner: Client<HttpConnector, Body>,
inner: Client<HttpsConnector<HttpConnector>, Body>,
}
impl HyperClient {
pub fn new() -> Self {
Self {
inner: Client::builder(OtelSharedRuntime).build(HttpConnector::new()),
}
pub fn new() -> deno_core::anyhow::Result<Self> {
let ca_certs = match std::env::var("OTEL_EXPORTER_OTLP_CERTIFICATE") {
Ok(path) => vec![std::fs::read(path)?],
_ => vec![],
};
let keys = match (
std::env::var("OTEL_EXPORTER_OTLP_CLIENT_KEY"),
std::env::var("OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE"),
) {
(Ok(key_path), Ok(cert_path)) => {
let key = std::fs::read(key_path)?;
let cert = std::fs::read(cert_path)?;
let certs = load_certs(&mut std::io::Cursor::new(cert))?;
let key = load_private_keys(&key)?.into_iter().next().unwrap();
TlsKeys::Static(TlsKey(certs, key))
}
_ => TlsKeys::Null,
};
let tls_config =
create_client_config(None, ca_certs, None, keys, SocketUse::Http)?;
let mut http_connector = HttpConnector::new();
http_connector.enforce_http(false);
let connector = HttpsConnector::from((http_connector, tls_config));
Ok(Self {
inner: Client::builder(OtelSharedRuntime).build(connector),
})
}
}
@ -628,7 +662,7 @@ pub fn init(
// `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable. Additional headers can
// be specified using `OTEL_EXPORTER_OTLP_HEADERS`.
let client = hyper_client::HyperClient::new();
let client = hyper_client::HyperClient::new()?;
let span_exporter = HttpExporterBuilder::default()
.with_http_client(client.clone())

View file

@ -8,6 +8,8 @@ const data = {
const server = Deno.serve(
{
key: Deno.readTextFileSync("../../../testdata/tls/localhost.key"),
cert: Deno.readTextFileSync("../../../testdata/tls/localhost.crt"),
port: 0,
onListen({ port }) {
const command = new Deno.Command(Deno.execPath(), {
@ -16,7 +18,8 @@ const server = Deno.serve(
OTEL_DENO: "true",
DENO_UNSTABLE_OTEL_DETERMINISTIC: "1",
OTEL_EXPORTER_OTLP_PROTOCOL: "http/json",
OTEL_EXPORTER_OTLP_ENDPOINT: `http://localhost:${port}`,
OTEL_EXPORTER_OTLP_ENDPOINT: `https://localhost:${port}`,
OTEL_EXPORTER_OTLP_CERTIFICATE: "../../../testdata/tls/RootCA.crt",
},
stdout: "null",
});