Backed out changeset ab64c55508aa (bug 1302663)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 12 Nov 2016 21:17:36 +0100
changeset 352394 215e84d751786dcf690f1a7511aa9806b2dc9a0b
parent 352393 f20e3b45a15660fe9d5d719f33ec73178f9d0602
child 352395 557a7e72a15086747793eb5dd0642c4f149b0937
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1302663
milestone52.0a1
backs outab64c55508aabf1af5063cda3322c526c67422ad
Backed out changeset ab64c55508aa (bug 1302663)
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryCommon.cpp
toolkit/components/telemetry/TelemetryCommon.h
toolkit/components/telemetry/TelemetryEvent.cpp
toolkit/components/telemetry/TelemetryEvent.h
toolkit/components/telemetry/TelemetryScalar.cpp
toolkit/components/telemetry/moz.build
toolkit/components/telemetry/nsITelemetry.idl
toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
toolkit/components/telemetry/tests/unit/xpcshell.ini
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -39,17 +39,16 @@
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIMemoryReporter.h"
 #include "nsISeekableStream.h"
 #include "Telemetry.h"
 #include "TelemetryCommon.h"
 #include "TelemetryHistogram.h"
 #include "TelemetryScalar.h"
-#include "TelemetryEvent.h"
 #include "WebrtcTelemetry.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsBaseHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsXULAppAPI.h"
 #include "nsReadableUtils.h"
 #include "nsThreadUtils.h"
@@ -1858,17 +1857,16 @@ TelemetryImpl::GetCanRecordBase(bool *re
   *ret = TelemetryHistogram::CanRecordBase();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::SetCanRecordBase(bool canRecord) {
   TelemetryHistogram::SetCanRecordBase(canRecord);
   TelemetryScalar::SetCanRecordBase(canRecord);
-  TelemetryEvent::SetCanRecordBase(canRecord);
   return NS_OK;
 }
 
 /**
  * Indicates if Telemetry is allowed to record extended data. Returns false if the user
  * hasn't opted into "extended Telemetry" on the Release channel, when the user has
  * explicitly opted out of Telemetry on Nightly/Aurora/Beta or if manually set to false
  * during tests.
@@ -1879,17 +1877,16 @@ TelemetryImpl::GetCanRecordExtended(bool
   *ret = TelemetryHistogram::CanRecordExtended();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::SetCanRecordExtended(bool canRecord) {
   TelemetryHistogram::SetCanRecordExtended(canRecord);
   TelemetryScalar::SetCanRecordExtended(canRecord);
-  TelemetryEvent::SetCanRecordExtended(canRecord);
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 TelemetryImpl::GetIsOfficialTelemetry(bool *ret) {
 #if defined(MOZILLA_OFFICIAL) && defined(MOZ_TELEMETRY_REPORTING) && !defined(DEBUG)
   *ret = true;
@@ -1913,19 +1910,16 @@ 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());
 
-  // Only record events from the parent process.
-  TelemetryEvent::InitializeGlobalState(XRE_IsParentProcess(), XRE_IsParentProcess());
-
   // Now, create and initialize the Telemetry global state.
   sTelemetry = new TelemetryImpl();
 
   // AddRef for the local reference
   NS_ADDREF(sTelemetry);
   // AddRef for the caller
   nsCOMPtr<nsITelemetry> ret = sTelemetry;
 
@@ -1941,17 +1935,16 @@ TelemetryImpl::ShutdownTelemetry()
   // No point in collecting IO beyond this point
   ClearIOReporting();
   NS_IF_RELEASE(sTelemetry);
 
   // Lastly, de-initialise the TelemetryHistogram and TelemetryScalar global states,
   // so as to release any heap storage that would otherwise be kept alive by it.
   TelemetryHistogram::DeInitializeGlobalState();
   TelemetryScalar::DeInitializeGlobalState();
-  TelemetryEvent::DeInitializeGlobalState();
 }
 
 void
 TelemetryImpl::StoreSlowSQL(const nsACString &sql, uint32_t delay,
                             SanitizedState state)
 {
   AutoHashtable<SlowSQLEntryType>* slowSQLMap = nullptr;
   if (state == Sanitized)
@@ -2306,17 +2299,23 @@ TelemetryImpl::GetFileIOReports(JSContex
   }
   ret.setNull();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::MsSinceProcessStart(double* aResult)
 {
-  return Telemetry::Common::MsSinceProcessStart(aResult);
+  bool error;
+  *aResult = (TimeStamp::NowLoRes() -
+              TimeStamp::ProcessCreation(error)).ToMilliseconds();
+  if (error) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  return NS_OK;
 }
 
 // Telemetry Scalars IDL Implementation
 
 NS_IMETHODIMP
 TelemetryImpl::ScalarAdd(const nsACString& aName, JS::HandleValue aVal, JSContext* aCx)
 {
   return TelemetryScalar::Add(aName, aVal, aCx);
@@ -2372,41 +2371,16 @@ TelemetryImpl::SnapshotKeyedScalars(unsi
 
 NS_IMETHODIMP
 TelemetryImpl::ClearScalars()
 {
   TelemetryScalar::ClearScalars();
   return NS_OK;
 }
 
-// Telemetry Event IDL implementation.
-
-NS_IMETHODIMP
-TelemetryImpl::RecordEvent(const nsACString & aCategory, const nsACString & aMethod,
-                           const nsACString & aObject, JS::HandleValue aValue,
-                           JS::HandleValue aExtra, JSContext* aCx, uint8_t optional_argc)
-{
-  return TelemetryEvent::RecordEvent(aCategory, aMethod, aObject, aValue, aExtra, aCx, optional_argc);
-}
-
-NS_IMETHODIMP
-TelemetryImpl::SnapshotBuiltinEvents(uint32_t aDataset, bool aClear, JSContext* aCx,
-                                     uint8_t optional_argc, JS::MutableHandleValue aResult)
-{
-  return TelemetryEvent::CreateSnapshots(aDataset, aClear, aCx, optional_argc, aResult);
-}
-
-NS_IMETHODIMP
-TelemetryImpl::ClearEvents()
-{
-  TelemetryEvent::ClearEvents();
-  return NS_OK;
-}
-
-
 NS_IMETHODIMP
 TelemetryImpl::FlushBatchedChildTelemetry()
 {
   TelemetryHistogram::IPCTimerFired(nullptr, nullptr);
   return NS_OK;
 }
 
 size_t
@@ -2435,17 +2409,16 @@ TelemetryImpl::SizeOfIncludingThis(mozil
   // It's a bit gross that we measure this other stuff that lives outside of
   // TelemetryImpl... oh well.
   if (sTelemetryIOObserver) {
     n += sTelemetryIOObserver->SizeOfIncludingThis(aMallocSizeOf);
   }
 
   n += TelemetryHistogram::GetHistogramSizesofIncludingThis(aMallocSizeOf);
   n += TelemetryScalar::GetScalarSizesOfIncludingThis(aMallocSizeOf);
-  n += TelemetryEvent::SizeOfIncludingThis(aMallocSizeOf);
 
   return n;
 }
 
 struct StackFrame
 {
   uintptr_t mPC;      // The program counter at this position in the call stack.
   uint16_t mIndex;    // The number of this frame in the call stack.
--- a/toolkit/components/telemetry/TelemetryCommon.cpp
+++ b/toolkit/components/telemetry/TelemetryCommon.cpp
@@ -1,19 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsITelemetry.h"
 #include "nsVersionComparator.h"
-#include "mozilla/TimeStamp.h"
-#include "nsIConsoleService.h"
-#include "nsThreadUtils.h"
 
 #include "TelemetryCommon.h"
 
 #include <cstring>
 
 namespace mozilla {
 namespace Telemetry {
 namespace Common {
@@ -60,45 +57,11 @@ CanRecordDataset(uint32_t aDataset, bool
       return true;
   }
 
   // We're not recording extended telemetry or this is not the base
   // dataset. Bail out.
   return false;
 }
 
-nsresult
-MsSinceProcessStart(double* aResult)
-{
-  bool error;
-  *aResult = (TimeStamp::NowLoRes() -
-              TimeStamp::ProcessCreation(error)).ToMilliseconds();
-  if (error) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-  return NS_OK;
-}
-
-void
-LogToBrowserConsole(uint32_t aLogLevel, const nsAString& aMsg)
-{
-  if (!NS_IsMainThread()) {
-    nsString msg(aMsg);
-    nsCOMPtr<nsIRunnable> task =
-      NS_NewRunnableFunction([aLogLevel, msg]() { LogToBrowserConsole(aLogLevel, msg); });
-    NS_DispatchToMainThread(task.forget(), NS_DISPATCH_NORMAL);
-    return;
-  }
-
-  nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
-  if (!console) {
-    NS_WARNING("Failed to log message to console.");
-    return;
-  }
-
-  nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
-  error->Init(aMsg, EmptyString(), EmptyString(), 0, 0, aLogLevel, "chrome javascript");
-  console->LogMessage(error);
-}
-
 } // namespace Common
 } // namespace Telemetry
 } // namespace mozilla
--- a/toolkit/components/telemetry/TelemetryCommon.h
+++ b/toolkit/components/telemetry/TelemetryCommon.h
@@ -3,17 +3,16 @@
  * 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/. */
 
 #ifndef TelemetryCommon_h__
 #define TelemetryCommon_h__
 
 #include "nsTHashtable.h"
 #include "jsapi.h"
-#include "nsIScriptError.h"
 
 namespace mozilla {
 namespace Telemetry {
 namespace Common {
 
 template<class EntryType>
 class AutoHashtable : public nsTHashtable<EntryType>
 {
@@ -46,30 +45,13 @@ AutoHashtable<EntryType>::ReflectIntoJS(
   }
   return true;
 }
 
 bool IsExpiredVersion(const char* aExpiration);
 bool IsInDataset(uint32_t aDataset, uint32_t aContainingDataset);
 bool CanRecordDataset(uint32_t aDataset, bool aCanRecordBase, bool aCanRecordExtended);
 
-/**
- * Return the number of milliseconds since process start using monotonic
- * timestamps (unaffected by system clock changes).
- *
- * @return NS_OK on success, NS_ERROR_NOT_AVAILABLE if TimeStamp doesn't have the data.
- */
-nsresult MsSinceProcessStart(double* aResult);
-
-/**
- * Dumps a log message to the Browser Console using the provided level.
- *
- * @param aLogLevel The level to use when displaying the message in the browser console
- *        (e.g. nsIScriptError::warningFlag, ...).
- * @param aMsg The text message to print to the console.
- */
-void LogToBrowserConsole(uint32_t aLogLevel, const nsAString& aMsg);
-
 } // namespace Common
 } // namespace Telemetry
 } // namespace mozilla
 
 #endif // TelemetryCommon_h__
deleted file mode 100644
--- a/toolkit/components/telemetry/TelemetryEvent.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 <prtime.h>
-#include "nsITelemetry.h"
-#include "nsHashKeys.h"
-#include "nsDataHashtable.h"
-#include "nsClassHashtable.h"
-#include "nsTArray.h"
-#include "mozilla/StaticMutex.h"
-#include "mozilla/Unused.h"
-#include "mozilla/Maybe.h"
-#include "jsapi.h"
-#include "nsJSUtils.h"
-#include "nsXULAppAPI.h"
-#include "nsUTF8Utils.h"
-
-#include "TelemetryCommon.h"
-#include "TelemetryEvent.h"
-#include "TelemetryEventData.h"
-
-using mozilla::StaticMutex;
-using mozilla::StaticMutexAutoLock;
-using mozilla::ArrayLength;
-using mozilla::Maybe;
-using mozilla::Nothing;
-using mozilla::Pair;
-using mozilla::Telemetry::Common::AutoHashtable;
-using mozilla::Telemetry::Common::IsExpiredVersion;
-using mozilla::Telemetry::Common::CanRecordDataset;
-using mozilla::Telemetry::Common::IsInDataset;
-using mozilla::Telemetry::Common::MsSinceProcessStart;
-using mozilla::Telemetry::Common::LogToBrowserConsole;
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// Naming: there are two kinds of functions in this file:
-//
-// * Functions taking a StaticMutexAutoLock: these can only be reached via
-//   an interface function (TelemetryEvent::*). They expect the interface
-//   function to have acquired |gTelemetryEventsMutex|, so they do not
-//   have to be thread-safe.
-//
-// * Functions named TelemetryEvent::*. This is the external interface.
-//   Entries and exits to these functions are serialised using
-//   |gTelemetryEventsMutex|.
-//
-// Avoiding races and deadlocks:
-//
-// All functions in the external interface (TelemetryEvent::*) are
-// serialised using the mutex |gTelemetryEventsMutex|. This means
-// that the external interface is thread-safe, and the internal
-// functions can ignore thread safety. But it also brings a danger
-// of deadlock if any function in the external interface can get back
-// to that interface. That is, we will deadlock on any call chain like
-// this:
-//
-// TelemetryEvent::* -> .. any functions .. -> TelemetryEvent::*
-//
-// To reduce the danger of that happening, observe the following rules:
-//
-// * No function in TelemetryEvent::* may directly call, nor take the
-//   address of, any other function in TelemetryEvent::*.
-//
-// * No internal function may call, nor take the address
-//   of, any function in TelemetryEvent::*.
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// PRIVATE TYPES
-
-namespace {
-
-const uint32_t kEventCount = mozilla::Telemetry::EventID::EventCount;
-// This is a special event id used to mark expired events, to make expiry checks
-// faster at runtime.
-const uint32_t kExpiredEventId = kEventCount + 1;
-static_assert(kEventCount < kExpiredEventId, "Should not overflow.");
-
-// This is the hard upper limit on the number of event records we keep in storage.
-// If we cross this limit, we will drop any further event recording until elements
-// are removed from storage.
-const uint32_t kMaxEventRecords = 10000;
-// Maximum length of any passed value string, in UTF8 byte sequence length.
-const uint32_t kMaxValueByteLength = 100;
-// Maximum length of any string value in the extra dictionary, in UTF8 byte sequence length.
-const uint32_t kMaxExtraValueByteLength = 100;
-
-typedef nsDataHashtable<nsCStringHashKey, uint32_t> EventMapType;
-typedef nsClassHashtable<nsCStringHashKey, nsCString> StringMap;
-
-enum class RecordEventResult {
-  Ok,
-  UnknownEvent,
-  InvalidExtraKey,
-  StorageLimitReached,
-};
-
-struct ExtraEntry {
-  const nsCString key;
-  const nsCString value;
-};
-
-typedef nsTArray<ExtraEntry> ExtraArray;
-
-class EventRecord {
-public:
-  EventRecord(double timestamp, uint32_t eventId, const Maybe<nsCString>& value,
-              const ExtraArray& extra)
-    : mTimestamp(timestamp)
-    , mEventId(eventId)
-    , mValue(value)
-    , mExtra(extra)
-  {}
-
-  EventRecord(const EventRecord& other)
-    : mTimestamp(other.mTimestamp)
-    , mEventId(other.mEventId)
-    , mValue(other.mValue)
-    , mExtra(other.mExtra)
-  {}
-
-  EventRecord& operator=(const EventRecord& other) = delete;
-
-  double Timestamp() const { return mTimestamp; }
-  uint32_t EventId() const { return mEventId; }
-  const Maybe<nsCString>& Value() const { return mValue; }
-  const ExtraArray& Extra() const { return mExtra; }
-
-  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
-
-private:
-  const double mTimestamp;
-  const uint32_t mEventId;
-  const Maybe<nsCString> mValue;
-  const ExtraArray mExtra;
-};
-
-// Implements the methods for EventInfo.
-const char*
-EventInfo::method() const
-{
-  return &gEventsStringTable[this->method_offset];
-}
-
-const char*
-EventInfo::object() const
-{
-  return &gEventsStringTable[this->object_offset];
-}
-
-// Implements the methods for CommonEventInfo.
-const char*
-CommonEventInfo::category() const
-{
-  return &gEventsStringTable[this->category_offset];
-}
-
-const char*
-CommonEventInfo::expiration_version() const
-{
-  return &gEventsStringTable[this->expiration_version_offset];
-}
-
-const char*
-CommonEventInfo::extra_key(uint32_t index) const
-{
-  MOZ_ASSERT(index < this->extra_count);
-  uint32_t key_index = gExtraKeysTable[this->extra_index + index];
-  return &gEventsStringTable[key_index];
-}
-
-// Implementation for the EventRecord class.
-size_t
-EventRecord::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
-{
-  size_t n = 0;
-
-  if (mValue) {
-    n += mValue.value().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-  }
-
-  n += mExtra.ShallowSizeOfExcludingThis(aMallocSizeOf);
-  for (uint32_t i = 0; i < mExtra.Length(); ++i) {
-    n += mExtra[i].key.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-    n += mExtra[i].value.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-  }
-
-  return n;
-}
-
-nsCString
-UniqueEventName(const nsACString& category, const nsACString& method, const nsACString& object)
-{
-  nsCString name;
-  name.Append(category);
-  name.AppendLiteral("#");
-  name.Append(method);
-  name.AppendLiteral("#");
-  name.Append(object);
-  return name;
-}
-
-nsCString
-UniqueEventName(const EventInfo& info)
-{
-  return UniqueEventName(nsDependentCString(info.common_info.category()),
-                         nsDependentCString(info.method()),
-                         nsDependentCString(info.object()));
-}
-
-bool
-IsExpiredDate(uint32_t expires_days_since_epoch) {
-  if (expires_days_since_epoch == 0) {
-    return false;
-  }
-
-  const uint32_t days_since_epoch = PR_Now() / (PRTime(PR_USEC_PER_SEC) * 24 * 60 * 60);
-  return expires_days_since_epoch <= days_since_epoch;
-}
-
-void
-TruncateToByteLength(nsCString& str, uint32_t length)
-{
-  // last will be the index of the first byte of the current multi-byte sequence.
-  uint32_t last = RewindToPriorUTF8Codepoint(str.get(), length);
-  str.Truncate(last);
-}
-
-} // anonymous namespace
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// PRIVATE STATE, SHARED BY ALL THREADS
-
-namespace {
-
-// Set to true once this global state has been initialized.
-bool gInitDone = false;
-
-bool gCanRecordBase;
-bool gCanRecordExtended;
-
-// The Name -> ID cache map.
-EventMapType gEventNameIDMap(kEventCount);
-
-// The main event storage. Events are inserted here in recording order.
-nsTArray<EventRecord> gEventRecords;
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// PRIVATE: thread-unsafe helpers for event recording.
-
-namespace {
-
-bool
-CanRecordEvent(const StaticMutexAutoLock& lock, const CommonEventInfo& info)
-{
-  if (!gCanRecordBase) {
-    return false;
-  }
-
-  return CanRecordDataset(info.dataset, gCanRecordBase, gCanRecordExtended);
-}
-
-RecordEventResult
-RecordEvent(const StaticMutexAutoLock& lock, double timestamp,
-            const nsACString& category, const nsACString& method,
-            const nsACString& object, const Maybe<nsCString>& value,
-            const ExtraArray& extra)
-{
-  // Apply hard limit on event count in storage.
-  if (gEventRecords.Length() >= kMaxEventRecords) {
-    return RecordEventResult::StorageLimitReached;
-  }
-
-  // Look up the event id.
-  const nsCString& name = UniqueEventName(category, method, object);
-  uint32_t eventId;
-  if (!gEventNameIDMap.Get(name, &eventId)) {
-    return RecordEventResult::UnknownEvent;
-  }
-
-  // If the event is expired, silently drop this call.
-  // We don't want recording for expired probes to be an error so code doesn't
-  // have to be removed at a specific time or version.
-  // Even logging warnings would become very noisy.
-  if (eventId == kExpiredEventId) {
-    return RecordEventResult::Ok;
-  }
-
-  // Check whether we can record this event.
-  const CommonEventInfo& common = gEventInfo[eventId].common_info;
-  if (!CanRecordEvent(lock, common)) {
-    return RecordEventResult::Ok;
-  }
-
-  // Check whether the extra keys passed are valid.
-  nsTHashtable<nsCStringHashKey> validExtraKeys;
-  for (uint32_t i = 0; i < common.extra_count; ++i) {
-    validExtraKeys.PutEntry(nsDependentCString(common.extra_key(i)));
-  }
-
-  for (uint32_t i = 0; i < extra.Length(); ++i) {
-    if (!validExtraKeys.GetEntry(extra[i].key)) {
-      return RecordEventResult::InvalidExtraKey;
-    }
-  }
-
-  // Add event record.
-  gEventRecords.AppendElement(EventRecord(timestamp, eventId, value, extra));
-  return RecordEventResult::Ok;
-}
-
-} // anonymous namespace
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// EXTERNALLY VISIBLE FUNCTIONS in namespace TelemetryEvents::
-
-// This is a StaticMutex rather than a plain Mutex (1) so that
-// it gets initialised in a thread-safe manner the first time
-// it is used, and (2) because it is never de-initialised, and
-// a normal Mutex would show up as a leak in BloatView.  StaticMutex
-// also has the "OffTheBooks" property, so it won't show as a leak
-// in BloatView.
-// Another reason to use a StaticMutex instead of a plain Mutex is
-// that, due to the nature of Telemetry, we cannot rely on having a
-// mutex initialized in InitializeGlobalState. Unfortunately, we
-// cannot make sure that no other function is called before this point.
-static StaticMutex gTelemetryEventsMutex;
-
-void
-TelemetryEvent::InitializeGlobalState(bool aCanRecordBase, bool aCanRecordExtended)
-{
-  StaticMutexAutoLock locker(gTelemetryEventsMutex);
-  MOZ_ASSERT(!gInitDone, "TelemetryEvent::InitializeGlobalState "
-             "may only be called once");
-
-  gCanRecordBase = aCanRecordBase;
-  gCanRecordExtended = aCanRecordExtended;
-
-  // Populate the static event name->id cache. Note that the event names are
-  // statically allocated and come from the automatically generated TelemetryEventData.h.
-  const uint32_t eventCount = static_cast<uint32_t>(mozilla::Telemetry::EventID::EventCount);
-  for (uint32_t i = 0; i < eventCount; ++i) {
-    const EventInfo& info = gEventInfo[i];
-    uint32_t eventId = i;
-
-    // If this event is expired, mark it with a special event id.
-    // This avoids doing expensive expiry checks at runtime.
-    if (IsExpiredVersion(info.common_info.expiration_version()) ||
-        IsExpiredDate(info.common_info.expiration_day)) {
-      eventId = kExpiredEventId;
-    }
-
-    gEventNameIDMap.Put(UniqueEventName(info), eventId);
-  }
-
-#ifdef DEBUG
-  gEventNameIDMap.MarkImmutable();
-#endif
-  gInitDone = true;
-}
-
-void
-TelemetryEvent::DeInitializeGlobalState()
-{
-  StaticMutexAutoLock locker(gTelemetryEventsMutex);
-  MOZ_ASSERT(gInitDone);
-
-  gCanRecordBase = false;
-  gCanRecordExtended = false;
-  gInitDone = false;
-}
-
-void
-TelemetryEvent::SetCanRecordBase(bool b)
-{
-  StaticMutexAutoLock locker(gTelemetryEventsMutex);
-  gCanRecordBase = b;
-}
-
-void
-TelemetryEvent::SetCanRecordExtended(bool b) {
-  StaticMutexAutoLock locker(gTelemetryEventsMutex);
-  gCanRecordExtended = b;
-}
-
-nsresult
-TelemetryEvent::RecordEvent(const nsACString& aCategory, const nsACString& aMethod,
-                            const nsACString& aObject, JS::HandleValue aValue,
-                            JS::HandleValue aExtra, JSContext* cx,
-                            uint8_t optional_argc)
-{
-  // Currently only recording in the parent process is supported.
-  if (!XRE_IsParentProcess()) {
-    return NS_OK;
-  }
-
-  // Get the current time.
-  double timestamp = -1;
-  nsresult rv = MsSinceProcessStart(&timestamp);
-  if (NS_FAILED(rv)) {
-    LogToBrowserConsole(nsIScriptError::warningFlag,
-                        NS_LITERAL_STRING("Failed to get time since process start."));
-    return NS_OK;
-  }
-
-  // Check value argument.
-  if ((optional_argc > 0) && !aValue.isNull() && !aValue.isString()) {
-    LogToBrowserConsole(nsIScriptError::warningFlag,
-                        NS_LITERAL_STRING("Invalid type for value parameter."));
-    return NS_OK;
-  }
-
-  // Extract value parameter.
-  Maybe<nsCString> value;
-  if (aValue.isString()) {
-    nsAutoJSString jsStr;
-    if (!jsStr.init(cx, aValue)) {
-      LogToBrowserConsole(nsIScriptError::warningFlag,
-                          NS_LITERAL_STRING("Invalid string value for value parameter."));
-      return NS_OK;
-    }
-
-    nsCString str = NS_ConvertUTF16toUTF8(jsStr);
-    if (str.Length() > kMaxValueByteLength) {
-      LogToBrowserConsole(nsIScriptError::warningFlag,
-                          NS_LITERAL_STRING("Value parameter exceeds maximum string length, truncating."));
-      TruncateToByteLength(str, kMaxValueByteLength);
-    }
-    value = mozilla::Some(str);
-  }
-
-  // Check extra argument.
-  if ((optional_argc > 1) && !aExtra.isNull() && !aExtra.isObject()) {
-    LogToBrowserConsole(nsIScriptError::warningFlag,
-                        NS_LITERAL_STRING("Invalid type for extra parameter."));
-    return NS_OK;
-  }
-
-  // Extract extra dictionary.
-  ExtraArray extra;
-  if (aExtra.isObject()) {
-    JS::RootedObject obj(cx, &aExtra.toObject());
-    JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx));
-    if (!JS_Enumerate(cx, obj, &ids)) {
-      LogToBrowserConsole(nsIScriptError::warningFlag,
-                          NS_LITERAL_STRING("Failed to enumerate object."));
-      return NS_OK;
-    }
-
-    for (size_t i = 0, n = ids.length(); i < n; i++) {
-      nsAutoJSString key;
-      if (!key.init(cx, ids[i])) {
-        LogToBrowserConsole(nsIScriptError::warningFlag,
-                            NS_LITERAL_STRING("Extra dictionary should only contain string keys."));
-        return NS_OK;
-      }
-
-      JS::Rooted<JS::Value> value(cx);
-      if (!JS_GetPropertyById(cx, obj, ids[i], &value)) {
-        LogToBrowserConsole(nsIScriptError::warningFlag,
-                            NS_LITERAL_STRING("Failed to get extra property."));
-        return NS_OK;
-      }
-
-      nsAutoJSString jsStr;
-      if (!value.isString() || !jsStr.init(cx, value)) {
-        LogToBrowserConsole(nsIScriptError::warningFlag,
-                            NS_LITERAL_STRING("Extra properties should have string values."));
-        return NS_OK;
-      }
-
-      nsCString str = NS_ConvertUTF16toUTF8(jsStr);
-      if (str.Length() > kMaxExtraValueByteLength) {
-        LogToBrowserConsole(nsIScriptError::warningFlag,
-                            NS_LITERAL_STRING("Extra value exceeds maximum string length, truncating."));
-        TruncateToByteLength(str, kMaxExtraValueByteLength);
-      }
-
-      extra.AppendElement(ExtraEntry{NS_ConvertUTF16toUTF8(key), str});
-    }
-  }
-
-  // Lock for accessing internal data.
-  // While the lock is being held, no complex calls like JS calls can be made,
-  // as all of these could record Telemetry, which would result in deadlock.
-  RecordEventResult res;
-  {
-    StaticMutexAutoLock lock(gTelemetryEventsMutex);
-    res = ::RecordEvent(lock, timestamp, aCategory, aMethod, aObject, value, extra);
-  }
-
-  // Trigger warnings or errors where needed.
-  switch (res) {
-    case RecordEventResult::UnknownEvent:
-      JS_ReportErrorASCII(cx, "Unknown event.");
-      return NS_ERROR_INVALID_ARG;
-    case RecordEventResult::InvalidExtraKey:
-      LogToBrowserConsole(nsIScriptError::warningFlag,
-                          NS_LITERAL_STRING("Invalid extra key for event."));
-      return NS_OK;
-    case RecordEventResult::StorageLimitReached:
-      LogToBrowserConsole(nsIScriptError::warningFlag,
-                          NS_LITERAL_STRING("Event storage limit reached."));
-      return NS_OK;
-    default:
-      return NS_OK;
-  }
-}
-
-nsresult
-TelemetryEvent::CreateSnapshots(uint32_t aDataset, bool aClear, JSContext* cx,
-                                uint8_t optional_argc, JS::MutableHandleValue aResult)
-{
-  // Extract the events from storage.
-  nsTArray<EventRecord> events;
-  {
-    StaticMutexAutoLock locker(gTelemetryEventsMutex);
-
-    uint32_t len = gEventRecords.Length();
-    for (uint32_t i = 0; i < len; ++i) {
-      const EventRecord& record = gEventRecords[i];
-      const EventInfo& info = gEventInfo[record.EventId()];
-
-      if (IsInDataset(info.common_info.dataset, aDataset)) {
-        events.AppendElement(record);
-      }
-    }
-
-    if (aClear) {
-      gEventRecords.Clear();
-    }
-  }
-
-  // We serialize the events to a JS array.
-  JS::RootedObject eventsArray(cx, JS_NewArrayObject(cx, events.Length()));
-  if (!eventsArray) {
-    return NS_ERROR_FAILURE;
-  }
-
-  for (uint32_t i = 0; i < events.Length(); ++i) {
-    const EventRecord& record = events[i];
-    const EventInfo& info = gEventInfo[record.EventId()];
-
-    // Each entry is an array of the form:
-    // [timestamp, category, method, object, value, extra]
-    JS::RootedObject itemsArray(cx, JS_NewArrayObject(cx, 6));
-    if (!itemsArray) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // Add timestamp.
-    JS::Rooted<JS::Value> val(cx);
-    uint32_t itemIndex = 0;
-    val.setDouble(floor(record.Timestamp()));
-    if (!JS_DefineElement(cx, itemsArray, itemIndex++, val, JSPROP_ENUMERATE)) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // Add category, method, object.
-    const char* strings[] = {
-      info.common_info.category(),
-      info.method(),
-      info.object(),
-    };
-    for (uint32_t s = 0; s < ArrayLength(strings); ++s) {
-      const NS_ConvertUTF8toUTF16 wide(strings[s]);
-      val.setString(JS_NewUCStringCopyN(cx, wide.Data(), wide.Length()));
-      if (!JS_DefineElement(cx, itemsArray, itemIndex++, val, JSPROP_ENUMERATE)) {
-        return NS_ERROR_FAILURE;
-      }
-    }
-
-    // Add the optional string value.
-    if (!record.Value()) {
-      val.setNull();
-    } else {
-      const NS_ConvertUTF8toUTF16 wide(record.Value().value());
-      val.setString(JS_NewUCStringCopyN(cx, wide.Data(), wide.Length()));
-    }
-    if (!JS_DefineElement(cx, itemsArray, itemIndex++, val, JSPROP_ENUMERATE)) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // Add the optional extra dictionary.
-    if (record.Extra().IsEmpty()) {
-      val.setNull();
-    } else {
-      JS::RootedObject obj(cx, JS_NewPlainObject(cx));
-      if (!obj) {
-        return NS_ERROR_FAILURE;
-      }
-
-      const ExtraArray& extra = record.Extra();
-      for (uint32_t i = 0; i < extra.Length(); ++i) {
-        const NS_ConvertUTF8toUTF16 wide(extra[i].value);
-        JS::Rooted<JS::Value> value(cx);
-        value.setString(JS_NewUCStringCopyN(cx, wide.Data(), wide.Length()));
-
-        if (!JS_DefineProperty(cx, obj, extra[i].key.get(), value, JSPROP_ENUMERATE)) {
-          return NS_ERROR_FAILURE;
-        }
-      }
-      val.setObject(*obj);
-    }
-    if (!JS_DefineElement(cx, itemsArray, itemIndex++, val, JSPROP_ENUMERATE)) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // Add the record to the events array.
-    if (!JS_DefineElement(cx, eventsArray, i, itemsArray, JSPROP_ENUMERATE)) {
-      return NS_ERROR_FAILURE;
-    }
-  }
-
-  aResult.setObject(*eventsArray);
-  return NS_OK;
-}
-
-/**
- * Resets all the stored events. This is intended to be only used in tests.
- */
-void
-TelemetryEvent::ClearEvents()
-{
-  StaticMutexAutoLock lock(gTelemetryEventsMutex);
-  gEventRecords.Clear();
-}
-
-size_t
-TelemetryEvent::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-{
-  StaticMutexAutoLock locker(gTelemetryEventsMutex);
-  size_t n = 0;
-
-  n += gEventRecords.ShallowSizeOfExcludingThis(aMallocSizeOf);
-  for (uint32_t i = 0; i < gEventRecords.Length(); ++i) {
-    n += gEventRecords[i].SizeOfExcludingThis(aMallocSizeOf);
-  }
-
-  n += gEventNameIDMap.ShallowSizeOfExcludingThis(aMallocSizeOf);
-  for (auto iter = gEventNameIDMap.ConstIter(); !iter.Done(); iter.Next()) {
-    n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-  }
-
-  return n;
-}
deleted file mode 100644
--- a/toolkit/components/telemetry/TelemetryEvent.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* 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/. */
-
-#ifndef TelemetryEvent_h__
-#define TelemetryEvent_h__
-
-#include "mozilla/TelemetryEventEnums.h"
-
-// This module is internal to Telemetry. It encapsulates Telemetry's
-// event recording and storage logic. It should only be used by
-// Telemetry.cpp. These functions should not be used anywhere else.
-// For the public interface to Telemetry functionality, see Telemetry.h.
-
-namespace TelemetryEvent {
-
-void InitializeGlobalState(bool canRecordBase, bool canRecordExtended);
-void DeInitializeGlobalState();
-
-void SetCanRecordBase(bool b);
-void SetCanRecordExtended(bool b);
-
-// JS API Endpoints.
-nsresult RecordEvent(const nsACString& aCategory, const nsACString& aMethod,
-                     const nsACString& aObject, JS::HandleValue aValue,
-                     JS::HandleValue aExtra, JSContext* aCx,
-                     uint8_t optional_argc);
-nsresult CreateSnapshots(uint32_t aDataset, bool aClear, JSContext* aCx,
-                         uint8_t optional_argc, JS::MutableHandleValue aResult);
-
-// Only to be used for testing.
-void ClearEvents();
-
-size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
-
-} // namespace TelemetryEvent
-
-#endif // TelemetryEvent_h__
--- a/toolkit/components/telemetry/TelemetryScalar.cpp
+++ b/toolkit/components/telemetry/TelemetryScalar.cpp
@@ -7,31 +7,32 @@
 #include "nsITelemetry.h"
 #include "nsIVariant.h"
 #include "nsVariant.h"
 #include "nsHashKeys.h"
 #include "nsBaseHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsIXPConnect.h"
 #include "nsContentUtils.h"
+#include "nsIConsoleService.h"
+#include "nsIScriptError.h"
 #include "nsThreadUtils.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/Unused.h"
 
 #include "TelemetryCommon.h"
 #include "TelemetryScalar.h"
 #include "TelemetryScalarData.h"
 
 using mozilla::StaticMutex;
 using mozilla::StaticMutexAutoLock;
 using mozilla::Telemetry::Common::AutoHashtable;
 using mozilla::Telemetry::Common::IsExpiredVersion;
 using mozilla::Telemetry::Common::CanRecordDataset;
 using mozilla::Telemetry::Common::IsInDataset;
-using mozilla::Telemetry::Common::LogToBrowserConsole;
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // Naming: there are two kinds of functions in this file:
 //
 // * Functions named internal_*: these can only be reached via an
 //   interface function (TelemetryScalar::*). They expect the interface
@@ -747,16 +748,45 @@ KeyedScalarStorageMapType gKeyedScalarSt
 // back into the TelemetryScalar interface, hence trying to re-acquire the mutex.
 //
 // This means that these functions potentially race against threads, but
 // that seems preferable to risking deadlock.
 
 namespace {
 
 /**
+ * Dumps a log message to the Browser Console using the provided level.
+ *
+ * @param aLogLevel The level to use when displaying the message in the browser console
+ *        (e.g. nsIScriptError::warningFlag, ...).
+ * @param aMsg The text message to print to the console.
+ */
+void
+internal_LogToBrowserConsole(uint32_t aLogLevel, const nsAString& aMsg)
+{
+  if (!NS_IsMainThread()) {
+    nsString msg(aMsg);
+    nsCOMPtr<nsIRunnable> task =
+      NS_NewRunnableFunction([aLogLevel, msg]() { internal_LogToBrowserConsole(aLogLevel, msg); });
+    NS_DispatchToMainThread(task.forget(), NS_DISPATCH_NORMAL);
+    return;
+  }
+
+  nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
+  if (!console) {
+    NS_WARNING("Failed to log message to console.");
+    return;
+  }
+
+  nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+  error->Init(aMsg, EmptyString(), EmptyString(), 0, 0, aLogLevel, "chrome javascript");
+  console->LogMessage(error);
+}
+
+/**
  * Checks if the error should be logged.
  *
  * @param aSr The error code.
  * @return true if the error should be logged, false otherwise.
  */
 bool
 internal_ShouldLogError(ScalarResult aSr)
 {
@@ -806,17 +836,17 @@ internal_LogScalarError(const nsACString
     case ScalarResult::UnsignedTruncatedValue:
       errorMessage.Append(NS_LITERAL_STRING(" - Truncating float/double number."));
       break;
     default:
       // Nothing.
       return;
   }
 
-  LogToBrowserConsole(nsIScriptError::warningFlag, errorMessage);
+  internal_LogToBrowserConsole(nsIScriptError::warningFlag, errorMessage);
 }
 
 } // namespace
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: thread-unsafe helpers for the external interface
--- a/toolkit/components/telemetry/moz.build
+++ b/toolkit/components/telemetry/moz.build
@@ -27,29 +27,27 @@ BROWSER_CHROME_MANIFESTS += ['tests/brow
 
 XPIDL_SOURCES += [
     'nsITelemetry.idl',
 ]
 
 XPIDL_MODULE = 'telemetry'
 
 EXPORTS.mozilla += [
-    '!TelemetryEventEnums.h',
     '!TelemetryHistogramEnums.h',
     '!TelemetryScalarEnums.h',
     'ProcessedStack.h',
     'Telemetry.h',
     'TelemetryComms.h',
     'ThreadHangStats.h',
 ]
 
 SOURCES += [
     'Telemetry.cpp',
     'TelemetryCommon.cpp',
-    'TelemetryEvent.cpp',
     'TelemetryHistogram.cpp',
     'TelemetryScalar.cpp',
     'WebrtcTelemetry.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'TelemetryStartup.js',
     'TelemetryStartup.manifest'
--- a/toolkit/components/telemetry/nsITelemetry.idl
+++ b/toolkit/components/telemetry/nsITelemetry.idl
@@ -326,17 +326,17 @@ interface nsITelemetry : nsISupports
    * arrays of size three, representing startup, normal, and shutdown stages.
    * Each stage's entry is either null or an array with the layout
    * [total_time, #creates, #reads, #writes, #fsyncs, #stats]
    */
   [implicit_jscontext]
   readonly attribute jsval fileIOReports;
 
   /**
-   * Return the number of milliseconds since process start using monotonic
+   * Return the number of seconds since process start using monotonic
    * timestamps (unaffected by system clock changes).
    * @throws NS_ERROR_NOT_AVAILABLE if TimeStamp doesn't have the data.
    */
   double msSinceProcessStart();
 
   /**
    * Adds the value to the given scalar.
    *
@@ -425,45 +425,9 @@ interface nsITelemetry : nsISupports
    */
   void clearScalars();
 
   /**
    * Immediately sends any Telemetry batched on this process to the parent
    * process. This is intended only to be used on process shutdown.
    */
   void flushBatchedChildTelemetry();
-
-  /**
-   * Record an event in Telemetry.
-   *
-   * @param aCategory The category name.
-   * @param aMethod The method name.
-   * @param aMethod The object name.
-   * @param aValue An optional string value to record.
-   * @param aExtra An optional object of the form (string -> string).
-   *               It should only contain registered extra keys.
-   *
-   * @throws NS_ERROR_INVALID_ARG When trying to record an unknown event.
-   */
-  [implicit_jscontext, optional_argc]
-  void recordEvent(in ACString aCategory, in ACString aMethod, in ACString aObject, [optional] in jsval aValue, [optional] in jsval extra);
-
-  /**
-   * Serializes the recorded events to a JSON-appropriate array and optionally resets them.
-   * The returned structure looks like this:
-   *   [
-   *     // [timestamp, category, method, object, stringValue, extraValues]
-   *     [43245, "category1", "method1", "object1", "string value", null],
-   *     [43258, "category1", "method2", "object1", null, {"key1": "string value"}],
-   *     ...
-   *   ]
-   *
-   * @param aDataset DATASET_RELEASE_CHANNEL_OPTOUT or DATASET_RELEASE_CHANNEL_OPTIN.
-   * @param [aClear=false] Whether to clear out the scalars after snapshotting.
-   */
-  [implicit_jscontext, optional_argc]
-  jsval snapshotBuiltinEvents(in uint32_t aDataset, [optional] in boolean aClear);
-
-  /**
-   * Resets all the stored events. This is intended to be only used in tests.
-   */
-  void clearEvents();
 };
deleted file mode 100644
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
+++ /dev/null
@@ -1,232 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/
-*/
-
-const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN;
-const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
-
-function checkEventFormat(events) {
-  Assert.ok(Array.isArray(events), "Events should be serialized to an array.");
-  for (let e of events) {
-    Assert.ok(Array.isArray(e), "Event should be an array.");
-    Assert.equal(e.length, 6, "Event should have 6 elements.");
-
-    Assert.equal(typeof(e[0]), "number", "Element 0 should be a number.");
-    Assert.equal(typeof(e[1]), "string", "Element 1 should be a string.");
-    Assert.equal(typeof(e[2]), "string", "Element 2 should be a string.");
-    Assert.equal(typeof(e[3]), "string", "Element 3 should be a string.");
-
-    Assert.ok(e[4] === null || typeof(e[4]) == "string",
-              "Event element 4 should be null or a string.");
-    Assert.ok(e[5] === null || typeof(e[5]) == "object",
-              "Event element 4 should be null or an object.");
-
-    let extra = e[5];
-    if (extra) {
-      Assert.ok(Object.keys(extra).every(k => typeof(k) == "string"),
-                "All extra keys should be strings.");
-      Assert.ok(Object.values(extra).every(v => typeof(v) == "string"),
-                "All extra values should be strings.");
-    }
-  }
-}
-
-add_task(function* test_recording() {
-  Telemetry.clearEvents();
-
-  // Record some events.
-  let expected = [
-    {optout: false, event: ["telemetry.test", "test1", "object1"]},
-    {optout: false, event: ["telemetry.test", "test2", "object2"]},
-
-    {optout: false, event: ["telemetry.test", "test1", "object1", "value"]},
-    {optout: false, event: ["telemetry.test", "test1", "object1", "value", null]},
-    {optout: false, event: ["telemetry.test", "test1", "object1", null, {"key1": "value1"}]},
-    {optout: false, event: ["telemetry.test", "test1", "object1", "value", {"key1": "value1", "key2": "value2"}]},
-
-    {optout: true,  event: ["telemetry.test", "test_optout", "object1"]},
-    {optout: false, event: ["telemetry.test.second", "test", "object1"]},
-    {optout: false, event: ["telemetry.test.second", "test", "object1", null, {"key1": "value1"}]},
-  ];
-
-  for (let entry of expected) {
-    entry.tsBefore = Math.floor(Telemetry.msSinceProcessStart());
-    try {
-      Telemetry.recordEvent(...entry.event);
-    } catch (ex) {
-      Assert.ok(false, `Failed to record event ${JSON.stringify(entry.event)}: ${ex}`);
-    }
-    entry.tsAfter = Math.floor(Telemetry.msSinceProcessStart());
-  }
-
-  // The following should not result in any recorded events.
-  Assert.throws(() => Telemetry.recordEvent("unknown.category", "test1", "object1"),
-                /Error: Unknown event\./,
-                "Should throw on unknown category.");
-  Assert.throws(() => Telemetry.recordEvent("telemetry.test", "unknown", "object1"),
-                /Error: Unknown event\./,
-                "Should throw on unknown method.");
-  Assert.throws(() => Telemetry.recordEvent("telemetry.test", "test1", "unknown"),
-                /Error: Unknown event\./,
-                "Should throw on unknown object.");
-
-  let checkEvents = (events, expected) => {
-    checkEventFormat(events);
-    Assert.equal(events.length, expected.length,
-                 "Snapshot should have the right number of events.");
-
-    for (let i = 0; i < events.length; ++i) {
-      let {tsBefore, tsAfter} = expected[i];
-      let ts = events[i][0];
-      Assert.greaterOrEqual(ts, tsBefore, "The recorded timestamp should be greater than the one before recording.");
-      Assert.lessOrEqual(ts, tsAfter, "The recorded timestamp should be less than the one after recording.");
-
-      let recordedData = events[i].slice(1);
-      let expectedData = expected[i].event.slice();
-      for (let j=expectedData.length; j<5; ++j) {
-        expectedData.push(null);
-      }
-      Assert.deepEqual(recordedData, expectedData, "The recorded event data should match.");
-    }
-  };
-
-  // Check that the expected events were recorded.
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, false);
-  checkEvents(events, expected);
-
-  // Check serializing only opt-out events.
-  events = Telemetry.snapshotBuiltinEvents(OPTOUT, false);
-  filtered = expected.filter(e => e.optout == true);
-  checkEvents(events, filtered);
-});
-
-add_task(function* test_clear() {
-  Telemetry.clearEvents();
-
-  const COUNT = 10;
-  for (let i = 0; i < COUNT; ++i) {
-    Telemetry.recordEvent("telemetry.test", "test1", "object1");
-    Telemetry.recordEvent("telemetry.test.second", "test", "object1");
-  }
-
-  // Check that events were recorded.
-  // The events are cleared by passing the respective flag.
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 2 * COUNT, `Should have recorded ${2 * COUNT} events.`);
-
-  // Now the events should be cleared.
-  events = Telemetry.snapshotBuiltinEvents(OPTIN, false);
-  Assert.equal(events.length, 0, `Should have cleared the events.`);
-});
-
-add_task(function* test_expiry() {
-  Telemetry.clearEvents();
-
-  // Recording call with event that is expired by version.
-  Telemetry.recordEvent("telemetry.test", "test_expired_version", "object1");
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 0, "Should not record event with expired version.");
-
-  // Recording call with event that is expired by date.
-  Telemetry.recordEvent("telemetry.test", "test_expired_date", "object1");
-  events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 0, "Should not record event with expired date.");
-
-  // Recording call with event that has expiry_version and expiry_date in the future.
-  Telemetry.recordEvent("telemetry.test", "test_not_expired_optout", "object1");
-  events = Telemetry.snapshotBuiltinEvents(OPTOUT, true);
-  Assert.equal(events.length, 1, "Should record event when date and version are not expired.");
-});
-
-add_task(function* test_invalidParams() {
-  Telemetry.clearEvents();
-
-  // Recording call with wrong type for value argument.
-  Telemetry.recordEvent("telemetry.test", "test1", "object1", 1);
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 0, "Should not record event when value argument with invalid type is passed.");
-
-  // Recording call with wrong type for extra argument.
-  Telemetry.recordEvent("telemetry.test", "test1", "object1", null, "invalid");
-  events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 0, "Should not record event when extra argument with invalid type is passed.");
-
-  // Recording call with unknown extra key.
-  Telemetry.recordEvent("telemetry.test", "test1", "object1", null, {"key3": "x"});
-  events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 0, "Should not record event when extra argument with invalid key is passed.");
-
-  // Recording call with invalid value type.
-  Telemetry.recordEvent("telemetry.test", "test1", "object1", null, {"key3": 1});
-  events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 0, "Should not record event when extra argument with invalid value type is passed.");
-});
-
-add_task(function* test_storageLimit() {
-  Telemetry.clearEvents();
-
-  // Record more events than the storage limit allows.
-  let LIMIT = 10000;
-  let COUNT = LIMIT + 10;
-  for (let i = 0; i < COUNT; ++i) {
-    Telemetry.recordEvent("telemetry.test", "test1", "object1", String(i));
-  }
-
-  // Check that the right events were recorded.
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, LIMIT, `Should have only recorded ${LIMIT} events`);
-  Assert.ok(events.every((e, idx) => e[4] === String(idx)),
-            "Should have recorded all events from before hitting the limit.");
-});
-
-add_task(function* test_valueLimits() {
-  Telemetry.clearEvents();
-
-  // Record values that are at or over the limits for string lengths.
-  let LIMIT = 100;
-  let expected = [
-    ["telemetry.test", "test1", "object1", "a".repeat(LIMIT - 10), null],
-    ["telemetry.test", "test1", "object1", "a".repeat(LIMIT     ), null],
-    ["telemetry.test", "test1", "object1", "a".repeat(LIMIT +  1), null],
-    ["telemetry.test", "test1", "object1", "a".repeat(LIMIT + 10), null],
-
-    ["telemetry.test", "test1", "object1", null, {key1: "a".repeat(LIMIT - 10)}],
-    ["telemetry.test", "test1", "object1", null, {key1: "a".repeat(LIMIT     )}],
-    ["telemetry.test", "test1", "object1", null, {key1: "a".repeat(LIMIT +  1)}],
-    ["telemetry.test", "test1", "object1", null, {key1: "a".repeat(LIMIT + 10)}],
-  ];
-
-  for (let event of expected) {
-    Telemetry.recordEvent(...event);
-    if (event[3]) {
-      event[3] = event[3].substr(0, 100);
-    }
-    if (event[4]) {
-      event[4].key1 = event[4].key1.substr(0, 100);
-    }
-  }
-
-  // Check that the right events were recorded.
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, expected.length,
-               "Should have recorded the expected number of events");
-  for (let i = 0; i < expected.length; ++i) {
-    Assert.deepEqual(events[i].slice(1), expected[i],
-                     "Should have recorded the expected event data.");
-  }
-});
-
-add_task(function* test_unicodeValues() {
-  Telemetry.clearEvents();
-
-  // Record string values containing unicode characters.
-  let value = "漢語";
-  Telemetry.recordEvent("telemetry.test", "test1", "object1", value);
-  Telemetry.recordEvent("telemetry.test", "test1", "object1", null, {"key1": value});
-
-  // Check that the values were correctly recorded.
-  let events = Telemetry.snapshotBuiltinEvents(OPTIN, true);
-  Assert.equal(events.length, 2, "Should have recorded 2 events.");
-  Assert.equal(events[0][4], value, "Should have recorded the right value.");
-  Assert.equal(events[1][5]["key1"], value, "Should have recorded the right extra value.");
-});
--- a/toolkit/components/telemetry/tests/unit/xpcshell.ini
+++ b/toolkit/components/telemetry/tests/unit/xpcshell.ini
@@ -55,9 +55,8 @@ run-sequentially = Bug 1046307, test can
 [test_ChildHistograms.js]
 skip-if = os == "android"
 tags = addons
 [test_TelemetryReportingPolicy.js]
 tags = addons
 [test_TelemetryScalars.js]
 [test_TelemetryTimestamps.js]
 skip-if = toolkit == 'android'
-[test_TelemetryEvents.js]