use crate::carrier::{LaneRef, LaneRejected};
use crate::dynamic::message_chain;
use crate::fail::Level;
pub const FIELDS: &[&str] = &[
"error",
"error.lane",
"error.code",
"error.level",
"exception.message",
"exception.type",
"otel.status_code",
];
pub(crate) fn record_lanes<R: LaneRejected>(span: &tracing::Span, lane: LaneRef<'_, R>) {
span.record("error", true);
span.record("error.lane", lane.lane().as_str());
span.record("error.level", lane.level().as_str());
span.record("error.code", lane_code(&lane));
match lane {
LaneRef::Rejected(_) | LaneRef::Denied(_) => {}
LaneRef::Transient(t) => {
span.record("exception.message", message_chain(t));
}
LaneRef::Fatal(x) => {
span.record("exception.message", message_chain(x));
span.record("exception.type", x.kind.as_str());
span.record("otel.status_code", "ERROR");
}
}
}
fn lane_code<R: LaneRejected>(lane: &LaneRef<'_, R>) -> &'static str {
match lane {
LaneRef::Rejected(d) => d.code_str(),
LaneRef::Denied(_) => "FORBIDDEN",
LaneRef::Transient(t) => t.kind.as_str(),
LaneRef::Fatal(x) => x.kind.as_str(),
}
}
pub(crate) fn emit_lanes<R: LaneRejected>(lane: LaneRef<'_, R>) {
let lane_name = lane.lane().as_str();
let code = lane_code(&lane);
let message = lane.message();
match lane.level() {
Level::Error => tracing::error!(
error = true,
error.lane = lane_name,
error.code = code,
exception.message = %message
),
Level::Warn => tracing::warn!(
error = true,
error.lane = lane_name,
error.code = code,
exception.message = %message
),
Level::Info => tracing::info!(
error = true,
error.lane = lane_name,
error.code = code,
exception.message = %message
),
Level::Debug => tracing::debug!(
error = true,
error.lane = lane_name,
error.code = code,
exception.message = %message
),
Level::Trace => tracing::trace!(
error = true,
error.lane = lane_name,
error.code = code,
exception.message = %message
),
}
}
pub fn emit<E: crate::Laned>(err: &E) {
err.emit_event();
}