Commit 4d0cce18 authored by Eric Roman's avatar Eric Roman Committed by Commit Bot

Make stitch_net_log_files.py handle more cases.

 * Order event files from oldest to newest
 * Remove the --num_files switch
 * Don't fail if end_netlog.json is missing (since it probably will be
   when using this)

Bug: 744815
Change-Id: I26307d3c293eb445b7e3456d6b359f8ef05a0204
Reviewed-on: https://chromium-review.googlesource.com/578484
Commit-Queue: Eric Roman <eroman@chromium.org>
Reviewed-by: default avatarHelen Li <xunjieli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488045}
parent 0881de77
...@@ -4,50 +4,87 @@ ...@@ -4,50 +4,87 @@
# found in the LICENSE file. # found in the LICENSE file.
''' '''
This script stitches the NetLog files in a specified directory. 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>.
The complete NetLog will be written to net-internals-log.json in the directory If <OUTPUT_PATH> is not specified, it should end with ".inprogress", and the
passed as argument to --path. completed NetLog file will be written to the location with ".inprogress"
stripped.
''' '''
import argparse, os
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(): def main():
parser = argparse.ArgumentParser() if len(sys.argv) != 2 and len(sys.argv) != 3:
parser.add_argument('--path', action='store', sys.stderr.write(USAGE)
help="Specifies the complete filepath of the directory where the log " sys.exit(1)
"files are located.")
# TODO(dconnol): Automatically pull all event files matching the format inprogress_dir = sys.argv[1]
# event_file_<num>.json and remove the num_files argument. output_path = None
parser.add_argument('--num_files', action='store',
help="Specifies the number of event files (not including the constants " # Pick an output path based on command line arguments.
"file or the end_netlog file) that need need to be stitched together. " if len(sys.argv) == 3:
"The number of event files passed to the script must not be greater " output_path = sys.argv[2]
"than the number of event files in the directory.") elif len(sys.argv) == 2:
args = parser.parse_args() m = re.match("^(.*)\.inprogress/?$", inprogress_dir)
if not m:
num_files = int(args.num_files) sys.stdout.write("Must specify OUTPUT_PATH\n")
filepath = args.path sys.exit(1)
if filepath[-1:] != "/": output_path = m.group(1)
filepath += "/"
output_path = os.path.abspath(output_path)
os.chdir(filepath)
sys.stdout.write("Reading data from: %s\n" % inprogress_dir)
with open("net-internals-log.json", "w") as stitched_file: sys.stdout.write("Writing log file to: %s\n" % output_path)
os.chdir(inprogress_dir)
with open(output_path, "w") as stitched_file:
try: try:
file = open("constants.json") file = open("constants.json")
with file: with file:
for line in file: for line in file:
stitched_file.write(line) stitched_file.write(line)
except IOError: except IOError:
os.remove("net-internals-log.json") sys.stderr.write("Failed reading \"constants.json\".\n")
print "File \"constants.json\" not found." sys.exit(1)
return
events_written = False; events_written = False;
for i in range(num_files): for event_file_path in get_ordered_event_files():
try: try:
file = open("event_file_%d.json" % i) file = open(event_file_path)
with file: with file:
if not events_written: if not events_written:
line = file.readline(); line = file.readline();
...@@ -59,9 +96,8 @@ def main(): ...@@ -59,9 +96,8 @@ def main():
stitched_file.write(line) stitched_file.write(line)
line = next_line line = next_line
except IOError: except IOError:
os.remove("net-internals-log.json") sys.stderr.write("Failed reading \"%s\"\n" % event_file_path)
print "File \"event_file_%d.json\" not found." % i sys.exit(1)
return
# Remove hanging comma from last event # Remove hanging comma from last event
# TODO(dconnol): Check if the last line is a valid JSON object. If not, # 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. # do not write the line to file. This handles incomplete logs.
...@@ -71,21 +107,21 @@ def main(): ...@@ -71,21 +107,21 @@ def main():
elif line: elif line:
raise ValueError('Last event is not properly formed') raise ValueError('Last event is not properly formed')
if os.path.exists("end_netlog.json"):
try: try:
file = open("end_netlog.json") file = open("end_netlog.json")
with file: with file:
for line in file: for line in file:
stitched_file.write(line) stitched_file.write(line)
except IOError: except IOError:
os.remove("net-internals-log.json") sys.stderr.write("Failed reading \"end_netlog.json\".\n")
print "File \"end_netlog\" not found." sys.exit(1)
return else:
# end_netlog.json won't exist when using this tool to stitch logging
# Delete old NetLog files # sessions that didn't shutdown gracefully.
for i in range (num_files): #
os.remove("event_file_%d.json" % i) # Close the events array and then the log (no polled_data).
os.remove("constants.json") stitched_file.write("]}\n")
os.remove("end_netlog.json")
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment