summaryrefslogtreecommitdiff
path: root/cli/bench/metrics.rs
blob: 964fdde4b904fdc09b724bfd9e40dd4666d4d7a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.

use google_storage1::api::Object;
use google_storage1::hyper;
use google_storage1::hyper_rustls;
use google_storage1::oauth2;
use google_storage1::Storage;
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::io::Cursor;

static GIT_HASH: Lazy<String> = Lazy::new(|| {
  test_util::run_collect(&["git", "rev-parse", "HEAD"], None, None, None, true)
    .0
    .trim()
    .to_string()
});

#[derive(serde::Serialize)]
struct Metric<T: serde::Serialize> {
  name: String,
  value: T,
  sha1: String,
  #[serde(rename = "type")]
  type_: String,
  time: i64,
}

pub struct Reporter {
  wtr: csv::Writer<Vec<u8>>,
  gcloud_client: Option<Storage>,
}

impl Reporter {
  pub async fn new() -> Self {
    dotenv::dotenv().ok();
    let gcloud_client =
      match std::env::var("CI").map(|_| std::env::var("GOOGLE_SVC_KEY")) {
        Ok(Ok(key_str)) => {
          let secret = oauth2::parse_service_account_key(key_str)
            .expect("Failed to load service account key");
          let auth =
            oauth2::authenticator::ServiceAccountAuthenticator::builder(secret)
              .build()
              .await
              .unwrap();
          let client = hyper::Client::builder().build(
            hyper_rustls::HttpsConnectorBuilder::new()
              .with_native_roots()
              .https_or_http()
              .enable_http1()
              .enable_http2()
              .build(),
          );
          Some(Storage::new(client, auth))
        }
        _ => None,
      };
    Self {
      wtr: csv::Writer::from_writer(vec![]),
      gcloud_client,
    }
  }

  pub fn write_one<T: serde::Serialize>(
    &mut self,
    type_: &str,
    name: &str,
    value: T,
  ) {
    self
      .wtr
      .serialize(Metric {
        name: name.to_string(),
        type_: type_.to_string(),
        value,
        sha1: GIT_HASH.clone(),
        time: chrono::Utc::now().timestamp_millis(),
      })
      .unwrap();
  }

  pub fn write<T: serde::Serialize + Copy>(
    &mut self,
    type_: &str,
    hashmap: &HashMap<String, T>,
  ) {
    for (name, value) in hashmap {
      self.write_one(type_, name, *value);
    }
  }

  pub async fn submit(mut self) {
    self.wtr.flush().unwrap();
    if let Some(client) = self.gcloud_client.take() {
      let mut reader = Cursor::new(self.wtr.into_inner().unwrap());
      let object: Object = Object::default();
      client
        .objects()
        .insert(object, "deno_benchmark_data")
        .name(&format!("{}.csv", *GIT_HASH))
        .param("uploadType", "multipart")
        .upload(&mut reader, "text/csv".parse().unwrap())
        .await
        .unwrap();
    }
  }
}