Bug 1278556 - Enable child process scalar recording. r=chutten, f=gfritzsche,froydnj

MozReview-Commit-ID: IddrszBX0f5
This commit is contained in:
Alessio Placitelli 2017-01-16 05:12:00 +01:00
Родитель 23dbcfc1a4
Коммит 932126d970
14 изменённых файлов: 1017 добавлений и 179 удалений

Просмотреть файл

@ -4765,6 +4765,22 @@ ContentParent::RecvAccumulateChildKeyedHistogram(
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvUpdateChildScalars(
InfallibleTArray<ScalarAction>&& aScalarActions)
{
Telemetry::UpdateChildScalars(GeckoProcessType_Content, aScalarActions);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvUpdateChildKeyedScalars(
InfallibleTArray<KeyedScalarAction>&& aScalarActions)
{
Telemetry::UpdateChildKeyedScalars(GeckoProcessType_Content, aScalarActions);
return IPC_OK();
}
PURLClassifierParent*
ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal,
const bool& aUseTrackingProtection,

Просмотреть файл

@ -1082,6 +1082,10 @@ private:
InfallibleTArray<Accumulation>&& aAccumulations) override;
virtual mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistogram(
InfallibleTArray<KeyedAccumulation>&& aAccumulations) override;
virtual mozilla::ipc::IPCResult RecvUpdateChildScalars(
InfallibleTArray<ScalarAction>&& aScalarActions) override;
virtual mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(
InfallibleTArray<KeyedScalarAction>&& aScalarActions) override;
public:
void SendGetFilesResponseAndForget(const nsID& aID,
const GetFilesResponseResult& aResult);

Просмотреть файл

@ -95,6 +95,8 @@ using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/Comp
using struct mozilla::dom::FlyWebPublishOptions from "mozilla/dom/FlyWebPublishOptionsIPCSerializer.h";
using mozilla::Telemetry::Accumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
union ChromeRegistryItem
{
@ -1150,6 +1152,8 @@ parent:
*/
async AccumulateChildHistogram(Accumulation[] accumulations);
async AccumulateChildKeyedHistogram(KeyedAccumulation[] accumulations);
async UpdateChildScalars(ScalarAction[] updates);
async UpdateChildKeyedScalars(KeyedScalarAction[] updates);
sync GetA11yContentId() returns (uint32_t aContentId);

Просмотреть файл

@ -153,6 +153,20 @@ GPUChild::RecvAccumulateChildKeyedHistogram(InfallibleTArray<KeyedAccumulation>&
return IPC_OK();
}
mozilla::ipc::IPCResult
GPUChild::RecvUpdateChildScalars(InfallibleTArray<ScalarAction>&& aScalarActions)
{
Telemetry::UpdateChildScalars(GeckoProcessType_GPU, aScalarActions);
return IPC_OK();
}
mozilla::ipc::IPCResult
GPUChild::RecvUpdateChildKeyedScalars(InfallibleTArray<KeyedScalarAction>&& aScalarActions)
{
Telemetry::UpdateChildKeyedScalars(GeckoProcessType_GPU, aScalarActions);
return IPC_OK();
}
mozilla::ipc::IPCResult
GPUChild::RecvNotifyDeviceReset()
{

Просмотреть файл

@ -40,6 +40,8 @@ public:
mozilla::ipc::IPCResult RecvInitCrashReporter(Shmem&& shmem) override;
mozilla::ipc::IPCResult RecvAccumulateChildHistogram(InfallibleTArray<Accumulation>&& aAccumulations) override;
mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistogram(InfallibleTArray<KeyedAccumulation>&& aAccumulations) override;
mozilla::ipc::IPCResult RecvUpdateChildScalars(InfallibleTArray<ScalarAction>&& aScalarActions) override;
mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(InfallibleTArray<KeyedScalarAction>&& aScalarActions) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvGraphicsError(const nsCString& aError) override;
mozilla::ipc::IPCResult RecvNotifyUiObservers(const nsCString& aTopic) override;

Просмотреть файл

@ -17,6 +17,8 @@ using mozilla::gfx::IntSize from "mozilla/gfx/2D.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
using mozilla::Telemetry::Accumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
namespace mozilla {
namespace gfx {
@ -101,6 +103,8 @@ child:
// Messages for reporting telemetry to the UI process.
async AccumulateChildHistogram(Accumulation[] accumulations);
async AccumulateChildKeyedHistogram(KeyedAccumulation[] accumulations);
async UpdateChildScalars(ScalarAction[] actions);
async UpdateChildKeyedScalars(KeyedScalarAction[] actions);
async NotifyDeviceReset();
};

Просмотреть файл

@ -2132,9 +2132,7 @@ TelemetryImpl::CreateTelemetryInstance()
// First, initialize the TelemetryHistogram and TelemetryScalar global states.
TelemetryHistogram::InitializeGlobalState(useTelemetry, useTelemetry);
// Only record scalars from the parent process.
TelemetryScalar::InitializeGlobalState(XRE_IsParentProcess(), XRE_IsParentProcess());
TelemetryScalar::InitializeGlobalState(useTelemetry, useTelemetry);
// Only record events from the parent process.
TelemetryEvent::InitializeGlobalState(XRE_IsParentProcess(), XRE_IsParentProcess());
@ -3107,6 +3105,20 @@ AccumulateChildKeyed(GeckoProcessType aProcessType,
TelemetryHistogram::AccumulateChildKeyed(aProcessType, aAccumulations);
}
void
UpdateChildScalars(GeckoProcessType aProcessType,
const nsTArray<ScalarAction>& aScalarActions)
{
TelemetryScalar::UpdateChildData(aProcessType, aScalarActions);
}
void
UpdateChildKeyedScalars(GeckoProcessType aProcessType,
const nsTArray<KeyedScalarAction>& aScalarActions)
{
TelemetryScalar::UpdateChildKeyedData(aProcessType, aScalarActions);
}
const char*
GetHistogramName(ID id)
{

Просмотреть файл

@ -36,6 +36,8 @@ namespace Telemetry {
struct Accumulation;
struct KeyedAccumulation;
struct ScalarAction;
struct KeyedScalarAction;
enum TimerResolution {
Millisecond,
@ -143,6 +145,20 @@ void AccumulateChild(GeckoProcessType aProcessType, const nsTArray<Accumulation>
*/
void AccumulateChildKeyed(GeckoProcessType aProcessType, const nsTArray<KeyedAccumulation>& aAccumulations);
/**
* Update scalars for the given process type with the data coming from child process.
*
* @param aScalarActions - actions to update the scalar data
*/
void UpdateChildScalars(GeckoProcessType aProcessType, const nsTArray<ScalarAction>& aScalarActions);
/**
* Update keyed scalars for the given process type with the data coming from child process.
*
* @param aScalarActions - actions to update the keyed scalar data
*/
void UpdateChildKeyedScalars(GeckoProcessType aProcessType, const nsTArray<KeyedScalarAction>& aScalarActions);
/**
* Enable/disable recording for this histogram at runtime.
* Recording is enabled by default, unless listed at kRecordingInitiallyDisabledIDs[].

Просмотреть файл

@ -7,10 +7,13 @@
#define Telemetry_Comms_h__
#include "ipc/IPCMessageUtils.h"
#include "nsITelemetry.h"
#include "nsVariant.h"
namespace mozilla {
namespace Telemetry {
// Histogram accumulation types.
enum ID : uint32_t;
struct Accumulation
@ -26,6 +29,32 @@ struct KeyedAccumulation
nsCString mKey;
};
// Scalar accumulation types.
enum class ScalarID : uint32_t;
enum class ScalarActionType : uint32_t {
eSet = 0,
eAdd = 1,
eSetMaximum = 2
};
struct ScalarAction
{
ScalarID mId;
uint32_t mScalarType;
ScalarActionType mActionType;
nsCOMPtr<nsIVariant> mData;
};
struct KeyedScalarAction
{
ScalarID mId;
uint32_t mScalarType;
ScalarActionType mActionType;
nsCString mKey;
nsCOMPtr<nsIVariant> mData;
};
} // namespace Telemetry
} // namespace mozilla
@ -79,6 +108,217 @@ ParamTraits<mozilla::Telemetry::KeyedAccumulation>
}
};
/**
* IPC scalar data message serialization and de-serialization.
*/
template<>
struct
ParamTraits<mozilla::Telemetry::ScalarAction>
{
typedef mozilla::Telemetry::ScalarAction paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
// Write the message type
aMsg->WriteUInt32(static_cast<uint32_t>(aParam.mId));
WriteParam(aMsg, aParam.mScalarType);
WriteParam(aMsg, static_cast<uint32_t>(aParam.mActionType));
switch(aParam.mScalarType) {
case nsITelemetry::SCALAR_COUNT:
{
uint32_t val = 0;
nsresult rv = aParam.mData->GetAsUint32(&val);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Count Scalar unable to convert variant to bool from child process.");
return;
}
WriteParam(aMsg, val);
break;
}
case nsITelemetry::SCALAR_STRING:
{
nsString val;
nsresult rv = aParam.mData->GetAsAString(val);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Conversion failed.");
return;
}
WriteParam(aMsg, val);
break;
}
case nsITelemetry::SCALAR_BOOLEAN:
{
bool val = 0;
nsresult rv = aParam.mData->GetAsBool(&val);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Boolean Scalar unable to convert variant to bool from child process.");
return;
}
WriteParam(aMsg, val);
break;
}
default:
MOZ_ASSERT(false, "Unknown scalar type.");
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
// Read the scalar ID and the scalar type.
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
!ReadParam(aMsg, aIter, &(aResult->mScalarType)) ||
!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->mActionType)))) {
return false;
}
// De-serialize the data based on the scalar type.
nsCOMPtr<nsIWritableVariant> outVar(new nsVariant());
switch (aResult->mScalarType)
{
case nsITelemetry::SCALAR_COUNT:
{
uint32_t data = 0;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data) ||
NS_FAILED(outVar->SetAsUint32(data))) {
return false;
}
break;
}
case nsITelemetry::SCALAR_STRING:
{
nsString data;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data) ||
NS_FAILED(outVar->SetAsAString(data))) {
return false;
}
break;
}
case nsITelemetry::SCALAR_BOOLEAN:
{
bool data = false;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data) ||
NS_FAILED(outVar->SetAsBool(data))) {
return false;
}
break;
}
default:
MOZ_ASSERT(false, "Unknown scalar type.");
return false;
}
aResult->mData = outVar.forget();
return true;
}
};
/**
* IPC keyed scalar data message serialization and de-serialization.
*/
template<>
struct
ParamTraits<mozilla::Telemetry::KeyedScalarAction>
{
typedef mozilla::Telemetry::KeyedScalarAction paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
// Write the message type
aMsg->WriteUInt32(static_cast<uint32_t>(aParam.mId));
WriteParam(aMsg, aParam.mScalarType);
WriteParam(aMsg, static_cast<uint32_t>(aParam.mActionType));
WriteParam(aMsg, aParam.mKey);
switch(aParam.mScalarType) {
case nsITelemetry::SCALAR_COUNT:
{
uint32_t val = 0;
nsresult rv = aParam.mData->GetAsUint32(&val);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Keyed Count Scalar unable to convert variant to uint from child process.");
return;
}
WriteParam(aMsg, val);
break;
}
case nsITelemetry::SCALAR_STRING:
{
// Keyed string scalars are not supported.
MOZ_ASSERT(false, "Keyed String Scalar unable to be write from child process. Not supported.");
break;
}
case nsITelemetry::SCALAR_BOOLEAN:
{
bool val = 0;
nsresult rv = aParam.mData->GetAsBool(&val);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Keyed Boolean Scalar unable to convert variant to bool from child process.");
return;
}
WriteParam(aMsg, val);
break;
}
default:
MOZ_ASSERT(false, "Unknown keyed scalar type.");
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
// Read the scalar ID and the scalar type.
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
!ReadParam(aMsg, aIter, &(aResult->mScalarType)) ||
!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->mActionType))) ||
!ReadParam(aMsg, aIter, &(aResult->mKey))) {
return false;
}
// De-serialize the data based on the scalar type.
nsCOMPtr<nsIWritableVariant> outVar(new nsVariant());
switch (aResult->mScalarType)
{
case nsITelemetry::SCALAR_COUNT:
{
uint32_t data = 0;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data) ||
NS_FAILED(outVar->SetAsUint32(data))) {
return false;
}
break;
}
case nsITelemetry::SCALAR_STRING:
{
// Keyed string scalars are not supported.
MOZ_ASSERT(false, "Keyed String Scalar unable to be read from child process. Not supported.");
return false;
}
case nsITelemetry::SCALAR_BOOLEAN:
{
bool data = false;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data) ||
NS_FAILED(outVar->SetAsBool(data))) {
return false;
}
break;
}
default:
MOZ_ASSERT(false, "Unknown keyed scalar type.");
return false;
}
aResult->mData = outVar.forget();
return true;
}
};
} // namespace IPC
#endif // Telemetry_Comms_h__

Просмотреть файл

@ -16,12 +16,16 @@
#include "nsITimer.h"
#include "nsThreadUtils.h"
#include "TelemetryHistogram.h"
#include "TelemetryScalar.h"
using mozilla::StaticMutex;
using mozilla::StaticMutexAutoLock;
using mozilla::StaticAutoPtr;
using mozilla::Telemetry::Accumulation;
using mozilla::Telemetry::KeyedAccumulation;
using mozilla::Telemetry::ScalarActionType;
using mozilla::Telemetry::ScalarAction;
using mozilla::Telemetry::KeyedScalarAction;
// Sending each remote accumulation immediately places undue strain on the
// IPC subsystem. Batch the remote accumulations for a period of time before
@ -42,6 +46,8 @@ mozilla::Atomic<bool, mozilla::Relaxed> gIPCTimerArming(false);
// For batching and sending child process accumulations to the parent
StaticAutoPtr<nsTArray<Accumulation>> gHistogramAccumulations;
StaticAutoPtr<nsTArray<KeyedAccumulation>> gKeyedHistogramAccumulations;
StaticAutoPtr<nsTArray<ScalarAction>> gChildScalarsActions;
StaticAutoPtr<nsTArray<KeyedScalarAction>> gChildKeyedScalarsActions;
// This is a StaticMutex rather than a plain Mutex so that (1)
// it gets initialised in a thread-safe manner the first time
@ -127,6 +133,36 @@ TelemetryIPCAccumulator::AccumulateChildKeyedHistogram(mozilla::Telemetry::ID aI
ArmIPCTimer(locker);
}
void
TelemetryIPCAccumulator::RecordChildScalarAction(mozilla::Telemetry::ScalarID aId, uint32_t aKind,
ScalarActionType aAction, nsIVariant* aValue)
{
StaticMutexAutoLock locker(gTelemetryIPCAccumulatorMutex);
// Make sure to have the storage.
if (!gChildScalarsActions) {
gChildScalarsActions = new nsTArray<ScalarAction>();
}
// Store the action.
gChildScalarsActions->AppendElement(ScalarAction{aId, aKind, aAction, aValue});
ArmIPCTimer(locker);
}
void
TelemetryIPCAccumulator::RecordChildKeyedScalarAction(mozilla::Telemetry::ScalarID aId,
const nsAString& aKey, uint32_t aKind,
ScalarActionType aAction, nsIVariant* aValue)
{
StaticMutexAutoLock locker(gTelemetryIPCAccumulatorMutex);
// Make sure to have the storage.
if (!gChildKeyedScalarsActions) {
gChildKeyedScalarsActions = new nsTArray<KeyedScalarAction>();
}
// Store the action.
gChildKeyedScalarsActions->AppendElement(
KeyedScalarAction{aId, aKind, aAction, NS_ConvertUTF16toUTF8(aKey), aValue});
ArmIPCTimer(locker);
}
// This method takes the lock only to double-buffer the batched telemetry.
// It releases the lock before calling out to IPC code which can (and does)
// Accumulate (which would deadlock)
@ -143,6 +179,8 @@ TelemetryIPCAccumulator::IPCTimerFired(nsITimer* aTimer, void* aClosure)
// Get the accumulated data and free the storage buffer.
nsTArray<Accumulation> accumulationsToSend;
nsTArray<KeyedAccumulation> keyedAccumulationsToSend;
nsTArray<ScalarAction> scalarsToSend;
nsTArray<KeyedScalarAction> keyedScalarsToSend;
{
StaticMutexAutoLock locker(gTelemetryIPCAccumulatorMutex);
if (gHistogramAccumulations) {
@ -151,6 +189,13 @@ TelemetryIPCAccumulator::IPCTimerFired(nsITimer* aTimer, void* aClosure)
if (gKeyedHistogramAccumulations) {
keyedAccumulationsToSend.SwapElements(*gKeyedHistogramAccumulations);
}
// Copy the scalar actions.
if (gChildScalarsActions) {
scalarsToSend.SwapElements(*gChildScalarsActions);
}
if (gChildKeyedScalarsActions) {
keyedScalarsToSend.SwapElements(*gChildKeyedScalarsActions);
}
}
// Send the accumulated data to the parent process.
@ -167,6 +212,14 @@ TelemetryIPCAccumulator::IPCTimerFired(nsITimer* aTimer, void* aClosure)
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendAccumulateChildKeyedHistogram(keyedAccumulationsToSend));
}
if (scalarsToSend.Length()) {
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendUpdateChildScalars(scalarsToSend));
}
if (keyedScalarsToSend.Length()) {
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendUpdateChildKeyedScalars(keyedScalarsToSend));
}
}
break;
}
@ -178,6 +231,12 @@ TelemetryIPCAccumulator::IPCTimerFired(nsITimer* aTimer, void* aClosure)
if (keyedAccumulationsToSend.Length()) {
mozilla::Unused << gpu->SendAccumulateChildKeyedHistogram(keyedAccumulationsToSend);
}
if (scalarsToSend.Length()) {
mozilla::Unused << gpu->SendUpdateChildScalars(scalarsToSend);
}
if (keyedScalarsToSend.Length()) {
mozilla::Unused << gpu->SendUpdateChildKeyedScalars(keyedScalarsToSend);
}
}
break;
}
@ -199,6 +258,8 @@ TelemetryIPCAccumulator::DeInitializeGlobalState()
gHistogramAccumulations = nullptr;
gKeyedHistogramAccumulations = nullptr;
gChildScalarsActions = nullptr;
gChildKeyedScalarsActions = nullptr;
}
void

Просмотреть файл

@ -10,12 +10,16 @@
class nsIRunnable;
class nsITimer;
class nsAString;
class nsCString;
class nsIVariant;
namespace mozilla {
namespace Telemetry {
enum ID : uint32_t;
enum class ScalarID : uint32_t;
enum class ScalarActionType : uint32_t;
} // Telemetry
} // mozilla
@ -27,6 +31,14 @@ void AccumulateChildHistogram(mozilla::Telemetry::ID aId, uint32_t aSample);
void AccumulateChildKeyedHistogram(mozilla::Telemetry::ID aId, const nsCString& aKey,
uint32_t aSample);
// Scalar accumulation functions.
void RecordChildScalarAction(mozilla::Telemetry::ScalarID aId, uint32_t aKind,
mozilla::Telemetry::ScalarActionType aAction, nsIVariant* aValue);
void RecordChildKeyedScalarAction(mozilla::Telemetry::ScalarID aId, const nsAString& aKey,
uint32_t aKind, mozilla::Telemetry::ScalarActionType aAction,
nsIVariant* aValue);
void IPCTimerFired(nsITimer* aTimer, void* aClosure);
void DeInitializeGlobalState();

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -59,6 +59,12 @@ void ClearScalars();
size_t GetMapShallowSizesOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
size_t GetScalarSizesOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
void UpdateChildData(GeckoProcessType aProcessType,
const nsTArray<mozilla::Telemetry::ScalarAction>& aScalarActions);
void UpdateChildKeyedData(GeckoProcessType aProcessType,
const nsTArray<mozilla::Telemetry::KeyedScalarAction>& aScalarActions);
} // namespace TelemetryScalar
#endif // TelemetryScalar_h__

Просмотреть файл

@ -410,7 +410,7 @@ interface nsITelemetry : nsISupports
/**
* Serializes the scalars from the given dataset to a JSON-style object and resets them.
* The returned structure looks like:
* { "group1.probe": 1, "group1.other_probe": false, ... }
* {"process": {"group1.probe":1,"group1.other_probe":false,...}, ... }.
*
* @param aDataset DATASET_RELEASE_CHANNEL_OPTOUT or DATASET_RELEASE_CHANNEL_OPTIN.
* @param [aClear=false] Whether to clear out the scalars after snapshotting.
@ -453,7 +453,7 @@ interface nsITelemetry : nsISupports
* Serializes the keyed scalars from the given dataset to a JSON-style object and
* resets them.
* The returned structure looks like:
* { "group1.probe": { "key_1": 2, "key_2": 1, ... }, ... }
* { "process": { "group1.probe": { "key_1": 2, "key_2": 1, ... }, ... }, ... }
*
* @param aDataset DATASET_RELEASE_CHANNEL_OPTOUT or DATASET_RELEASE_CHANNEL_OPTIN.
* @param [aClear=false] Whether to clear out the scalars after snapshotting.