Bug 1501974 - Add keyed telemetry to know the download protection remote lookup result . r=francois
authorDimi Lee <dlee@mozilla.com>
Thu, 17 Jan 2019 20:39:53 +0000
changeset 511463 f412108e7d77f62d7eea2461e7e76e007356fa7b
parent 511462 33e42b897fb122df45448648f6a1d2e1a62ce083
child 511464 d7bf0d21448d4c1564f3d5e512167d2b8f887264
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfrancois
bugs1501974
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1501974 - Add keyed telemetry to know the download protection remote lookup result . r=francois Add APPLICATION_REPUTATION_SERVER_VERDICT_2 telemetry with file extension as the key. This can give us an idea about the current detecion rate for archived files. Differential Revision: https://phabricator.services.mozilla.com/D13249
toolkit/components/reputationservice/ApplicationReputation.cpp
toolkit/components/reputationservice/ApplicationReputationTelemetryUtils.cpp
toolkit/components/reputationservice/ApplicationReputationTelemetryUtils.h
toolkit/components/telemetry/Histograms.json
--- a/toolkit/components/reputationservice/ApplicationReputation.cpp
+++ b/toolkit/components/reputationservice/ApplicationReputation.cpp
@@ -775,26 +775,32 @@ static const char* const kRarFileExtensi
     ".r24", ".r25", ".r26", ".r27", ".r28", ".r29", ".rar",
 };
 
 static const char* const kZipFileExtensions[] = {
     ".zip",   // Generic archive
     ".zipx",  // WinZip
 };
 
+static const char* GetFileExt(const nsACString& aFilename,
+                              const char* const aFileExtensions[],
+                              const size_t aLength) {
+  for (size_t i = 0; i < aLength; ++i) {
+    if (StringEndsWith(aFilename, nsDependentCString(aFileExtensions[i]))) {
+      return aFileExtensions[i];
+    }
+  }
+  return nullptr;
+}
+
 // Returns true if the file extension matches one in the given array.
 static bool IsFileType(const nsACString& aFilename,
                        const char* const aFileExtensions[],
                        const size_t aLength) {
-  for (size_t i = 0; i < aLength; ++i) {
-    if (StringEndsWith(aFilename, nsDependentCString(aFileExtensions[i]))) {
-      return true;
-    }
-  }
-  return false;
+  return GetFileExt(aFilename, aFileExtensions, aLength) != nullptr;
 }
 
 ClientDownloadRequest::DownloadType PendingLookup::GetDownloadType(
     const nsACString& aFilename) {
   MOZ_ASSERT(IsFileType(aFilename, kBinaryFileExtensions,
                         ArrayLength(kBinaryFileExtensions)));
 
   // From
@@ -1728,16 +1734,20 @@ nsresult PendingLookup::OnStopRequestInt
              SERVER_RESPONSE_VALID);
   AccumulateCategorical(
       mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2::
           ResponseValid);
 
   // Clamp responses 0-7, we only know about 0-4 for now.
   Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER_VERDICT,
              std::min<uint32_t>(response.verdict(), 7));
+  AccumulateCategoricalKeyed(
+      nsCString(GetFileExt(mFileName, kBinaryFileExtensions,
+                           ArrayLength(kBinaryFileExtensions))),
+      VerdictToLabel(std::min<uint32_t>(response.verdict(), 7)));
   switch (response.verdict()) {
     case safe_browsing::ClientDownloadResponse::DANGEROUS:
       aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS;
       aReason = Reason::VerdictDangerous;
       break;
     case safe_browsing::ClientDownloadResponse::DANGEROUS_HOST:
       aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS_HOST;
       aReason = Reason::VerdictDangerousHost;
--- a/toolkit/components/reputationservice/ApplicationReputationTelemetryUtils.cpp
+++ b/toolkit/components/reputationservice/ApplicationReputationTelemetryUtils.cpp
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ApplicationReputationTelemetryUtils.h"
 #include "mozilla/Assertions.h"
 
 using ServerLabel = mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2;
+using ServerVerdictLabel =
+    mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_VERDICT_2;
 
 struct NSErrorTelemetryResult {
   nsresult mValue;
   ServerLabel mLabel;
 };
 
 static const NSErrorTelemetryResult sResult[] = {
     {
@@ -67,66 +69,60 @@ static const NSErrorTelemetryResult sRes
     },
     {
         NS_ERROR_UNKNOWN_PROXY_HOST,
         ServerLabel::ErrUnknownProxyHost,
     },
 };
 
 mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2 NSErrorToLabel(
-    nsresult rv) {
-  MOZ_ASSERT(rv != NS_OK);
+    nsresult aRv) {
+  MOZ_ASSERT(aRv != NS_OK);
 
   for (const auto& p : sResult) {
-    if (p.mValue == rv) {
+    if (p.mValue == aRv) {
       return p.mLabel;
     }
   }
   return ServerLabel::ErrOthers;
 }
 
 mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2 HTTPStatusToLabel(
-    uint32_t status) {
-  MOZ_ASSERT(status != 200);
+    uint32_t aStatus) {
+  MOZ_ASSERT(aStatus != 200);
 
-  ServerLabel label;
-  switch (status) {
+  switch (aStatus) {
     case 100:
     case 101:
       // Unexpected 1xx return code
-      label = ServerLabel::HTTP1xx;
-      break;
+      return ServerLabel::HTTP1xx;
     case 201:
     case 202:
     case 203:
     case 205:
     case 206:
       // Unexpected 2xx return code
-      label = ServerLabel::HTTP2xx;
-      break;
+      return ServerLabel::HTTP2xx;
     case 204:
       // No Content
-      label = ServerLabel::HTTP204;
-      break;
+      return ServerLabel::HTTP204;
     case 300:
     case 301:
     case 302:
     case 303:
     case 304:
     case 305:
     case 307:
     case 308:
       // Unexpected 3xx return code
-      label = ServerLabel::HTTP3xx;
-      break;
+      return ServerLabel::HTTP3xx;
     case 400:
       // Bad Request - The HTTP request was not correctly formed.
       // The client did not provide all required CGI parameters.
-      label = ServerLabel::HTTP400;
-      break;
+      return ServerLabel::HTTP400;
     case 401:
     case 402:
     case 405:
     case 406:
     case 407:
     case 409:
     case 410:
     case 411:
@@ -137,54 +133,62 @@ mozilla::Telemetry::LABELS_APPLICATION_R
     case 417:
     case 421:
     case 426:
     case 428:
     case 429:
     case 431:
     case 451:
       // Unexpected 4xx return code
-      label = ServerLabel::HTTP4xx;
-      break;
+      return ServerLabel::HTTP4xx;
     case 403:
       // Forbidden - The client id is invalid.
-      label = ServerLabel::HTTP403;
-      break;
+      return ServerLabel::HTTP403;
     case 404:
       // Not Found
-      label = ServerLabel::HTTP404;
-      break;
+      return ServerLabel::HTTP404;
     case 408:
       // Request Timeout
-      label = ServerLabel::HTTP408;
-      break;
+      return ServerLabel::HTTP408;
     case 413:
       // Request Entity Too Large
-      label = ServerLabel::HTTP413;
-      break;
+      return ServerLabel::HTTP413;
     case 500:
     case 501:
     case 510:
       // Unexpected 5xx return code
-      label = ServerLabel::HTTP5xx;
-      break;
+      return ServerLabel::HTTP5xx;
     case 502:
     case 504:
     case 511:
       // Local network errors, we'll ignore these.
-      label = ServerLabel::HTTP502_504_511;
-      break;
+      return ServerLabel::HTTP502_504_511;
     case 503:
       // Service Unavailable - The server cannot handle the request.
       // Clients MUST follow the backoff behavior specified in the
       // Request Frequency section.
-      label = ServerLabel::HTTP503;
-      break;
+      return ServerLabel::HTTP503;
     case 505:
       // HTTP Version Not Supported - The server CANNOT handle the requested
       // protocol major version.
-      label = ServerLabel::HTTP505;
-      break;
+      return ServerLabel::HTTP505;
     default:
-      label = ServerLabel::HTTPOthers;
-  };
-  return label;
+      return ServerLabel::HTTPOthers;
+  }
 }
+
+mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_VERDICT_2
+VerdictToLabel(uint32_t aVerdict) {
+  switch (aVerdict) {
+    case safe_browsing::ClientDownloadResponse::DANGEROUS:
+      return ServerVerdictLabel::Dangerous;
+    case safe_browsing::ClientDownloadResponse::DANGEROUS_HOST:
+      return ServerVerdictLabel::DangerousHost;
+    case safe_browsing::ClientDownloadResponse::POTENTIALLY_UNWANTED:
+      return ServerVerdictLabel::PotentiallyUnwanted;
+    case safe_browsing::ClientDownloadResponse::UNCOMMON:
+      return ServerVerdictLabel::Uncommon;
+    case safe_browsing::ClientDownloadResponse::UNKNOWN:
+      return ServerVerdictLabel::Unknown;
+    default:
+      return ServerVerdictLabel::Safe;
+  }
+}
--- a/toolkit/components/reputationservice/ApplicationReputationTelemetryUtils.h
+++ b/toolkit/components/reputationservice/ApplicationReputationTelemetryUtils.h
@@ -23,17 +23,23 @@
  * NS_ERROR_PROXY_CONNECTION_REFUSED
  * NS_ERROR_NET_PARTIAL_TRANSFER
  * NS_ERROR_NET_INADEQUATE_SECURITY
  * NS_ERROR_UNKNOWN_HOST
  * NS_ERROR_DNS_LOOKUP_QUEUE_FULL
  * NS_ERROR_UNKNOWN_PROXY_HOST
  */
 mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2 NSErrorToLabel(
-    nsresult rv);
+    nsresult aRv);
 
 /**
  * Convert http response status to telemetry labels
  */
 mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2 HTTPStatusToLabel(
-    uint32_t status);
+    uint32_t aStatus);
+
+/**
+ * Convert verdict type to telemetry labels
+ */
+mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_VERDICT_2
+VerdictToLabel(uint32_t aVerdict);
 
 #endif  // ApplicationReputationTelemetryUtils_h__
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -178,16 +178,27 @@
     "alert_emails": ["francois@mozilla.com", "safebrowsing-telemetry@mozilla.org"],
     "expires_in_version": "never",
     "releaseChannelCollection": "opt-out",
     "bug_numbers": [1272788],
     "kind": "enumerated",
     "n_values": 8,
     "description": "Application reputation remote verdict (0=SAFE, 1=DANGEROUS, 2=UNCOMMON, 3=POTENTIALLY_UNWANTED, 4=DANGEROUS_HOST, 5=UNKNOWN)"
   },
+  "APPLICATION_REPUTATION_SERVER_VERDICT_2": {
+    "record_in_processes": ["main", "content"],
+    "alert_emails": ["dlee@mozilla.com", "safebrowsing-telemetry@mozilla.org"],
+    "expires_in_version": "73",
+    "releaseChannelCollection": "opt-out",
+    "bug_numbers": [1501974],
+    "kind": "categorical",
+    "keyed": true,
+    "labels": ["Safe", "Dangerous", "Uncommon", "PotentiallyUnwanted", "DangerousHost", "Unknown"],
+    "description": "Application reputation remote verdict, keyed by file extension"
+  },
   "APPLICATION_REPUTATION_REMOTE_LOOKUP_RESPONSE_TIME": {
     "record_in_processes": ["main", "content"],
     "alert_emails": ["dlee@mozilla.com", "safebrowsing-telemetry@mozilla.org"],
     "expires_in_version": "never",
     "releaseChannelCollection": "opt-out",
     "bug_numbers": [1479898],
     "kind": "linear",
     "low": 1000,