21a10d3499
After Python 2 is getting unsupported, new distros like CentOS 8 and RHEL8 have stopped providing 'python' package forcing user to decide which alternative to use by installing 'python2' or 'python3.x' package and then setting python alternative. This change is intended to make using python3 command as much as possible and use it as default 'python' alternative where needed. The final goals motivating this change are: - stop using python2 as much as possible - help adding support for CentOS 8 and RHEL8 Change-Id: I1e90db987c0bfa6206c211e066be03ea8738ad3f
107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
# This is an output filter to filter and timestamp the logs from Grenade and
|
|
# DevStack. Largely our awk filters got beyond the complexity level which were
|
|
# sustainable, so this provides us much more control in a single place.
|
|
#
|
|
# The overhead of running python should be less than execing `date` a million
|
|
# times during a run.
|
|
|
|
import argparse
|
|
import datetime
|
|
import re
|
|
import sys
|
|
|
|
IGNORE_LINES = re.compile('(set \+o|xtrace)')
|
|
HAS_DATE = re.compile('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} \|')
|
|
|
|
|
|
def get_options():
|
|
parser = argparse.ArgumentParser(
|
|
description='Filter output by DevStack and friends')
|
|
parser.add_argument('-o', '--outfile',
|
|
help='Output file for content',
|
|
default=None)
|
|
# NOTE(ianw): This is intended for the case where your stdout is
|
|
# being captured by something like ansible which independently
|
|
# logs timestamps on the lines it receives. Note that if using a
|
|
# output file, those log lines are still timestamped.
|
|
parser.add_argument('-b', '--no-timestamp', action='store_true',
|
|
help='Do not prefix stdout with timestamp (bare)',
|
|
default=False)
|
|
parser.add_argument('-v', '--verbose', action='store_true',
|
|
default=False)
|
|
return parser.parse_args()
|
|
|
|
|
|
def skip_line(line):
|
|
"""Should we skip this line."""
|
|
return IGNORE_LINES.search(line) is not None
|
|
|
|
|
|
def main():
|
|
opts = get_options()
|
|
outfile = None
|
|
if opts.outfile:
|
|
# note, binary mode so we can do unbuffered output.
|
|
outfile = open(opts.outfile, 'ab', 0)
|
|
|
|
# Otherwise fileinput reprocess args as files
|
|
sys.argv = []
|
|
|
|
for line in iter(sys.stdin.readline, ''):
|
|
# put skip lines here
|
|
if skip_line(line):
|
|
continue
|
|
|
|
# This prevents us from nesting date lines, because we'd like
|
|
# to pull this in directly in Grenade and not double up on
|
|
# DevStack lines.
|
|
# NOTE(ianw): we could actually strip the extra ts in "bare"
|
|
# mode (which came after this)? ... as we get more experience
|
|
# with zuulv3 native jobs and ansible capture it may become
|
|
# clearer what to do
|
|
if HAS_DATE.search(line) is None:
|
|
now = datetime.datetime.utcnow()
|
|
ts_line = ("%s | %s" % (
|
|
now.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3],
|
|
line))
|
|
else:
|
|
ts_line = line
|
|
|
|
if opts.verbose:
|
|
sys.stdout.write(line if opts.no_timestamp else ts_line)
|
|
sys.stdout.flush()
|
|
|
|
if outfile:
|
|
# We've opened outfile as a binary file to get the
|
|
# non-buffered behaviour. on python3, sys.stdin was
|
|
# opened with the system encoding and made the line into
|
|
# utf-8, so write the logfile out in utf-8 bytes.
|
|
if sys.version_info < (3,):
|
|
outfile.write(ts_line)
|
|
else:
|
|
outfile.write(ts_line.encode('utf-8'))
|
|
outfile.flush()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
sys.exit(main())
|
|
except KeyboardInterrupt:
|
|
sys.exit(1)
|