瀏覽代碼

Add more logging calls across the board

Mark Rousskov 5 年之前
父節點
當前提交
09a68bc297
共有 7 個文件被更改,包括 176 次插入47 次删除
  1. 54 0
      Cargo.lock
  2. 2 0
      Cargo.toml
  3. 6 3
      src/config.rs
  4. 98 35
      src/github.rs
  5. 1 0
      src/handlers/assign.rs
  6. 2 0
      src/lib.rs
  7. 13 9
      src/main.rs

+ 54 - 0
Cargo.lock

@@ -575,6 +575,14 @@ dependencies = [
  "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "lock_api"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "log"
 version = "0.4.6"
@@ -710,6 +718,15 @@ name = "numtoa"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "once_cell"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "openssl"
 version = "0.10.23"
@@ -757,6 +774,16 @@ dependencies = [
  "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "parking_lot"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "parking_lot_core"
 version = "0.4.0"
@@ -769,6 +796,21 @@ dependencies = [
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "parking_lot_core"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "parser"
 version = "0.1.0"
@@ -1086,6 +1128,11 @@ name = "scopeguard"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "scopeguard"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "security-framework"
 version = "0.3.1"
@@ -1409,6 +1456,7 @@ dependencies = [
  "hyper 0.12.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "parser 0.1.0",
  "regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1417,6 +1465,7 @@ dependencies = [
  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1647,6 +1696,7 @@ dependencies = [
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 "checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6"
 "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
+"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
 "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
 "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
@@ -1662,12 +1712,15 @@ dependencies = [
 "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
 "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
 "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
+"checksum once_cell 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6959fb95e7164b7707aa016c65652f9f5a29a9210aa1800e64f51c6ac9988d51"
 "checksum openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)" = "97c140cbb82f3b3468193dd14c1b88def39f341f68257f8a7fe8ed9ed3f628a5"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 "checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc"
 "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
 "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
+"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7"
 "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
+"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
 "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
@@ -1703,6 +1756,7 @@ dependencies = [
 "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
 "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
+"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
 "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
 "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"

+ 2 - 0
Cargo.toml

@@ -24,6 +24,8 @@ toml = "0.5.1"
 hyper = "0.12.32"
 futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] }
 uuid = { version = "0.7.4", features = ["v4"] }
+url = "1.7.2"
+once_cell = "0.2.2"
 
 [dependencies.serde]
 version = "1"

+ 6 - 3
src/config.rs

@@ -12,19 +12,19 @@ lazy_static::lazy_static! {
         RwLock::new(HashMap::new());
 }
 
-#[derive(serde::Deserialize)]
+#[derive(Debug, serde::Deserialize)]
 pub(crate) struct Config {
     pub(crate) relabel: Option<RelabelConfig>,
     pub(crate) assign: Option<AssignConfig>,
 }
 
-#[derive(serde::Deserialize)]
+#[derive(Debug, serde::Deserialize)]
 pub(crate) struct AssignConfig {
     #[serde(default)]
     _empty: (),
 }
 
-#[derive(serde::Deserialize)]
+#[derive(Debug, serde::Deserialize)]
 #[serde(rename_all = "kebab-case")]
 pub(crate) struct RelabelConfig {
     #[serde(default)]
@@ -33,8 +33,10 @@ pub(crate) struct RelabelConfig {
 
 pub(crate) async fn get(gh: &GithubClient, repo: &str) -> Result<Arc<Config>, Error> {
     if let Some(config) = get_cached_config(repo) {
+        log::trace!("returning config for {} from cache", repo);
         Ok(config)
     } else {
+        log::trace!("fetching fresh config for {}", repo);
         get_fresh_config(gh, repo).await
     }
 }
@@ -60,6 +62,7 @@ async fn get_fresh_config(gh: &GithubClient, repo: &str) -> Result<Arc<Config>,
             )
         })?;
     let config = Arc::new(toml::from_slice::<Config>(&contents)?);
+    log::debug!("fresh configuration for {}: {:?}", repo, config);
     CONFIG_CACHE
         .write()
         .unwrap()

+ 98 - 35
src/github.rs

@@ -4,6 +4,7 @@ use futures::{
     compat::{Future01CompatExt, Stream01CompatExt},
     stream::{FuturesUnordered, StreamExt},
 };
+use once_cell::sync::OnceCell;
 use reqwest::header::{AUTHORIZATION, USER_AGENT};
 use reqwest::{
     r#async::{Client, RequestBuilder, Response},
@@ -24,7 +25,12 @@ impl GithubClient {
 
         let req_dbg = format!("{:?}", req);
 
-        let resp = self.client.execute(req).compat().await.context(req_dbg.clone())?;
+        let resp = self
+            .client
+            .execute(req)
+            .compat()
+            .await
+            .context(req_dbg.clone())?;
 
         resp.error_for_status_ref().context(req_dbg.clone())?;
 
@@ -68,10 +74,10 @@ impl User {
             .await
             .context("could not get team data")?;
         let map = permission.teams;
-        Ok(map["all"].members.iter().any(|g| g.github == self.login)
-            || map
-                .get("wg-triage")
-                .map_or(false, |w| w.members.iter().any(|g| g.github == self.login)))
+        let is_triager = map
+            .get("wg-triage")
+            .map_or(false, |w| w.members.iter().any(|g| g.github == self.login));
+        Ok(map["all"].members.iter().any(|g| g.github == self.login) || is_triager)
     }
 }
 
@@ -106,6 +112,8 @@ pub struct Issue {
     // API URL
     repository_url: String,
     comments_url: String,
+    #[serde(skip)]
+    repository: OnceCell<IssueRepository>,
 }
 
 #[derive(Debug, serde::Deserialize)]
@@ -121,6 +129,7 @@ pub enum AssignmentError {
     Http(Error),
 }
 
+#[derive(Debug)]
 pub enum Selection<'a, T> {
     All,
     One(&'a T),
@@ -137,7 +146,37 @@ impl fmt::Display for AssignmentError {
 
 impl std::error::Error for AssignmentError {}
 
+#[derive(Debug)]
+struct IssueRepository {
+    organization: String,
+    repository: String,
+}
+
+impl fmt::Display for IssueRepository {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}/{}", self.organization, self.repository)
+    }
+}
+
 impl Issue {
+    fn repository(&self) -> &IssueRepository {
+        self.repository.get_or_init(|| {
+            log::trace!("get repository for {}", self.repository_url);
+            let url = url::Url::parse(&self.repository_url).unwrap();
+            let mut segments = url.path_segments().unwrap();
+            let repository = segments.nth_back(0).unwrap();
+            let organization = segments.nth_back(1).unwrap();
+            IssueRepository {
+                organization: organization.into(),
+                repository: repository.into(),
+            }
+        })
+    }
+
+    pub fn global_id(&self) -> String {
+        format!("{}#{}", self.repository(), self.number)
+    }
+
     pub async fn get_comment(&self, client: &GithubClient, id: usize) -> Result<Comment, Error> {
         let comment_url = format!("{}/issues/comments/{}", self.repository_url, id);
         let comment = client.json(client.get(&comment_url)).await?;
@@ -150,9 +189,9 @@ impl Issue {
         struct ChangedIssue<'a> {
             body: &'a str,
         }
-        client._send_req(client
-            .patch(&edit_url)
-            .json(&ChangedIssue { body })).await
+        client
+            ._send_req(client.patch(&edit_url).json(&ChangedIssue { body }))
+            .await
             .context("failed to edit issue body")?;
         Ok(())
     }
@@ -168,10 +207,13 @@ impl Issue {
         struct NewComment<'a> {
             body: &'a str,
         }
-        client._send_req(client
-            .patch(&comment_url)
-            .json(&NewComment { body: new_body }))
-        .await
+        client
+            ._send_req(
+                client
+                    .patch(&comment_url)
+                    .json(&NewComment { body: new_body }),
+            )
+            .await
             .context("failed to edit comment")?;
         Ok(())
     }
@@ -181,15 +223,15 @@ impl Issue {
         struct PostComment<'a> {
             body: &'a str,
         }
-        client._send_req(client
-            .post(&self.comments_url)
-            .json(&PostComment { body }))
-        .await
+        client
+            ._send_req(client.post(&self.comments_url).json(&PostComment { body }))
+            .await
             .context("failed to post comment")?;
         Ok(())
     }
 
     pub async fn set_labels(&self, client: &GithubClient, labels: Vec<Label>) -> Result<(), Error> {
+        log::info!("set_labels {} to {:?}", self.global_id(), labels);
         // PUT /repos/:owner/:repo/issues/:number/labels
         // repo_url = https://api.github.com/repos/Codertocat/Hello-World
         let url = format!(
@@ -198,9 +240,10 @@ impl Issue {
             number = self.number
         );
 
-        let mut stream = labels.into_iter().map(|label| {
-            async { (label.exists(&self.repository_url, &client).await, label) }
-        }).collect::<FuturesUnordered<_>>();
+        let mut stream = labels
+            .into_iter()
+            .map(|label| async { (label.exists(&self.repository_url, &client).await, label) })
+            .collect::<FuturesUnordered<_>>();
         let mut labels = Vec::new();
         while let Some((true, label)) = stream.next().await {
             labels.push(label);
@@ -210,11 +253,11 @@ impl Issue {
         struct LabelsReq {
             labels: Vec<String>,
         }
-        client._send_req(client
-            .put(&url)
-            .json(&LabelsReq {
+        client
+            ._send_req(client.put(&url).json(&LabelsReq {
                 labels: labels.iter().map(|l| l.name.clone()).collect(),
-            })).await
+            }))
+            .await
             .context("failed to set labels")?;
 
         Ok(())
@@ -233,6 +276,7 @@ impl Issue {
         client: &GithubClient,
         selection: Selection<'_, User>,
     ) -> Result<(), AssignmentError> {
+        log::info!("remove {:?} assignees for {}", selection, self.global_id());
         let url = format!(
             "{repo_url}/issues/{number}/assignees",
             repo_url = self.repository_url,
@@ -252,16 +296,21 @@ impl Issue {
         struct AssigneeReq<'a> {
             assignees: &'a [&'a str],
         }
-        client._send_req(client
-            .delete(&url)
-            .json(&AssigneeReq {
+        client
+            ._send_req(client.delete(&url).json(&AssigneeReq {
                 assignees: &assignees[..],
-            })).await
+            }))
+            .await
             .map_err(AssignmentError::Http)?;
         Ok(())
     }
 
-    pub async fn set_assignee(&self, client: &GithubClient, user: &str) -> Result<(), AssignmentError> {
+    pub async fn set_assignee(
+        &self,
+        client: &GithubClient,
+        user: &str,
+    ) -> Result<(), AssignmentError> {
+        log::info!("set_assignee for {} to {}", self.global_id(), user);
         let url = format!(
             "{repo_url}/issues/{number}/assignees",
             repo_url = self.repository_url,
@@ -277,12 +326,17 @@ impl Issue {
         match client._send_req(client.get(&check_url)).await {
             Ok((resp, _)) => {
                 if resp.status() == reqwest::StatusCode::NO_CONTENT {
-                    // all okay
+                    log::debug!("set_assignee: assignee is valid");
+                // all okay
                 } else if resp.status() == reqwest::StatusCode::NOT_FOUND {
+                    log::debug!("set_assignee: assignee is invalid, returning");
                     return Err(AssignmentError::InvalidAssignee);
                 }
             }
-            Err(e) => return Err(AssignmentError::Http(e)),
+            Err(e) => {
+                log::debug!("set_assignee: get {} failed, {:?}", check_url, e);
+                return Err(AssignmentError::Http(e));
+            }
         }
 
         self.remove_assignees(client, Selection::All).await?;
@@ -292,9 +346,8 @@ impl Issue {
             assignees: &'a [&'a str],
         }
 
-        client._send_req(client
-            .post(&url)
-            .json(&AssigneeReq { assignees: &[user] }))
+        client
+            ._send_req(client.post(&url).json(&AssigneeReq { assignees: &[user] }))
             .await
             .map_err(AssignmentError::Http)?;
 
@@ -421,7 +474,12 @@ impl GithubClient {
         &self.client
     }
 
-    pub async fn raw_file(&self, repo: &str, branch: &str, path: &str) -> Result<Option<Vec<u8>>, Error> {
+    pub async fn raw_file(
+        &self,
+        repo: &str,
+        branch: &str,
+        path: &str,
+    ) -> Result<Option<Vec<u8>>, Error> {
         let url = format!(
             "https://raw.githubusercontent.com/{}/{}/{}",
             repo, branch, path
@@ -431,7 +489,12 @@ impl GithubClient {
         let req = req
             .build()
             .with_context(|_| format!("failed to build request {:?}", req_dbg))?;
-        let resp = self.client.execute(req).compat().await.context(req_dbg.clone())?;
+        let resp = self
+            .client
+            .execute(req)
+            .compat()
+            .await
+            .context(req_dbg.clone())?;
         let status = resp.status();
         match status {
             StatusCode::OK => {

+ 1 - 0
src/handlers/assign.rs

@@ -43,6 +43,7 @@ impl Handler for AssignmentHandler {
 
         if let Event::Issue(e) = event {
             if e.action != github::IssuesAction::Opened {
+                log::debug!("skipping event, issue was {:?}", e.action);
                 // skip events other than opening the issue to avoid retriggering commands in the
                 // issue body
                 return Ok(None);

+ 2 - 0
src/lib.rs

@@ -79,6 +79,8 @@ pub async fn webhook(
                 .context("IssuesEvent failed to deserialize")
                 .map_err(Error::from)?;
 
+            log::info!("handling issue event {:?}", payload);
+
             let event = github::Event::Issue(payload);
             if let Err(err) = handlers::handle(&ctx, &event).await {
                 if let Some(issue) = event.issue() {

+ 13 - 9
src/main.rs

@@ -124,15 +124,19 @@ async fn run_server(addr: SocketAddr) {
         service_fn(move |req| {
             let ctx = ctx.clone();
             let uuid = Uuid::new_v4();
-            logger::LogFuture::new(uuid, serve_req(req, ctx).map(move |mut resp| {
-                if let Ok(resp) = &mut resp {
-                    resp.headers_mut().insert("X-Request-Id", uuid.to_string().parse().unwrap());
-                }
-                log::info!("response = {:?}", resp);
-                resp
-            }))
-                .boxed()
-                .compat()
+            logger::LogFuture::new(
+                uuid,
+                serve_req(req, ctx).map(move |mut resp| {
+                    if let Ok(resp) = &mut resp {
+                        resp.headers_mut()
+                            .insert("X-Request-Id", uuid.to_string().parse().unwrap());
+                    }
+                    log::info!("response = {:?}", resp);
+                    resp
+                }),
+            )
+            .boxed()
+            .compat()
         })
     });