Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: events for ng #26908

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ zstd = "=0.12.4"

opentelemetry = "0.27.0"
opentelemetry-http = "0.27.0"
opentelemetry-otlp = { version = "0.27.0", features = ["logs", "http-proto", "http-json"] }
opentelemetry-otlp = { version = "0.27.0", features = ["logs", "http-proto", "http-json", "populate-logs-event-name"] }
opentelemetry-semantic-conventions = { version = "0.27.0", features = ["semconv_experimental"] }
opentelemetry_sdk = "0.27.0"

Expand Down
9 changes: 5 additions & 4 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,20 +431,21 @@ fn resolve_flags_and_init(
if err.kind() == clap::error::ErrorKind::DisplayVersion =>
{
// Ignore results to avoid BrokenPipe errors.
util::logger::init(None);
util::logger::init(None, None);
let _ = err.print();
deno_runtime::exit(0);
}
Err(err) => {
util::logger::init(None);
util::logger::init(None, None);
exit_for_error(AnyError::from(err))
}
};

if let Some(otel_config) = flags.otel_config() {
let otel_config = flags.otel_config();
util::logger::init(flags.log_level, otel_config.as_ref());
if let Some(otel_config) = otel_config {
deno_runtime::ops::otel::init(otel_config)?;
}
util::logger::init(flags.log_level);

// TODO(bartlomieju): remove in Deno v2.5 and hard error then.
if flags.unstable_config.legacy_flag_enabled {
Expand Down
7 changes: 5 additions & 2 deletions cli/mainrt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,20 @@ fn main() {
let future = async move {
match standalone {
Ok(Some(data)) => {
util::logger::init(
data.metadata.log_level,
data.metadata.otel_config.as_ref(),
);
if let Some(otel_config) = data.metadata.otel_config.clone() {
deno_runtime::ops::otel::init(otel_config)?;
}
util::logger::init(data.metadata.log_level);
load_env_vars(&data.metadata.env_vars_from_env_file);
let exit_code = standalone::run(data).await?;
deno_runtime::exit(exit_code);
}
Ok(None) => Ok(()),
Err(err) => {
util::logger::init(None);
util::logger::init(None, None);
Err(err)
}
}
Expand Down
11 changes: 8 additions & 3 deletions cli/tools/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,14 @@ pub async fn run_script(
let worker_factory = factory.create_cli_main_worker_factory().await?;
let mut worker = worker_factory
.create_main_worker(mode, main_module.clone())
.await?;

let exit_code = worker.run().await?;
.await
.inspect_err(|e| {
deno_runtime::ops::otel::report_event("deno_boot_failure", e)
})?;

let exit_code = worker.run().await.inspect_err(|e| {
deno_runtime::ops::otel::report_event("deno_uncaught_exception", e)
Comment on lines +82 to +86
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit worried about spread of these semi-random strings throughout the codebase. Maybe we could create a deno_otel crate that all other crates pull that contains a list of static: &str EVENT_NAME = "event_name; vars that we can use?

})?;
Ok(exit_code)
}

Expand Down
46 changes: 36 additions & 10 deletions cli/util/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,33 @@
use std::io::Write;

use super::draw_thread::DrawThread;
use deno_runtime::ops::otel::OtelConfig;
use deno_runtime::ops::otel::OtelConsoleConfig;

struct CliLogger(env_logger::Logger);
struct CliLogger {
logger: env_logger::Logger,
otel_console_config: OtelConsoleConfig,
}

impl CliLogger {
pub fn new(logger: env_logger::Logger) -> Self {
Self(logger)
pub fn new(
logger: env_logger::Logger,
otel_console_config: OtelConsoleConfig,
) -> Self {
Self {
logger,
otel_console_config,
}
}

pub fn filter(&self) -> log::LevelFilter {
self.0.filter()
self.logger.filter()
}
}

impl log::Log for CliLogger {
fn enabled(&self, metadata: &log::Metadata) -> bool {
self.0.enabled(metadata)
self.logger.enabled(metadata)
}

fn log(&self, record: &log::Record) {
Expand All @@ -28,18 +39,28 @@ impl log::Log for CliLogger {
// could potentially block other threads that access the draw
// thread's state
DrawThread::hide();
self.0.log(record);
deno_runtime::ops::otel::handle_log(record);
match self.otel_console_config {
OtelConsoleConfig::Ignore => {
self.logger.log(record);
}
OtelConsoleConfig::Capture => {
self.logger.log(record);
deno_runtime::ops::otel::handle_log(record);
}
OtelConsoleConfig::Replace => {
deno_runtime::ops::otel::handle_log(record);
}
}
DrawThread::show();
}
}

fn flush(&self) {
self.0.flush();
self.logger.flush();
}
}

pub fn init(maybe_level: Option<log::Level>) {
pub fn init(maybe_level: Option<log::Level>, otel_config: Option<&OtelConfig>) {
let log_level = maybe_level.unwrap_or(log::Level::Info);
let logger = env_logger::Builder::from_env(
env_logger::Env::new()
Expand Down Expand Up @@ -93,7 +114,12 @@ pub fn init(maybe_level: Option<log::Level>) {
})
.build();

let cli_logger = CliLogger::new(logger);
let cli_logger = CliLogger::new(
logger,
otel_config
.map(|c| c.console)
.unwrap_or(OtelConsoleConfig::Ignore),
);
let max_level = cli_logger.filter();
let r = log::set_boxed_logger(Box::new(cli_logger));
if r.is_ok() {
Expand Down
19 changes: 19 additions & 0 deletions runtime/ops/otel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,25 @@ pub fn flush() {
}
}

pub fn report_event(name: &'static str, data: impl std::fmt::Display) {
let Some((_, log_processor)) = OTEL_PROCESSORS.get() else {
return;
};

let mut log_record = LogRecord::default();

log_record.set_observed_timestamp(SystemTime::now());
log_record.set_event_name(name);
log_record.set_severity_number(Severity::Trace);
log_record.set_severity_text(Severity::Trace.name());
log_record.set_body(format!("{data}").into());

log_processor.emit(
&mut log_record,
&InstrumentationScope::builder("deno").build(),
);
}

pub fn handle_log(record: &log::Record) {
use log::Level;

Expand Down