firefox-devtools / profiler

Firefox Profiler — Web app for Firefox performance analysis
https://profiler.firefox.com
Mozilla Public License 2.0
1.19k stars 389 forks source link

Feature request: Add a method to export MozLog's captured by the Profiler #4660

Closed acreskeyMoz closed 3 weeks ago

acreskeyMoz commented 1 year ago

The Necko team would like to use about:logging and the resulting Firefox Profiles as the default method to collect nsHttp (and related) MozLogs from users.

While this currently works well, there are some advantages to having the raw MozLog files. Namely, they can be used in other tooling such as the log-analyzer, logan.

So the feature request is to add a method to the Profiler to export the full MozLogs. (I imagine one file per process).

┆Issue is synchronized with this Jira Task

padenot commented 1 year ago

This:

(function () {
  "use strict";
  function pad(p, c) {
    return ("" + p).padStart(c, 0);
  }
  function d2s(ts) {
    const d = new Date(ts);
    // new Date rounds down the timestamp (in milliseconds) to the lower integer,
    // let's get the microseconds and nanoseconds differently.
    // This will be imperfect because of float rounding errors but still better
    // than not having them.
    const ns = Math.trunc((ts - Math.trunc(ts)) * 10 ** 6);
    return `${d.getFullYear()}-${pad(d.getUTCMonth() + 1, 2)}-${pad(d.getUTCDate(), 2)} ${pad(d.getUTCHours(), 2)}:${pad(d.getUTCMinutes(), 2)}:${pad(d.getUTCSeconds(), 2)}.${pad(d.getUTCMilliseconds(), 3)}${pad(ns, 6)} UTC`;
  }
  var logs = {};
  var all = [];
  for (var thread of window.profile.threads) {
    for (var i = 0; i < thread.markers.length; i++) {
      if (!logs[thread.pid]) {
        logs[thread.pid] = [];
      }
      if (thread.markers.data[i] && thread.markers.data[i].type == "Log") {
        var statement =
          d2s(profile.meta.startTime + thread.markers.startTime[i]) +
          " - [" +
          thread.processName +
          " " +
          thread.pid +
          " " +
          thread.name +
          "] " +
          "D/"+thread.markers.data[i].module + " " + thread.markers.data[i].name; // lying about the log level -- not available yet in the markers
        logs[thread.pid].push(statement);
        all.push(statement);
      }
    }
  }
  copy(all.sort().join("\n"));
})();

copies all log statements from all processes to the system clipboard, sorted by time and with the pid and thread name added, a bit like the console/file output of MOZ_LOG.

But I agree it would be good to have a UI button to get a file, merged or not, I've needed it once or twice when I want to post-process logs.

acreskeyMoz commented 1 year ago

This is great. We would really like a UI button because we'll be asking folks in bug reports and elsewhere to share logs this way. So anything to make it easier for them would be beneficial.

acreskeyMoz commented 1 year ago

Sorry, let me talk to the Necko folks about this. Maybe the button is not needed.

julienw commented 10 months ago

FYI I updated the previous snippet to include micro and nanoseconds so that the sorting works better, from a feedback in the #necko channel on Matrix.

julienw commented 5 months ago

For future reference, here is a profile with some LogMessages markers: https://share.firefox.dev/4dn1QVu