Skip to content

Commit 62cb563

Browse files
committed
convert devstack from awk to outfilter
The complexity of the awk script was pretty high, and it would be good to do it in summaries as well, which starts to get a bit squirelly. Instead bring over the outfilter.py from grenade and use it for the timestamping. Any additional overhead from python should be offset from not shelling out to date on every line of output. Change-Id: Ic2b86ddba3e7f6520a0fd35599b01143936c6deb
1 parent 1469a04 commit 62cb563

2 files changed

Lines changed: 92 additions & 16 deletions

File tree

stack.sh

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -548,25 +548,14 @@ if [[ -n "$LOGFILE" ]]; then
548548
exec 3>&1
549549
if [[ "$VERBOSE" == "True" ]]; then
550550
# Set fd 1 and 2 to write the log file
551-
exec 1> >( awk -v logfile=${LOGFILE} '
552-
/((set \+o$)|xtrace)/ { next }
553-
{
554-
cmd ="date +\"%Y-%m-%d %H:%M:%S.%3N | \""
555-
cmd | getline now
556-
close("date +\"%Y-%m-%d %H:%M:%S.%3N | \"")
557-
sub(/^/, now)
558-
print > logfile
559-
fflush(logfile)
560-
print
561-
fflush("")
562-
}' ) 2>&1
551+
exec 1> >( ./tools/outfilter.py -v -o "${LOGFILE}" ) 2>&1
563552
# Set fd 6 to summary log file
564-
exec 6> >( tee "${SUMFILE}" )
553+
exec 6> >( ./tools/outfilter.py -o "${SUMFILE}" )
565554
else
566555
# Set fd 1 and 2 to primary logfile
567-
exec 1> "${LOGFILE}" 2>&1
556+
exec 1> >( ./tools/outfilter.py -o "${LOGFILE}" ) 2>&1
568557
# Set fd 6 to summary logfile and stdout
569-
exec 6> >( tee "${SUMFILE}" >&3 )
558+
exec 6> >( ./tools/outfilter.py -v -o "${SUMFILE}" >&3 )
570559
fi
571560

572561
echo_summary "stack.sh log $LOGFILE"
@@ -583,7 +572,7 @@ else
583572
exec 1>/dev/null 2>&1
584573
fi
585574
# Always send summary fd to original stdout
586-
exec 6>&3
575+
exec 6> >( ./tools/outfilter.py -v >&3 )
587576
fi
588577

589578
# Set up logging of screen windows

tools/outfilter.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2014 Hewlett-Packard Development Company, L.P.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
# This is an output filter to filter and timestamp the logs from grenade and
18+
# devstack. Largely our awk filters got beyond the complexity level which were
19+
# sustainable, so this provides us much more control in a single place.
20+
#
21+
# The overhead of running python should be less than execing `date` a million
22+
# times during a run.
23+
24+
import argparse
25+
import datetime
26+
import re
27+
import sys
28+
29+
IGNORE_LINES = re.compile('(set \+o|xtrace)')
30+
HAS_DATE = re.compile('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} \|')
31+
32+
33+
def get_options():
34+
parser = argparse.ArgumentParser(
35+
description='Filter output by devstack and friends')
36+
parser.add_argument('-o', '--outfile',
37+
help='Output file for content',
38+
default=None)
39+
parser.add_argument('-v', '--verbose', action='store_true',
40+
default=False)
41+
return parser.parse_args()
42+
43+
44+
def skip_line(line):
45+
"""Should we skip this line."""
46+
return IGNORE_LINES.search(line) is not None
47+
48+
49+
def main():
50+
opts = get_options()
51+
outfile = None
52+
if opts.outfile:
53+
outfile = open(opts.outfile, 'a', 0)
54+
55+
# otherwise fileinput reprocess args as files
56+
sys.argv = []
57+
while True:
58+
line = sys.stdin.readline()
59+
if not line:
60+
return 0
61+
62+
# put skip lines here
63+
if skip_line(line):
64+
continue
65+
66+
# this prevents us from nesting date lines, because
67+
# we'd like to pull this in directly in grenade and not double
68+
# up on devstack lines
69+
if HAS_DATE.search(line) is None:
70+
now = datetime.datetime.utcnow()
71+
line = ("%s | %s" % (
72+
now.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3],
73+
line))
74+
75+
if opts.verbose:
76+
sys.stdout.write(line)
77+
sys.stdout.flush()
78+
if outfile:
79+
outfile.write(line)
80+
outfile.flush()
81+
82+
83+
if __name__ == '__main__':
84+
try:
85+
sys.exit(main())
86+
except KeyboardInterrupt:
87+
sys.exit(1)

0 commit comments

Comments
 (0)