Bug 1513057 - P8: Report telemetry from socket process to parent process r=dragana,mayhemer,janerik
☠☠ backed out by 3f76ed638d83 ☠ ☠
authorKershaw Chang <kershaw@mozilla.com>
Fri, 11 Jan 2019 14:23:19 +0000
changeset 453478 46411c5de3dade8d056fe33b745ee0e4eb7c38f9
parent 453477 de65c456aad6dbd598f81138509c342152ae4047
child 453479 56329b5f1844a1d127bf877351be82006ecdee5b
push id35357
push usernerli@mozilla.com
push dateFri, 11 Jan 2019 21:54:07 +0000
treeherdermozilla-central@0ce024c91511 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana, mayhemer, janerik
bugs1513057
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 1513057 - P8: Report telemetry from socket process to parent process r=dragana,mayhemer,janerik Differential Revision: https://phabricator.services.mozilla.com/D14362
netwerk/ipc/PSocketProcess.ipdl
netwerk/ipc/SocketProcessParent.cpp
netwerk/ipc/SocketProcessParent.h
toolkit/components/telemetry/Processes.yaml
toolkit/components/telemetry/Scalars.yaml
toolkit/components/telemetry/build_scripts/mozparsers/shared_telemetry_utils.py
toolkit/components/telemetry/core/Telemetry.cpp
toolkit/components/telemetry/core/TelemetryCommon.h
toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp
toolkit/components/telemetry/pings/TelemetrySession.jsm
toolkit/components/telemetry/tests/python/test_histogramtools_strict.py
--- a/netwerk/ipc/PSocketProcess.ipdl
+++ b/netwerk/ipc/PSocketProcess.ipdl
@@ -4,27 +4,40 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include MemoryReportTypes;
 include protocol PSocketProcessBridge;
 include protocol PProfiler;
 include PrefsTypes;
 
 using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
+using mozilla::Telemetry::HistogramAccumulation from "mozilla/TelemetryComms.h";
+using mozilla::Telemetry::KeyedHistogramAccumulation from "mozilla/TelemetryComms.h";
+using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
+using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
+using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
+using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
 using base::ProcessId from "base/process.h";
 
 namespace mozilla {
 namespace net {
 
 protocol PSocketProcess
 {
 parent:
   async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
   async AddMemoryReport(MemoryReport aReport);
   async FinishMemoryReport(uint32_t aGeneration);
+  // Messages for sending telemetry to parent process.
+  async AccumulateChildHistograms(HistogramAccumulation[] accumulations);
+  async AccumulateChildKeyedHistograms(KeyedHistogramAccumulation[] accumulations);
+  async UpdateChildScalars(ScalarAction[] actions);
+  async UpdateChildKeyedScalars(KeyedScalarAction[] actions);
+  async RecordChildEvents(ChildEventData[] events);
+  async RecordDiscardedData(DiscardedData data);
 
 child:
   async PreferenceUpdate(Pref pref);
   async RequestMemoryReport(uint32_t generation,
                             bool anonymize,
                             bool minimizeMemoryUsage,
                             MaybeFileDesc DMDFile);
   async SetOffline(bool offline);
--- a/netwerk/ipc/SocketProcessParent.cpp
+++ b/netwerk/ipc/SocketProcessParent.cpp
@@ -2,16 +2,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 "SocketProcessParent.h"
 
 #include "SocketProcessHost.h"
 #include "mozilla/ipc/CrashReporterHost.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/TelemetryIPC.h"
 
 namespace mozilla {
 namespace net {
 
 static SocketProcessParent* sSocketProcessParent;
 
 SocketProcessParent::SocketProcessParent(SocketProcessHost* aHost)
     : mHost(aHost) {
@@ -77,16 +79,57 @@ mozilla::ipc::IPCResult SocketProcessPar
     const uint32_t& aGeneration) {
   if (mMemoryReportRequest) {
     mMemoryReportRequest->Finish(aGeneration);
     mMemoryReportRequest = nullptr;
   }
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildHistograms(
+    InfallibleTArray<HistogramAccumulation>&& aAccumulations) {
+  TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Socket,
+                                          aAccumulations);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildKeyedHistograms(
+    InfallibleTArray<KeyedHistogramAccumulation>&& aAccumulations) {
+  TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Socket,
+                                               aAccumulations);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildScalars(
+    InfallibleTArray<ScalarAction>&& aScalarActions) {
+  TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Socket,
+                                   aScalarActions);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildKeyedScalars(
+    InfallibleTArray<KeyedScalarAction>&& aScalarActions) {
+  TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Socket,
+                                        aScalarActions);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult SocketProcessParent::RecvRecordChildEvents(
+    nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents) {
+  TelemetryIPC::RecordChildEvents(Telemetry::ProcessID::Socket, aEvents);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult SocketProcessParent::RecvRecordDiscardedData(
+    const mozilla::Telemetry::DiscardedData& aDiscardedData) {
+  TelemetryIPC::RecordDiscardedData(Telemetry::ProcessID::Socket,
+                                    aDiscardedData);
+  return IPC_OK();
+}
+
 // To ensure that IPDL is finished before SocketParent gets deleted.
 class DeferredDeleteSocketProcessParent : public Runnable {
  public:
   explicit DeferredDeleteSocketProcessParent(
       UniquePtr<SocketProcessParent>&& aParent)
       : Runnable("net::DeferredDeleteSocketProcessParent"),
         mParent(std::move(aParent)) {}
 
--- a/netwerk/ipc/SocketProcessParent.h
+++ b/netwerk/ipc/SocketProcessParent.h
@@ -36,16 +36,28 @@ class SocketProcessParent final : public
   static SocketProcessParent* GetSingleton();
 
   mozilla::ipc::IPCResult RecvInitCrashReporter(
       Shmem&& aShmem, const NativeThreadId& aThreadId) override;
   mozilla::ipc::IPCResult RecvAddMemoryReport(
       const MemoryReport& aReport) override;
   mozilla::ipc::IPCResult RecvFinishMemoryReport(
       const uint32_t& aGeneration) override;
+  mozilla::ipc::IPCResult RecvAccumulateChildHistograms(
+      InfallibleTArray<HistogramAccumulation>&& aAccumulations) override;
+  mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(
+      InfallibleTArray<KeyedHistogramAccumulation>&& aAccumulations) override;
+  mozilla::ipc::IPCResult RecvUpdateChildScalars(
+      InfallibleTArray<ScalarAction>&& aScalarActions) override;
+  mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(
+      InfallibleTArray<KeyedScalarAction>&& aScalarActions) override;
+  mozilla::ipc::IPCResult RecvRecordChildEvents(
+      nsTArray<ChildEventData>&& events) override;
+  mozilla::ipc::IPCResult RecvRecordDiscardedData(
+      const DiscardedData& aDiscardedData) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   bool SendRequestMemoryReport(const uint32_t& aGeneration,
                                const bool& aAnonymize,
                                const bool& aMinimizeMemoryUsage,
                                const MaybeFileDesc& aDMDFile);
 
  private:
--- a/toolkit/components/telemetry/Processes.yaml
+++ b/toolkit/components/telemetry/Processes.yaml
@@ -19,8 +19,11 @@ extension:
 gpu:
   gecko_enum: GeckoProcessType_GPU
   description: This is the compositor or GPU process.
 dynamic:
   gecko_enum: GeckoProcessType_Default
   description: >
     This is not a real process, it is used to logically group add-on probes.
     It contains data of any probes registered at runtime by add-ons.
+socket:
+  gecko_enum: GeckoProcessType_Socket
+  description: This is the process that handles networking requests.
--- a/toolkit/components/telemetry/Scalars.yaml
+++ b/toolkit/components/telemetry/Scalars.yaml
@@ -2516,16 +2516,27 @@ telemetry.test:
     description: A testing uint scalar; not meant to be touched.
     expires: never
     kind: uint
     notification_emails:
       - telemetry-client-dev@mozilla.com
     record_in_processes:
       - 'content'
 
+  socket_only_uint:
+    bug_numbers:
+      - 1486033
+    description: A testing uint scalar; not meant to be touched.
+    expires: never
+    kind: uint
+    notification_emails:
+      - telemetry-client-dev@mozilla.com
+    record_in_processes:
+      - 'socket'
+
   all_processes_uint:
     bug_numbers:
       - 1278556
     description: A testing uint scalar; not meant to be touched.
     expires: never
     kind: uint
     notification_emails:
       - telemetry-client-dev@mozilla.com
--- a/toolkit/components/telemetry/build_scripts/mozparsers/shared_telemetry_utils.py
+++ b/toolkit/components/telemetry/build_scripts/mozparsers/shared_telemetry_utils.py
@@ -14,16 +14,17 @@ import sys
 # This is a list of flags that determine which process a measurement is allowed
 # to record from.
 KNOWN_PROCESS_FLAGS = {
     'all': 'All',
     'all_children': 'AllChildren',
     'main': 'Main',
     'content': 'Content',
     'gpu': 'Gpu',
+    'socket': 'Socket',
     # Historical Values
     'all_childs': 'AllChildren',  # Supporting files from before bug 1363725
 }
 
 SUPPORTED_PRODUCTS = {
     'firefox': 'Firefox',
     'fennec': 'Fennec',
     'geckoview': 'Geckoview',
--- a/toolkit/components/telemetry/core/Telemetry.cpp
+++ b/toolkit/components/telemetry/core/Telemetry.cpp
@@ -1157,17 +1157,18 @@ TelemetryImpl::GetIsOfficialTelemetry(bo
 }
 
 already_AddRefed<nsITelemetry> TelemetryImpl::CreateTelemetryInstance() {
   MOZ_ASSERT(
       sTelemetry == nullptr,
       "CreateTelemetryInstance may only be called once, via GetService()");
 
   bool useTelemetry = false;
-  if ((XRE_IsParentProcess() || XRE_IsContentProcess() || XRE_IsGPUProcess()) &&
+  if ((XRE_IsParentProcess() || XRE_IsContentProcess() || XRE_IsGPUProcess() ||
+       XRE_IsSocketProcess()) &&
       // Telemetry is never accumulated when recording or replaying, both
       // because the resulting measurements might be biased and because
       // measurements might occur at non-deterministic points in execution
       // (e.g. garbage collections).
       !recordreplay::IsRecordingOrReplaying()) {
     useTelemetry = true;
   }
 
--- a/toolkit/components/telemetry/core/TelemetryCommon.h
+++ b/toolkit/components/telemetry/core/TelemetryCommon.h
@@ -15,22 +15,23 @@
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace Telemetry {
 namespace Common {
 
 typedef nsTHashtable<nsCStringHashKey> StringHashSet;
 
-enum class RecordedProcessType : uint8_t {
+enum class RecordedProcessType : uint16_t {
   Main = (1 << GeckoProcessType_Default),  // Also known as "parent process"
   Content = (1 << GeckoProcessType_Content),
   Gpu = (1 << GeckoProcessType_GPU),
-  AllChildren = 0xFF - 1,  // All the child processes (i.e. content, gpu, ...)
-  All = 0xFF               // All the processes
+  Socket = (1 << GeckoProcessType_Socket),
+  AllChildren = 0xFFFF - 1,  // All the child processes (i.e. content, gpu, ...)
+  All = 0xFFFF               // All the processes
 };
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(RecordedProcessType);
 
 enum class SupportedProduct : uint8_t {
   Firefox = (1 << 0),
   Fennec = (1 << 1),
   Geckoview = (1 << 2),
   All = 0xFF  // All the products
--- a/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp
+++ b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp
@@ -6,16 +6,17 @@
 
 #include "TelemetryIPCAccumulator.h"
 
 #include "core/TelemetryHistogram.h"
 #include "core/TelemetryScalar.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/gfx/GPUParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
+#include "mozilla/net/SocketProcessChild.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/SystemGroup.h"
 #include "mozilla/Unused.h"
 #include "nsComponentManagerUtils.h"
 #include "nsITimer.h"
 #include "nsThreadUtils.h"
 
@@ -322,16 +323,19 @@ void TelemetryIPCAccumulator::IPCTimerFi
   // Send accumulated data to the correct parent process.
   switch (XRE_GetProcessType()) {
     case GeckoProcessType_Content:
       SendAccumulatedData(mozilla::dom::ContentChild::GetSingleton());
       break;
     case GeckoProcessType_GPU:
       SendAccumulatedData(mozilla::gfx::GPUParent::GetSingleton());
       break;
+    case GeckoProcessType_Socket:
+      SendAccumulatedData(mozilla::net::SocketProcessChild::GetSingleton());
+      break;
     default:
       MOZ_ASSERT_UNREACHABLE("Unsupported process type");
       break;
   }
 
   gIPCTimerArmed = false;
 }
 
--- a/toolkit/components/telemetry/pings/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/pings/TelemetrySession.jsm
@@ -918,22 +918,29 @@ var Impl = {
       scalars: protect(() => this.getScalars(isSubsession, clearSubsession), {}),
       keyedScalars: protect(() => this.getScalars(isSubsession, clearSubsession, true), {}),
     };
 
     let measurementsContainGPU = Object
       .keys(measurements)
       .some(key => "gpu" in measurements[key]);
 
+    let measurementsContainSocket = Object
+      .keys(measurements)
+      .some(key => "socket" in measurements[key]);
+
     payloadObj.processes = {};
     let processTypes = ["parent", "content", "extension", "dynamic"];
     // Only include the GPU process if we've accumulated data for it.
     if (measurementsContainGPU) {
       processTypes.push("gpu");
     }
+    if (measurementsContainSocket) {
+      processTypes.push("socket");
+    }
 
     // Collect per-process measurements.
     for (const processType of processTypes) {
       let processPayload = {};
 
       for (const key in measurements) {
         let payloadLoc = processPayload;
         // Parent histograms are added to the top-level payload object instead of the process payload.
--- a/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py
+++ b/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py
@@ -16,17 +16,17 @@ sys.path.append(path.join(TELEMETRY_ROOT
 from mozparsers.shared_telemetry_utils import ParserError
 from mozparsers import parse_histograms
 
 
 class TestParser(unittest.TestCase):
     def test_valid_histogram(self):
         SAMPLE_HISTOGRAM = {
             "TEST_VALID_HISTOGRAM": {
-                "record_in_processes": ["main", "content"],
+                "record_in_processes": ["main", "content", "socket"],
                 "alert_emails": ["team@mozilla.xyz"],
                 "bug_numbers": [1383793],
                 "expires_in_version": "never",
                 "kind": "boolean",
                 "description": "Test histogram"
             }
         }
         histograms = load_histogram(SAMPLE_HISTOGRAM)