Add telemetry events for loading extensions (#9793)
* Store extensions versions' wasm API version in the database * Share a common struct for extension API responses between collab and client * Add wasm API version and schema version to extension API responses Release Notes: - N/A Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
9b62e461ed
commit
5adc51f113
22 changed files with 531 additions and 306 deletions
|
@ -1,5 +1,5 @@
|
|||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
use super::ips_file::IpsFile;
|
||||
use crate::{api::slack, AppState, Error, Result};
|
||||
use anyhow::{anyhow, Context};
|
||||
use aws_sdk_s3::primitives::ByteStream;
|
||||
use axum::{
|
||||
|
@ -9,18 +9,16 @@ use axum::{
|
|||
routing::post,
|
||||
Extension, Router, TypedHeader,
|
||||
};
|
||||
use rpc::ExtensionMetadata;
|
||||
use serde::{Serialize, Serializer};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::sync::{Arc, OnceLock};
|
||||
use telemetry_events::{
|
||||
ActionEvent, AppEvent, AssistantEvent, CallEvent, CopilotEvent, CpuEvent, EditEvent,
|
||||
EditorEvent, Event, EventRequestBody, EventWrapper, MemoryEvent, SettingEvent,
|
||||
EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, MemoryEvent, SettingEvent,
|
||||
};
|
||||
use util::SemanticVersion;
|
||||
|
||||
use crate::{api::slack, AppState, Error, Result};
|
||||
|
||||
use super::ips_file::IpsFile;
|
||||
|
||||
pub fn router() -> Router {
|
||||
Router::new()
|
||||
.route("/telemetry/events", post(post_events))
|
||||
|
@ -331,6 +329,21 @@ pub async fn post_events(
|
|||
&request_body,
|
||||
first_event_at,
|
||||
)),
|
||||
Event::Extension(event) => {
|
||||
let metadata = app
|
||||
.db
|
||||
.get_extension_version(&event.extension_id, &event.version)
|
||||
.await?;
|
||||
to_upload
|
||||
.extension_events
|
||||
.push(ExtensionEventRow::from_event(
|
||||
event.clone(),
|
||||
&wrapper,
|
||||
&request_body,
|
||||
metadata,
|
||||
first_event_at,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,6 +365,7 @@ struct ToUpload {
|
|||
memory_events: Vec<MemoryEventRow>,
|
||||
app_events: Vec<AppEventRow>,
|
||||
setting_events: Vec<SettingEventRow>,
|
||||
extension_events: Vec<ExtensionEventRow>,
|
||||
edit_events: Vec<EditEventRow>,
|
||||
action_events: Vec<ActionEventRow>,
|
||||
}
|
||||
|
@ -410,6 +424,15 @@ impl ToUpload {
|
|||
.await
|
||||
.with_context(|| format!("failed to upload to table '{SETTING_EVENTS_TABLE}'"))?;
|
||||
|
||||
const EXTENSION_EVENTS_TABLE: &str = "extension_events";
|
||||
Self::upload_to_table(
|
||||
EXTENSION_EVENTS_TABLE,
|
||||
&self.extension_events,
|
||||
clickhouse_client,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("failed to upload to table '{EXTENSION_EVENTS_TABLE}'"))?;
|
||||
|
||||
const EDIT_EVENTS_TABLE: &str = "edit_events";
|
||||
Self::upload_to_table(EDIT_EVENTS_TABLE, &self.edit_events, clickhouse_client)
|
||||
.await
|
||||
|
@ -861,6 +884,68 @@ impl SettingEventRow {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, clickhouse::Row)]
|
||||
pub struct ExtensionEventRow {
|
||||
// AppInfoBase
|
||||
app_version: String,
|
||||
major: Option<i32>,
|
||||
minor: Option<i32>,
|
||||
patch: Option<i32>,
|
||||
release_channel: String,
|
||||
|
||||
// ClientEventBase
|
||||
installation_id: Option<String>,
|
||||
session_id: Option<String>,
|
||||
is_staff: Option<bool>,
|
||||
time: i64,
|
||||
|
||||
// ExtensionEventRow
|
||||
extension_id: Arc<str>,
|
||||
extension_version: Arc<str>,
|
||||
dev: bool,
|
||||
schema_version: Option<i32>,
|
||||
wasm_api_version: Option<String>,
|
||||
}
|
||||
|
||||
impl ExtensionEventRow {
|
||||
fn from_event(
|
||||
event: ExtensionEvent,
|
||||
wrapper: &EventWrapper,
|
||||
body: &EventRequestBody,
|
||||
extension_metadata: Option<ExtensionMetadata>,
|
||||
first_event_at: chrono::DateTime<chrono::Utc>,
|
||||
) -> Self {
|
||||
let semver = body.semver();
|
||||
let time =
|
||||
first_event_at + chrono::Duration::milliseconds(wrapper.milliseconds_since_first_event);
|
||||
|
||||
Self {
|
||||
app_version: body.app_version.clone(),
|
||||
major: semver.map(|s| s.major as i32),
|
||||
minor: semver.map(|s| s.minor as i32),
|
||||
patch: semver.map(|s| s.patch as i32),
|
||||
release_channel: body.release_channel.clone().unwrap_or_default(),
|
||||
installation_id: body.installation_id.clone(),
|
||||
session_id: body.session_id.clone(),
|
||||
is_staff: body.is_staff,
|
||||
time: time.timestamp_millis(),
|
||||
extension_id: event.extension_id,
|
||||
extension_version: event.version,
|
||||
dev: extension_metadata.is_none(),
|
||||
schema_version: extension_metadata
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.manifest.schema_version),
|
||||
wasm_api_version: extension_metadata.as_ref().and_then(|metadata| {
|
||||
metadata
|
||||
.manifest
|
||||
.wasm_api_version
|
||||
.as_ref()
|
||||
.map(|version| version.to_string())
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, clickhouse::Row)]
|
||||
pub struct EditEventRow {
|
||||
// AppInfoBase
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue