mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-16 06:54:00 +00:00
Bug 998989 - save as telemetry ping file for upload by telemetry. r=vladan
This commit is contained in:
parent
fc48e8c4ac
commit
f537c69ad6
@ -9,6 +9,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm", this);
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["MozLoopService"];
|
||||
|
||||
@ -52,7 +53,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
let MozLoopServiceInternal = {
|
||||
// The uri of the Loop server.
|
||||
loopServerUri: Services.prefs.getCharPref("loop.server"),
|
||||
telemetryUri: Services.prefs.getCharPref("loop.telemetryURL"),
|
||||
|
||||
// The current deferred for the registration process. This is set if in progress
|
||||
// or the registration was successful. This is null if a registration attempt was
|
||||
@ -314,65 +314,67 @@ let MozLoopServiceInternal = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Uploads telemetry logs to telemetryServer
|
||||
* Saves loop logs to the saved-telemetry-pings folder.
|
||||
*
|
||||
* @param {Object} pc The peerConnection in question.
|
||||
*/
|
||||
uploadTelemetry: function(window, pc) {
|
||||
if (!this.telemetryUri) {
|
||||
return;
|
||||
}
|
||||
stageForTelemetryUpload: function(window, pc) {
|
||||
window.WebrtcGlobalInformation.getAllStats(allStats => {
|
||||
let internalFormat = allStats.reports[0]; // filtered on pc.id
|
||||
window.WebrtcGlobalInformation.getLogging('', logs => {
|
||||
let report = convertToRTCStatsReport(internalFormat);
|
||||
let logStr = "";
|
||||
logs.forEach(s => { logStr += s + "\n"; });
|
||||
|
||||
// We have stats and logs.
|
||||
// Prepare payload from https://wiki.mozilla.org/Loop/Telemetry
|
||||
|
||||
// Create worker job. ping = saved telemetry ping file header + payload
|
||||
//
|
||||
// Prepare payload according to https://wiki.mozilla.org/Loop/Telemetry
|
||||
|
||||
let ai = Services.appinfo;
|
||||
let report = convertToRTCStatsReport(internalFormat);
|
||||
|
||||
let payload = {
|
||||
ver: 1,
|
||||
info: {
|
||||
appUpdateChannel: ai.defaultUpdateChannel,
|
||||
appBuildID: ai.appBuildID,
|
||||
appName: ai.name,
|
||||
appVersion: ai.version,
|
||||
reason: "loop",
|
||||
OS: ai.OS,
|
||||
version: Services.sysinfo.getProperty("version")
|
||||
},
|
||||
report: "ice failure",
|
||||
connectionstate: pc.iceConnectionState,
|
||||
stats: report,
|
||||
localSdp: internalFormat.localSdp,
|
||||
remoteSdp: internalFormat.remoteSdp,
|
||||
log: ""
|
||||
};
|
||||
logs.forEach(s => { payload.log += s + "\n"; });
|
||||
|
||||
let uuid = uuidgen.generateUUID().toString();
|
||||
uuid = uuid.substr(1,uuid.length-2); // remove uuid curly braces
|
||||
|
||||
let url = this.telemetryUri;
|
||||
url += ((url.substr(-1) == "/")? "":"/") + uuid + "/loop/" +
|
||||
ai.OS + "/" + ai.version + "/" + ai.defaultUpdateChannel + "/" +
|
||||
ai.appBuildID;
|
||||
|
||||
// Send payload.
|
||||
//TODO: gzip!
|
||||
|
||||
let xhr = new window.XMLHttpRequest();
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader("Content-Type", 'application/json');
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
console.log("Failed to upload telemetry logs: " + xhr.responseText);
|
||||
let directory = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"saved-telemetry-pings");
|
||||
let job = {
|
||||
directory: directory,
|
||||
filename: uuid + ".json",
|
||||
ping: {
|
||||
reason: "loop",
|
||||
slug: uuid,
|
||||
payload: {
|
||||
ver: 1,
|
||||
info: {
|
||||
appUpdateChannel: ai.defaultUpdateChannel,
|
||||
appBuildID: ai.appBuildID,
|
||||
appName: ai.name,
|
||||
appVersion: ai.version,
|
||||
reason: "loop",
|
||||
OS: ai.OS,
|
||||
version: Services.sysinfo.getProperty("version")
|
||||
},
|
||||
report: "ice failure",
|
||||
connectionstate: pc.iceConnectionState,
|
||||
stats: report,
|
||||
localSdp: internalFormat.localSdp,
|
||||
remoteSdp: internalFormat.remoteSdp,
|
||||
log: logStr
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(JSON.stringify(payload));
|
||||
console.log("Uploading telemetry logs to " + url);
|
||||
|
||||
// Send job to worker to do saving to
|
||||
// disk for pickup by telemetry on next startup, which then uploads it.
|
||||
|
||||
let worker = new ChromeWorker("MozLoopWorker.js");
|
||||
worker.onmessage = function(e) {
|
||||
console.log(e.data.ok ?
|
||||
"Successfully staged loop report for telemetry upload." :
|
||||
("Failed to stage loop report. Error: " + e.data.fail));
|
||||
}
|
||||
worker.postMessage(job);
|
||||
});
|
||||
}, pc.id);
|
||||
},
|
||||
@ -420,7 +422,10 @@ let MozLoopServiceInternal = {
|
||||
switch(pc.iceConnectionState) {
|
||||
case "failed":
|
||||
case "disconnected":
|
||||
this.uploadTelemetry(window, pc);
|
||||
if (Services.telemetry.canSend ||
|
||||
Services.prefs.getBoolPref("toolkit.telemetry.test")) {
|
||||
this.stageForTelemetryUpload(window, pc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
54
browser/components/loop/MozLoopWorker.js
Normal file
54
browser/components/loop/MozLoopWorker.js
Normal file
@ -0,0 +1,54 @@
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* A worker dedicated to loop-report sanitation and writing for MozLoopService.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
importScripts("resource://gre/modules/osfile.jsm");
|
||||
|
||||
let File = OS.File;
|
||||
let Encoder = new TextEncoder();
|
||||
let Counter = 0;
|
||||
|
||||
const MAX_LOOP_LOGS = 5;
|
||||
/**
|
||||
* Communications with the controller.
|
||||
*
|
||||
* Accepts messages:
|
||||
* { path: filepath, ping: data }
|
||||
*
|
||||
* Sends messages:
|
||||
* { ok: true }
|
||||
* { fail: serialized_form_of_OS.File.Error }
|
||||
*/
|
||||
|
||||
onmessage = function(e) {
|
||||
if (++Counter > MAX_LOOP_LOGS) {
|
||||
postMessage({
|
||||
fail: "Maximum " + MAX_LOOP_LOGS + "loop reports reached for this session"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let directory = e.data.directory;
|
||||
let filename = e.data.filename;
|
||||
let ping = e.data.ping;
|
||||
|
||||
let pingStr = JSON.stringify(ping);
|
||||
|
||||
// Save to disk
|
||||
let array = Encoder.encode(pingStr);
|
||||
try {
|
||||
File.makeDir(directory,
|
||||
{ unixMode: OS.Constants.S_IRWXU, ignoreExisting: true });
|
||||
File.writeAtomic(OS.Path.join(directory, filename), array);
|
||||
postMessage({ ok: true });
|
||||
} catch (ex if ex instanceof File.Error) {
|
||||
// Instances of OS.File.Error know how to serialize themselves
|
||||
postMessage({fail: File.Error.toMsg(ex)});
|
||||
}
|
||||
};
|
@ -14,4 +14,5 @@ EXTRA_JS_MODULES += [
|
||||
'MozLoopAPI.jsm',
|
||||
'MozLoopPushHandler.jsm',
|
||||
'MozLoopService.jsm',
|
||||
'MozLoopWorker.js',
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user