Skip to content

Commit bdc83ee

Browse files
Add telemetry for used SDKs (#3643)
1 parent 4d21d17 commit bdc83ee

File tree

8 files changed

+86
-7
lines changed

8 files changed

+86
-7
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.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ tracing-test = { version = "0.2.5" }
247247
typed-builder = "0.21.0"
248248
ulid = { version = "1.2.0" }
249249
url = { version = "2.5" }
250+
urlencoding = { version = "2.1" }
250251
uuid = { version = "1.3.0", features = ["v7", "serde"] }
251252
xxhash-rust = { version = "0.8", features = ["xxh3"] }
252253

crates/admin/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ tokio = { workspace = true }
6161
tonic = { workspace = true, features = ["transport", "codegen", "prost", "gzip", "zstd"] }
6262
tower = { workspace = true, features = ["load-shed", "limit"] }
6363
tracing = { workspace = true }
64+
urlencoding = { workspace = true }
6465

6566
[dev-dependencies]
6667
restate-bifrost = { workspace = true, features = ["test-util"] }

crates/admin/src/schema_registry/mod.rs

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,19 @@
1111
pub mod error;
1212
mod updater;
1313

14+
use anyhow::Context;
15+
use http::uri::PathAndQuery;
16+
use http::{HeaderMap, HeaderValue, Uri};
1417
use std::borrow::Borrow;
1518
use std::collections::HashMap;
1619
use std::ops::Deref;
1720
use std::sync::Arc;
1821
use std::time::Duration;
19-
20-
use http::Uri;
2122
use tracing::subscriber::NoSubscriber;
23+
use tracing::trace;
2224

23-
use restate_core::{Metadata, MetadataWriter};
25+
use restate_core::{Metadata, MetadataWriter, TaskCenter, TaskKind};
26+
use restate_service_client::HttpClient;
2427
use restate_service_protocol::discovery::{DiscoverEndpoint, DiscoveredEndpoint, ServiceDiscovery};
2528
use restate_types::identifiers::{DeploymentId, ServiceRevision, SubscriptionId};
2629
use restate_types::schema::Schema;
@@ -77,18 +80,21 @@ pub enum ModifyServiceChange {
7780
pub struct SchemaRegistry<V> {
7881
metadata_writer: MetadataWriter,
7982
service_discovery: ServiceDiscovery,
83+
telemetry_http_client: Option<HttpClient>,
8084
subscription_validator: V,
8185
}
8286

8387
impl<V> SchemaRegistry<V> {
8488
pub fn new(
8589
metadata_writer: MetadataWriter,
8690
service_discovery: ServiceDiscovery,
91+
telemetry_http_client: Option<HttpClient>,
8792
subscription_validator: V,
8893
) -> Self {
8994
Self {
9095
metadata_writer,
9196
service_discovery,
97+
telemetry_http_client,
9298
subscription_validator,
9399
}
94100
}
@@ -123,7 +129,7 @@ impl<V> SchemaRegistry<V> {
123129
),
124130
};
125131

126-
let (id, services) = if !apply_mode.should_apply() {
132+
let (deployment, services) = if !apply_mode.should_apply() {
127133
let mut updater =
128134
SchemaUpdater::new(Metadata::with_current(|m| m.schema()).deref().clone());
129135

@@ -171,7 +177,64 @@ impl<V> SchemaRegistry<V> {
171177
(deployment, services)
172178
};
173179

174-
Ok((id, services))
180+
if apply_mode.should_apply() {
181+
self.send_register_deployment_telemetry(deployment.metadata.sdk_version.clone());
182+
}
183+
184+
Ok((deployment, services))
185+
}
186+
187+
fn send_register_deployment_telemetry(&self, sdk_version: Option<String>) {
188+
if let Some(telemetry_http_client) = &self.telemetry_http_client {
189+
let client = telemetry_http_client.clone();
190+
let _ = TaskCenter::spawn(TaskKind::Disposable, "telemetry-operation", async move {
191+
let (sdk_type, full_sdk_version_string) = if let Some(sdk_version) = &sdk_version {
192+
(
193+
sdk_version
194+
.split_once('/')
195+
.map(|(version, _)| version)
196+
.unwrap_or_else(|| "unknown"),
197+
sdk_version.as_str(),
198+
)
199+
} else {
200+
("unknown", "unknown")
201+
};
202+
203+
let uri = format!(
204+
"{TELEMETRY_URI_PREFIX}?sdk={}&version={}",
205+
urlencoding::encode(sdk_type),
206+
urlencoding::encode(full_sdk_version_string)
207+
)
208+
.parse()
209+
.with_context(|| "cannot create telemetry uri")?;
210+
211+
trace!(%uri, "Sending telemetry data");
212+
213+
match client
214+
.request(
215+
uri,
216+
None,
217+
http::Method::GET,
218+
http_body_util::Empty::new(),
219+
PathAndQuery::from_static("/"),
220+
HeaderMap::from_iter([(
221+
http::header::USER_AGENT,
222+
HeaderValue::from_static("restate-server"),
223+
)]),
224+
)
225+
.await
226+
{
227+
Ok(resp) => {
228+
trace!(status = %resp.status(), "Sent telemetry data")
229+
}
230+
Err(err) => {
231+
trace!(error = %err, "Failed to send telemetry data")
232+
}
233+
}
234+
235+
Ok(())
236+
});
237+
}
175238
}
176239

177240
pub async fn update_deployment(
@@ -467,3 +530,5 @@ impl Borrow<String> for ServiceName {
467530
&self.0
468531
}
469532
}
533+
534+
static TELEMETRY_URI_PREFIX: &str = "https://restate.gateway.scarf.sh/sdk-registration/";

crates/admin/src/service.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::schema_registry::SchemaRegistry;
2020
use crate::{rest_api, state};
2121
use restate_core::MetadataWriter;
2222
use restate_core::network::net_util;
23+
use restate_service_client::HttpClient;
2324
use restate_service_protocol::discovery::ServiceDiscovery;
2425
use restate_types::invocation::client::InvocationClient;
2526
use restate_types::net::BindAddress;
@@ -51,6 +52,7 @@ where
5152
invocation_client: IC,
5253
subscription_validator: V,
5354
service_discovery: ServiceDiscovery,
55+
telemetry_http_client: Option<HttpClient>,
5456
) -> Self {
5557
Self {
5658
bifrost,
@@ -59,6 +61,7 @@ where
5961
schema_registry: SchemaRegistry::new(
6062
metadata_writer,
6163
service_discovery,
64+
telemetry_http_client,
6265
subscription_validator,
6366
),
6467
invocation_client,

crates/ingress-http/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ tokio = { workspace = true }
4848
tower = { workspace = true, features = ["util"] }
4949
tower-http = { workspace = true, features = ["cors", "normalize-path"] }
5050
url = "2.5.0"
51-
urlencoding = "2.1"
51+
urlencoding = { workspace = true }
5252

5353
[dev-dependencies]
5454
restate-core = { workspace = true, features = ["test-util"] }

crates/node/src/roles/admin.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use restate_core::network::TransportConnect;
2020
use restate_core::partitions::PartitionRouting;
2121
use restate_core::worker_api::PartitionProcessorInvocationClient;
2222
use restate_core::{Metadata, MetadataWriter, TaskCenter, TaskKind};
23-
use restate_service_client::{AssumeRoleCacheMode, ServiceClient};
23+
use restate_service_client::{AssumeRoleCacheMode, HttpClient, ServiceClient};
2424
use restate_service_protocol::discovery::ServiceDiscovery;
2525
use restate_storage_query_datafusion::context::{QueryContext, SelectPartitionsFromMetadata};
2626
use restate_storage_query_datafusion::empty_invoker_status_handle::EmptyInvokerStatusHandle;
@@ -84,6 +84,12 @@ impl<T: TransportConnect> AdminRole<T> {
8484
ServiceClient::from_options(&config.common.service_client, AssumeRoleCacheMode::None)?;
8585
let service_discovery = ServiceDiscovery::new(retry_policy, client);
8686

87+
let telemetry_http_client = if config.common.disable_telemetry {
88+
None
89+
} else {
90+
Some(HttpClient::from_options(&config.common.service_client.http))
91+
};
92+
8793
let query_context = if let Some(query_context) = local_query_context {
8894
query_context
8995
} else {
@@ -114,6 +120,7 @@ impl<T: TransportConnect> AdminRole<T> {
114120
),
115121
config.ingress.clone(),
116122
service_discovery,
123+
telemetry_http_client,
117124
)
118125
.with_query_context(query_context);
119126

tools/xtask/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ async fn generate_rest_api_doc() -> anyhow::Result<()> {
209209
ServiceClient::from_options(&config.common.service_client, AssumeRoleCacheMode::None)
210210
.unwrap(),
211211
),
212+
None,
212213
);
213214

214215
TaskCenter::spawn(

0 commit comments

Comments
 (0)