Skip to content

Commit 40496e3

Browse files
authored
Merge pull request #2437 from calebschoepp/trace-more-host-components
Trace some more host components
2 parents 08fbdf5 + 4c416ae commit 40496e3

File tree

6 files changed

+44
-2
lines changed

6 files changed

+44
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/outbound-http/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ spin-expressions = { path = "../expressions", optional = true }
1717
spin-locked-app = { path = "../locked-app" }
1818
spin-outbound-networking = { path = "../outbound-networking" }
1919
spin-world = { path = "../world", optional = true }
20+
spin-telemetry = { path = "../telemetry" }
2021
terminal = { path = "../terminal" }
2122
tracing = { workspace = true }
2223
url = "2.2.1"
2324

2425
[features]
2526
default = ["runtime"]
2627
runtime = ["dep:spin-app", "dep:spin-core", "dep:spin-expressions", "dep:spin-world"]
28+
29+
[lints]
30+
workspace = true

crates/outbound-http/src/host_impl.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use anyhow::Result;
2-
use http::HeaderMap;
2+
use http::{HeaderMap, Uri};
33
use reqwest::Client;
44
use spin_core::async_trait;
55
use spin_outbound_networking::{AllowedHostsConfig, OutboundUrl};
66
use spin_world::v1::{
77
http as outbound_http,
88
http_types::{Headers, HttpError, Method, Request, Response},
99
};
10+
use tracing::{field::Empty, instrument, Level};
1011

1112
/// A very simple implementation for outbound HTTP requests.
1213
#[derive(Default, Clone)]
@@ -38,8 +39,28 @@ impl OutboundHttp {
3839

3940
#[async_trait]
4041
impl outbound_http::Host for OutboundHttp {
42+
#[instrument(name = "spin_outbound_http.send_request", skip_all, err(level = Level::INFO),
43+
fields(otel.kind = "client", url.full = Empty, http.request.method = Empty,
44+
http.response.status_code = Empty, otel.name = Empty, server.address = Empty, server.port = Empty))]
4145
async fn send_request(&mut self, req: Request) -> Result<Result<Response, HttpError>> {
4246
Ok(async {
47+
let current_span = tracing::Span::current();
48+
let method = format!("{:?}", req.method)
49+
.strip_prefix("Method::")
50+
.unwrap_or("_OTHER")
51+
.to_uppercase();
52+
current_span.record("otel.name", method.clone());
53+
current_span.record("url.full", req.uri.clone());
54+
current_span.record("http.request.method", method);
55+
if let Ok(uri) = req.uri.parse::<Uri>() {
56+
if let Some(authority) = uri.authority() {
57+
current_span.record("server.address", authority.host());
58+
if let Some(port) = authority.port() {
59+
current_span.record("server.port", port.as_u16());
60+
}
61+
}
62+
}
63+
4364
tracing::log::trace!("Attempting to send outbound HTTP request to {}", req.uri);
4465
if !self
4566
.is_allowed(&req.uri)
@@ -63,7 +84,8 @@ impl outbound_http::Host for OutboundHttp {
6384

6485
let req_url = reqwest::Url::parse(&abs_url).map_err(|_| HttpError::InvalidUrl)?;
6586

66-
let headers = request_headers(req.headers).map_err(|_| HttpError::RuntimeError)?;
87+
let mut headers = request_headers(req.headers).map_err(|_| HttpError::RuntimeError)?;
88+
spin_telemetry::inject_trace_context(&mut headers);
6789
let body = req.body.unwrap_or_default().to_vec();
6890

6991
if !req.params.is_empty() {
@@ -82,6 +104,7 @@ impl outbound_http::Host for OutboundHttp {
82104
.await
83105
.map_err(log_reqwest_error)?;
84106
tracing::log::trace!("Returning response from outbound request to {}", req.uri);
107+
current_span.record("http.response.status_code", resp.status().as_u16());
85108
response_from_reqwest(resp).await
86109
}
87110
.await)

crates/outbound-mqtt/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ spin-outbound-networking = { path = "../outbound-networking" }
1818
table = { path = "../table" }
1919
tokio = { version = "1", features = ["sync"] }
2020
tracing = { workspace = true }
21+
22+
[lints]
23+
workspace = true

crates/outbound-mqtt/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use spin_core::{async_trait, wasmtime::component::Resource};
88
use spin_world::v2::mqtt::{self as v2, Connection as MqttConnection, Error, Qos};
99

1010
pub use host_component::OutboundMqttComponent;
11+
use tracing::{instrument, Level};
1112

1213
pub struct OutboundMqtt {
1314
allowed_hosts: spin_outbound_networking::AllowedHostsConfig,
@@ -59,6 +60,7 @@ impl v2::Host for OutboundMqtt {}
5960

6061
#[async_trait]
6162
impl v2::HostConnection for OutboundMqtt {
63+
#[instrument(name = "spin_outbound_mqtt.open_connection", skip(self, password), err(level = Level::INFO), fields(otel.kind = "client"))]
6264
async fn open(
6365
&mut self,
6466
address: String,
@@ -80,6 +82,14 @@ impl v2::HostConnection for OutboundMqtt {
8082
.await
8183
}
8284

85+
/// Publish a message to the MQTT broker.
86+
///
87+
/// OTEL trace propagation is not directly supported in MQTT V3. You will need to embed the
88+
/// current trace context into the payload yourself.
89+
/// https://w3c.github.io/trace-context-mqtt/#mqtt-v3-recommendation.
90+
#[instrument(name = "spin_outbound_mqtt.publish", skip(self, connection, payload), err(level = Level::INFO),
91+
fields(otel.kind = "producer", otel.name = format!("{} publish", topic), messaging.operation = "publish",
92+
messaging.system = "mqtt"))]
8393
async fn publish(
8494
&mut self,
8595
connection: Resource<MqttConnection>,

examples/spin-timer/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)