123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #!/usr/bin/env python
- # Copyright 2016 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- '''
- This script "stitches" the NetLog files from a ".inprogress" directory to
- create a single NetLog file.
- '''
- import glob
- import os
- import re
- import sys
- USAGE ='''Usage: stitch_net_log_files.py <INPROGRESS_DIR> [<OUTPUT_PATH>]
- Will copy all the files in <INPROGRESS_DIR> and write the their content into a
- NetLog file at path <OUTPUT_PATH>.
- If <OUTPUT_PATH> is not specified, it should end with ".inprogress", and the
- completed NetLog file will be written to the location with ".inprogress"
- stripped.
- '''
- def get_event_file_sort_key(path):
- '''Returns a tuple (modification timestamp, file number) for a path of the
- form event_file_%d.json'''
- m = re.match('^event_file_(\d+).json$', path)
- file_index = int(m.group(1))
- return (os.path.getmtime(path), file_index)
- def get_ordered_event_files():
- '''Returns a list of file paths to event files. The order of the files is
- from oldest to newest. If modification times are the same, files will be
- ordered based on the numeral in their file name.'''
- paths = glob.glob("event_file_*.json")
- paths = sorted(paths, key=get_event_file_sort_key)
- sys.stdout.write("Identified %d event files:\n %s\n" %
- (len(paths), "\n ".join(paths)))
- return paths
- def main():
- if len(sys.argv) != 2 and len(sys.argv) != 3:
- sys.stderr.write(USAGE)
- sys.exit(1)
- inprogress_dir = sys.argv[1]
- output_path = None
- # Pick an output path based on command line arguments.
- if len(sys.argv) == 3:
- output_path = sys.argv[2]
- elif len(sys.argv) == 2:
- m = re.match("^(.*)\.inprogress/?$", inprogress_dir)
- if not m:
- sys.stdout.write("Must specify OUTPUT_PATH\n")
- sys.exit(1)
- output_path = m.group(1)
- output_path = os.path.abspath(output_path)
- sys.stdout.write("Reading data from: %s\n" % inprogress_dir)
- sys.stdout.write("Writing log file to: %s\n" % output_path)
- os.chdir(inprogress_dir)
- with open(output_path, "w") as stitched_file:
- try:
- file = open("constants.json")
- with file:
- for line in file:
- stitched_file.write(line)
- except IOError:
- sys.stderr.write("Failed reading \"constants.json\".\n")
- sys.exit(1)
- events_written = False;
- for event_file_path in get_ordered_event_files():
- try:
- file = open(event_file_path)
- with file:
- if not events_written:
- line = file.readline();
- events_written = True
- for next_line in file:
- if next_line.strip() == "":
- line += next_line
- else:
- stitched_file.write(line)
- line = next_line
- except IOError:
- sys.stderr.write("Failed reading \"%s\"\n" % event_file_path)
- sys.exit(1)
- # Remove hanging comma from last event
- # TODO(dconnol): Check if the last line is a valid JSON object. If not,
- # do not write the line to file. This handles incomplete logs.
- line = line.strip()
- if line[-1:] == ",":
- stitched_file.write(line[:-1])
- elif line:
- raise ValueError('Last event is not properly formed')
- if os.path.exists("end_netlog.json"):
- try:
- file = open("end_netlog.json")
- with file:
- for line in file:
- stitched_file.write(line)
- except IOError:
- sys.stderr.write("Failed reading \"end_netlog.json\".\n")
- sys.exit(1)
- else:
- # end_netlog.json won't exist when using this tool to stitch logging
- # sessions that didn't shutdown gracefully.
- #
- # Close the events array and then the log (no polled_data).
- stitched_file.write("]}\n")
- if __name__ == "__main__":
- main()
|