Skip to content
This repository has been archived by the owner on Jul 1, 2021. It is now read-only.

Integrate amplitude #209

Merged
merged 3 commits into from
Jun 16, 2021
Merged
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
160 changes: 160 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions meilisearch-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ uuid = { version = "0.8.2", features = ["serde"] }
walkdir = "2.3.2"
obkv = "0.1.1"
pin-project = "1.0.7"
whoami = { version = "1.1.2", optional = true }
reqwest = { version = "0.11.3", features = ["json"], optional = true }

[dependencies.sentry]
default-features = false
Expand Down Expand Up @@ -109,8 +111,8 @@ mini-dashboard = [
"tempfile",
"zip",
]
telemetry = ["sentry"]
default = ["telemetry", "mini-dashboard"]
analytics = ["sentry", "whoami", "reqwest"]
default = ["analytics", "mini-dashboard"]

[target.'cfg(target_os = "linux")'.dependencies]
jemallocator = "0.3.2"
Expand Down
55 changes: 24 additions & 31 deletions meilisearch-http/src/analytics.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use std::hash::{Hash, Hasher};
use std::{error, thread};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};

use log::error;
use log::debug;
use serde::Serialize;
use serde_qs as qs;
use siphasher::sip::SipHasher;
use walkdir::WalkDir;

use crate::helpers::EnvSizer;
use crate::Data;
use crate::Opt;

Expand All @@ -22,26 +18,21 @@ struct EventProperties {
}

impl EventProperties {
fn from(data: Data) -> Result<EventProperties, Box<dyn error::Error>> {
let mut index_list = Vec::new();
async fn from(data: Data) -> anyhow::Result<EventProperties> {
let stats = data.index_controller.get_all_stats().await?;

let reader = data.db.main_read_txn()?;

for index_uid in data.db.indexes_uids() {
if let Some(index) = data.db.open_index(&index_uid) {
let number_of_documents = index.main.number_of_documents(&reader)?;
index_list.push(number_of_documents);
}
}

let database_size = data.env.size();

let last_update_timestamp = data.db.last_update(&reader)?.map(|u| u.timestamp());
let database_size = stats.database_size;
let last_update_timestamp = stats.last_update.map(|u| u.timestamp());
let number_of_documents = stats
.indexes
.values()
.map(|index| index.number_of_documents)
.collect();

Ok(EventProperties {
database_size,
last_update_timestamp,
number_of_documents: index_list,
number_of_documents,
})
}
}
Expand All @@ -68,10 +59,10 @@ struct Event<'a> {
#[derive(Debug, Serialize)]
struct AmplitudeRequest<'a> {
api_key: &'a str,
event: &'a str,
events: Vec<Event<'a>>,
}

pub fn analytics_sender(data: Data, opt: Opt) {
pub async fn analytics_sender(data: Data, opt: Opt) {
let username = whoami::username();
let hostname = whoami::hostname();
let platform = whoami::platform();
Expand All @@ -93,7 +84,7 @@ pub fn analytics_sender(data: Data, opt: Opt) {
let time = n.as_secs();
let event_type = "runtime_tick";
let elapsed_since_start = first_start.elapsed().as_secs() / 86_400; // One day
let event_properties = EventProperties::from(data.clone()).ok();
let event_properties = EventProperties::from(data.clone()).await.ok();
let app_version = env!("CARGO_PKG_VERSION").to_string();
let app_version = app_version.as_str();
let user_email = std::env::var("MEILI_USER_EMAIL").ok();
Expand All @@ -114,20 +105,22 @@ pub fn analytics_sender(data: Data, opt: Opt) {
user_properties,
event_properties,
};
let event = serde_json::to_string(&event).unwrap();

let request = AmplitudeRequest {
api_key: AMPLITUDE_API_KEY,
event: &event,
events: vec![event],
};

let body = qs::to_string(&request).unwrap();
let response = ureq::post("https://api.amplitude.com/httpapi").send_string(&body);
if !response.ok() {
let body = response.into_string().unwrap();
error!("Unsuccessful call to Amplitude: {}", body);
let response = reqwest::Client::new()
.post("https://api2.amplitude.com/2/httpapi")
.timeout(Duration::from_secs(60)) // 1 minute max
.json(&request)
.send()
.await;
if let Err(e) = response {
debug!("Unsuccessful call to Amplitude: {}", e);
}

thread::sleep(Duration::from_secs(3600)) // one hour
tokio::time::sleep(Duration::from_secs(3600)).await;
}
}
3 changes: 3 additions & 0 deletions meilisearch-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ mod index_controller;
pub mod option;
pub mod routes;

#[cfg(all(not(debug_assertions), feature = "analytics"))]
pub mod analytics;

pub use self::data::Data;
pub use option::Opt;

Expand Down
Loading