Skip to content

Commit 8727753

Browse files
committed
stamp: align with supabase otel requirement
1 parent b309ee5 commit 8727753

File tree

18 files changed

+1030
-129
lines changed

18 files changed

+1030
-129
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ deno_fs = { version = "0.92.0", features = ["sync_fs"] }
5555
deno_http = "0.180.0"
5656
deno_io = "0.92.0"
5757
deno_net = "0.174.0"
58-
deno_telemetry = "0.12.0"
58+
deno_telemetry = "0.17.0"
5959
deno_tls = "0.169.0"
6060
deno_url = "0.182.0"
6161
deno_web = "0.213.0"

cli/src/flags.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use clap::ArgAction;
1111
use clap::ArgGroup;
1212
use clap::Command;
1313
use clap::ValueEnum;
14+
use deno::deno_telemetry;
1415
use deno_facade::Checksum;
1516

1617
#[derive(ValueEnum, Default, Clone, Copy)]
@@ -28,6 +29,30 @@ impl From<EszipV2ChecksumKind> for Option<Checksum> {
2829
}
2930
}
3031

32+
#[derive(ValueEnum, Clone, Copy)]
33+
pub(super) enum OtelKind {
34+
Main,
35+
Event,
36+
}
37+
38+
#[derive(ValueEnum, Default, Clone, Copy)]
39+
pub(super) enum OtelConsoleConfig {
40+
#[default]
41+
Ignore,
42+
Capture,
43+
Replace,
44+
}
45+
46+
impl From<OtelConsoleConfig> for deno_telemetry::OtelConsoleConfig {
47+
fn from(value: OtelConsoleConfig) -> Self {
48+
match value {
49+
OtelConsoleConfig::Ignore => Self::Ignore,
50+
OtelConsoleConfig::Capture => Self::Capture,
51+
OtelConsoleConfig::Replace => Self::Replace,
52+
}
53+
}
54+
}
55+
3156
pub(super) fn get_cli() -> Command {
3257
Command::new(env!("CARGO_BIN_NAME"))
3358
.about(env!("CARGO_PKG_DESCRIPTION"))
@@ -278,6 +303,21 @@ fn get_start_command() -> Command {
278303
.value_parser(value_parser!(u8).range(..=99))
279304
.default_value("90"),
280305
)
306+
.arg(
307+
arg!(--"enable-otel")
308+
.help("Enable Otel in the main and event workers")
309+
.value_delimiter(',')
310+
.value_parser(value_parser!(OtelKind))
311+
.num_args(0..=1)
312+
.default_missing_value("main,event")
313+
.action(ArgAction::Append),
314+
)
315+
.arg(
316+
arg!(--"otel-console" <MODE>)
317+
// .env("OTEL_DENO_CONSOLE")
318+
.help("Configure otel console auto instrumentation")
319+
.value_parser(value_parser!(OtelConsoleConfig)),
320+
)
281321
}
282322

283323
fn get_bundle_command() -> Command {

cli/src/main.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::sync::Arc;
1010
use anyhow::bail;
1111
use anyhow::Context;
1212
use anyhow::Error;
13+
use base::server;
1314
use base::server::Builder;
1415
use base::server::ServerFlags;
1516
use base::server::Tls;
@@ -30,6 +31,8 @@ use deno_facade::Metadata;
3031
use env::resolve_deno_runtime_env;
3132
use flags::get_cli;
3233
use flags::EszipV2ChecksumKind;
34+
use flags::OtelConsoleConfig;
35+
use flags::OtelKind;
3336
use log::warn;
3437

3538
mod env;
@@ -83,7 +86,7 @@ fn main() -> Result<ExitCode, anyhow::Error> {
8386
Some(("start", sub_matches)) => {
8487
deno_telemetry::init(
8588
deno::versions::otel_runtime_config(),
86-
&OtelConfig::default(),
89+
OtelConfig::default(),
8790
)?;
8891

8992
let ip = sub_matches.get_one::<String>("ip").cloned().unwrap();
@@ -128,6 +131,17 @@ fn main() -> Result<ExitCode, anyhow::Error> {
128131
.cloned()
129132
.unwrap();
130133

134+
let enable_otel = sub_matches
135+
.get_many::<OtelKind>("enable-otel")
136+
.unwrap_or_default()
137+
.cloned()
138+
.collect::<Vec<_>>();
139+
140+
let otel_console = sub_matches
141+
.get_one::<OtelConsoleConfig>("otel-console")
142+
.cloned()
143+
.map(Into::into);
144+
131145
let event_service_manager_path =
132146
sub_matches.get_one::<String>("event-worker").cloned();
133147
let maybe_main_entrypoint =
@@ -210,6 +224,21 @@ fn main() -> Result<ExitCode, anyhow::Error> {
210224
.unwrap();
211225

212226
let flags = ServerFlags {
227+
otel: if !enable_otel.is_empty() {
228+
if enable_otel.len() > 1 {
229+
Some(server::OtelKind::Both)
230+
} else {
231+
match enable_otel.first() {
232+
Some(OtelKind::Main) => Some(server::OtelKind::Main),
233+
Some(OtelKind::Event) => Some(server::OtelKind::Event),
234+
None => None,
235+
}
236+
}
237+
} else {
238+
None
239+
},
240+
otel_console,
241+
213242
no_module_cache,
214243
allow_main_inspector,
215244
tcp_nodelay,

crates/base/src/runtime/mod.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use base_rt::get_current_cpu_time_ns;
2323
use base_rt::BlockingScopeCPUUsage;
2424
use base_rt::DenoRuntimeDropToken;
2525
use base_rt::DropToken;
26-
use base_rt::RuntimeOtelAttribute;
26+
use base_rt::RuntimeOtelExtraAttributes;
2727
use base_rt::RuntimeState;
2828
use base_rt::RuntimeWaker;
2929
use cooked_waker::IntoWaker;
@@ -55,6 +55,7 @@ use deno_cache::SqliteBackedCache;
5555
use deno_core::error::AnyError;
5656
use deno_core::error::JsError;
5757
use deno_core::serde_json;
58+
use deno_core::serde_json::Value;
5859
use deno_core::url::Url;
5960
use deno_core::v8;
6061
use deno_core::v8::GCCallbackFlags;
@@ -1105,6 +1106,7 @@ where
11051106
s3_fs,
11061107
beforeunload_cpu_threshold,
11071108
beforeunload_mem_threshold,
1109+
context,
11081110
..
11091111
} = match bootstrap_ret {
11101112
Ok(Ok(v)) => v,
@@ -1116,6 +1118,7 @@ where
11161118
}
11171119
};
11181120

1121+
let context = context.unwrap_or_default();
11191122
let span = Span::current();
11201123
let post_task_ret = unsafe {
11211124
spawn_blocking_non_send(|| {
@@ -1143,14 +1146,31 @@ where
11431146
op_state.put::<HashMap<usize, CancellationToken>>(HashMap::new());
11441147
}
11451148

1149+
let mut otel_attributes = HashMap::new();
1150+
1151+
otel_attributes.insert(
1152+
"edge_runtime.worker.kind".into(),
1153+
conf.to_worker_kind().to_string().into(),
1154+
);
1155+
11461156
if conf.is_user_worker() {
11471157
let conf = conf.as_user_worker().unwrap();
11481158
let key = conf.key.map_or("".to_string(), |k| k.to_string());
11491159

11501160
// set execution id for user workers
11511161
env_vars.insert("SB_EXECUTION_ID".to_string(), key.clone());
11521162

1153-
op_state.put(RuntimeOtelAttribute(key.into()));
1163+
if let Some(Value::Object(attributes)) = context.get("otel") {
1164+
for (k, v) in attributes {
1165+
otel_attributes.insert(
1166+
k.to_string().into(),
1167+
match v {
1168+
Value::String(str) => str.to_string().into(),
1169+
others => others.to_string().into(),
1170+
},
1171+
);
1172+
}
1173+
}
11541174

11551175
if let Some(events_msg_tx) = conf.events_msg_tx.clone() {
11561176
op_state.put::<mpsc::UnboundedSender<WorkerEventWithMetadata>>(
@@ -1161,14 +1181,11 @@ where
11611181
execution_id: conf.key,
11621182
});
11631183
}
1164-
} else {
1165-
op_state.put(RuntimeOtelAttribute(
1166-
conf.to_worker_kind().to_string().into(),
1167-
));
11681184
}
11691185

11701186
op_state.put(ext_env::EnvVars(env_vars));
11711187
op_state.put(DenoRuntimeDropToken(DropToken(drop_token.clone())));
1188+
op_state.put(RuntimeOtelExtraAttributes(otel_attributes));
11721189
}
11731190

11741191
if is_user_worker {

crates/base/src/server.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashSet;
12
use std::future::pending;
23
use std::future::Future;
34
use std::net::SocketAddr;
@@ -13,6 +14,7 @@ use anyhow::Context;
1314
use anyhow::Error;
1415
use deno::deno_telemetry::OtelConfig;
1516
use deno::deno_telemetry::OtelConsoleConfig;
17+
use deno::deno_telemetry::OtelPropagators;
1618
use deno_core::serde_json;
1719
use deno_core::serde_json::json;
1820
use either::Either;
@@ -269,8 +271,18 @@ pub struct WorkerEntrypoints {
269271
pub events: Option<String>,
270272
}
271273

274+
#[derive(Debug, Clone, Copy)]
275+
pub enum OtelKind {
276+
Main,
277+
Event,
278+
Both,
279+
}
280+
272281
#[derive(Debug, Default, Clone, Copy)]
273282
pub struct ServerFlags {
283+
pub otel: Option<OtelKind>,
284+
pub otel_console: Option<OtelConsoleConfig>,
285+
274286
pub no_module_cache: bool,
275287
pub allow_main_inspector: bool,
276288
pub tcp_nodelay: bool,
@@ -401,13 +413,19 @@ impl Server {
401413
.set_server_flags(Some(Left(flags.clone())))
402414
.set_termination_token(Some(termination_tokens.event.clone().unwrap()));
403415

404-
builder
405-
.set_entrypoint(maybe_event_entrypoint.as_deref())
406-
.set_otel_config(Some(OtelConfig {
416+
builder.set_entrypoint(maybe_event_entrypoint.as_deref());
417+
418+
if let Some(OtelKind::Event | OtelKind::Both) = flags.otel {
419+
builder.set_otel_config(Some(OtelConfig {
407420
tracing_enabled: true,
408-
console: OtelConsoleConfig::Capture,
421+
console: flags.otel_console.unwrap_or_default(),
422+
propagators: HashSet::from([
423+
OtelPropagators::TraceContext,
424+
OtelPropagators::Baggage,
425+
]),
409426
..Default::default()
410427
}));
428+
}
411429

412430
Some(builder.build().await?)
413431
} else {
@@ -450,12 +468,19 @@ impl Server {
450468
.set_shared_metric_source(Some(shared_metric_src.clone()))
451469
.set_event_worker_metric_source(
452470
event_worker_surface.as_ref().map(|it| it.metric.clone()),
453-
)
454-
.set_otel_config(Some(OtelConfig {
471+
);
472+
473+
if let Some(OtelKind::Main | OtelKind::Both) = flags.otel {
474+
builder.set_otel_config(Some(OtelConfig {
455475
tracing_enabled: true,
456-
console: OtelConsoleConfig::Capture,
476+
console: flags.otel_console.unwrap_or_default(),
477+
propagators: HashSet::from([
478+
OtelPropagators::TraceContext,
479+
OtelPropagators::Baggage,
480+
]),
457481
..Default::default()
458482
}));
483+
}
459484

460485
builder.build().await?
461486
};

crates/base/tests/integration_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3827,7 +3827,7 @@ async fn test_should_be_able_to_trigger_early_drop_with_mem() {
38273827
let resp = tb
38283828
.request(|b| {
38293829
b.uri("/early-drop-mem")
3830-
.header("x-memory-limit-mb", HeaderValue::from_static("22"))
3830+
.header("x-memory-limit-mb", HeaderValue::from_static("30"))
38313831
.body(Body::empty())
38323832
.context("can't make request")
38333833
})

crates/base_rt/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::num::NonZeroUsize;
23
use std::sync::atomic::AtomicI64;
34
use std::sync::atomic::Ordering;
@@ -200,4 +201,6 @@ impl BlockingScopeCPUUsageMetricExt for &mut OpState {
200201
pub struct RuntimeWaker(pub Arc<AtomicWaker>);
201202

202203
#[derive(Debug, Clone)]
203-
pub struct RuntimeOtelAttribute(pub opentelemetry::Value);
204+
pub struct RuntimeOtelExtraAttributes(
205+
pub HashMap<opentelemetry::Key, opentelemetry::Value>,
206+
);

examples/main/index.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import { STATUS_CODE } from "https://deno.land/std/http/status.ts";
33

44
import { handleRegistryRequest } from "./registry/mod.ts";
55
import { join } from "jsr:@std/path@^1.0";
6+
import { context, propagation } from "npm:@opentelemetry/api";
7+
import { W3CBaggagePropagator } from "npm:@opentelemetry/core@1";
8+
9+
// @ts-ignore See https://github.com/denoland/deno/issues/28082
10+
globalThis[Symbol.for("opentelemetry.js.api.1")].propagation =
11+
new W3CBaggagePropagator();
612

713
console.log("main function started");
814
console.log(Deno.version);
@@ -42,6 +48,17 @@ addEventListener("unhandledrejection", (ev) => {
4248
// }, 30 * 1000);
4349

4450
Deno.serve(async (req: Request) => {
51+
const ctx = propagation.extract(context.active(), req.headers, {
52+
get(carrier, key) {
53+
return carrier.get(key) ?? void 0;
54+
},
55+
keys(carrier) {
56+
return [...carrier.keys()];
57+
},
58+
});
59+
const baggage = propagation.getBaggage(ctx);
60+
const requestId = baggage?.getEntry("sb-request-id")?.value ?? null;
61+
4562
const headers = new Headers({
4663
"Content-Type": "application/json",
4764
});
@@ -149,7 +166,7 @@ Deno.serve(async (req: Request) => {
149166

150167
// console.error(`serving the request with ${servicePath}`);
151168

152-
const createWorker = async () => {
169+
const createWorker = async (otelAttributes?: { [_: string]: string }) => {
153170
const memoryLimitMb = 150;
154171
const workerTimeoutMs = 5 * 60 * 1000;
155172
const noModuleCache = false;
@@ -184,10 +201,11 @@ Deno.serve(async (req: Request) => {
184201
staticPatterns,
185202
context: {
186203
useReadSyncFileAPI: true,
204+
otel: otelAttributes,
187205
},
188206
otelConfig: {
189207
tracing_enabled: true,
190-
console: "Replace",
208+
propagators: ["TraceContext", "Baggage"],
191209
},
192210
// maybeEszip,
193211
// maybeEntrypoint,
@@ -200,7 +218,14 @@ Deno.serve(async (req: Request) => {
200218
// If a worker for the given service path already exists,
201219
// it will be reused by default.
202220
// Update forceCreate option in createWorker to force create a new worker for each request.
203-
const worker = await createWorker();
221+
const worker = await createWorker(
222+
requestId
223+
? {
224+
"sb_request_id": requestId,
225+
}
226+
: void 0,
227+
);
228+
204229
const controller = new AbortController();
205230

206231
const signal = controller.signal;

0 commit comments

Comments
 (0)