static recordsFromLogs(devtoolsLog) {
    const networkRecorder = new NetworkRecorder();
    // playback all the devtools messages to recreate network records
    devtoolsLog.forEach(message => networkRecorder.dispatch(message));

    // get out the list of records & filter out invalid records
    const records = networkRecorder.getRawRecords().filter(record => record.isValid);

    /** @type {Map<string, NetworkRequest[]>} */
    const recordsByURL = new Map();
    for (const record of records) {
      const records = recordsByURL.get(record.url) || [];
      records.push(record);
      recordsByURL.set(record.url, records);
    }

    // set the initiatorRequest and redirects array
    for (const record of records) {
      const initiatorRequest = NetworkRecorder._chooseInitiatorRequest(record, recordsByURL);
      if (initiatorRequest) {
        record.setInitiatorRequest(initiatorRequest);
      }

      let finalRecord = record;
      while (finalRecord.redirectDestination) finalRecord = finalRecord.redirectDestination;
      if (finalRecord === record || finalRecord.redirects) continue;

      const redirects = [];
      for (
        let redirect = finalRecord.redirectSource;
        redirect;
        redirect = redirect.redirectSource
      ) {
        redirects.unshift(redirect);
      }

      finalRecord.redirects = redirects;
    }

    return records;
  }
Construct network records from a log of devtools protocol messages.
@param {LH.DevtoolsLog} devtoolsLog
@return {Array<LH.Artifacts.NetworkRequest>}