tailor.py: avec le preset php, traiter \n

This commit is contained in:
Jephté Clain 2018-06-19 01:15:39 +04:00
parent 7676c7635a
commit 6184fde5a2
1 changed files with 49 additions and 31 deletions

View File

@ -6,13 +6,15 @@ u"""Afficher les lignes d'un fichier en mettant en surbrillance certains pattern
import sys, subprocess, re import sys, subprocess, re
from collections import OrderedDict from collections import OrderedDict
def bluef(line, *ignored): return '\x1B[34m%s\x1B[0m' % line def fixnlf(line, mo): return re.sub(r'\\n', '\n', line)
def greenf(line, *ignored): return '\x1B[32m%s\x1B[0m' % line def bluef(line, mo): return '\x1B[34m%s\x1B[0m' % line
def yellowf(line, *ignored): return '\x1B[33m%s\x1B[0m' % line def greenf(line, mo): return '\x1B[32m%s\x1B[0m' % line
def redf(line, *ignored): return '\x1B[31m%s\x1B[0m' % line def yellowf(line, mo): return '\x1B[33m%s\x1B[0m' % line
def nonef(line, *ignored): return re.sub('\x1B\[.*?m', '', line) def redf(line, mo): return '\x1B[31m%s\x1B[0m' % line
def nonef(line, mo): return re.sub('\x1B\[.*?m', '', line)
FORMATS = OrderedDict([ FORMATS = OrderedDict([
('fixnl', fixnlf),
('blue', bluef), ('blue', bluef),
('green', greenf), ('green', greenf),
('yellow', yellowf), ('yellow', yellowf),
@ -20,6 +22,7 @@ FORMATS = OrderedDict([
('none', nonef), ('none', nonef),
]) ])
FORMAT_ALIASES = { FORMAT_ALIASES = {
'f': 'fixnl',
'b': 'blue', 'b': 'blue',
'g': 'green', 'g': 'green',
'y': 'yellow', 'y': 'yellow',
@ -27,30 +30,35 @@ FORMAT_ALIASES = {
'': 'none', '': 'none',
} }
APACHE_PATTERNS = OrderedDict([ DEFAULT_PATTERNS = OrderedDict([
(r'(?i)error', redf), (r'(?i)error', redf),
(r'(?i)warn(ing)?', yellowf), (r'(?i)warn(ing)?', yellowf),
(r'(?i)info', bluef), (r'(?i)info', bluef),
(None, nonef), (None, nonef),
]) ])
PHP_PATTERNS = OrderedDict([
(r'(?i)php fatal error', redf), APACHE_PATTERNS = [
(r'(?i)php notice', yellowf), r'(?i)error:red',
(r'(?i)php warning', bluef), r'(?i)warn(ing)?:yellow',
(None, nonef), r'(?i)info:blue',
]) r':none',
]
PHP_PATTERNS = [
r'(?i)php fatal error:fixnl,red',
r'(?i)php notice:yellow,fixnl',
r'(?i)php warning:fixnl,blue',
r':fixnl,none',
]
PRESETS = { PRESETS = {
'apache': ('/var/log/apache2/error.log', True, APACHE_PATTERNS), 'apache': ('/var/log/apache2/error.log', True, APACHE_PATTERNS, False),
'php': ('/var/log/apache2/error.log', True, PHP_PATTERNS), 'php': ('/var/log/apache2/error.log', True, PHP_PATTERNS, False),
} }
PRESET_ALIASES = { PRESET_ALIASES = {
'a': 'apache', 'a': 'apache',
'p': 'php', 'p': 'php',
} }
DEFAULT_PATTERNS = APACHE_PATTERNS
def strip_nl(s): def strip_nl(s):
if s is None: return None if s is None: return None
elif s.endswith("\r\n"): s = s[:-2] elif s.endswith("\r\n"): s = s[:-2]
@ -146,7 +154,7 @@ Les lignes qui ne correspondent à aucun pattern ne sont pas affichées.""" % pa
default_patterns = [u"%s:%s" % (p or '', f.__name__[:-1]) for (p, f) in DEFAULT_PATTERNS.items()] default_patterns = [u"%s:%s" % (p or '', f.__name__[:-1]) for (p, f) in DEFAULT_PATTERNS.items()]
no_defaults_vars = dict(default_patterns='\n'.join([u">>> %s" % pattern for pattern in default_patterns])) no_defaults_vars = dict(default_patterns='\n'.join([u">>> %s" % pattern for pattern in default_patterns]))
no_defaults_help = u"""\ no_defaults_help = u"""\
Ne pas ajouter les patterns par défaut. Sans cette option, les patterns par défaut sont: Ne pas ajouter les patterns par défaut à ceux définis par l'option --pattern. Sans cette option, les patterns par défaut sont:
%(default_patterns)s""" % no_defaults_vars %(default_patterns)s""" % no_defaults_vars
follow_help = u"""Suivre le contenu du fichier spécifié""" follow_help = u"""Suivre le contenu du fichier spécifié"""
presets_help = u"""Utiliser un ensemble prédéfini de paramètres. presets_help = u"""Utiliser un ensemble prédéfini de paramètres.
@ -165,6 +173,7 @@ Si cet argument n'est pas spécifié, l'entrée standard est utilisée comme sou
AP.set_defaults(inputfile=None, follow=False, patterns=None, defaults=True, presets=None) AP.set_defaults(inputfile=None, follow=False, patterns=None, defaults=True, presets=None)
AP.add_argument('-e', '--pattern', action='append', dest='patterns', metavar='PATTERN:FORMAT', help=pattern_help) AP.add_argument('-e', '--pattern', action='append', dest='patterns', metavar='PATTERN:FORMAT', help=pattern_help)
AP.add_argument('-z', '--no-defaults', action='store_false', dest='defaults', help=no_defaults_help) AP.add_argument('-z', '--no-defaults', action='store_false', dest='defaults', help=no_defaults_help)
AP.add_argument('-d', '--defaults', action='store_true', dest='defaults', help=no_defaults_help)
AP.add_argument('-f', '--follow', action='store_true', dest='follow', help=follow_help) AP.add_argument('-f', '--follow', action='store_true', dest='follow', help=follow_help)
AP.add_argument('-p', '--presets', action='store', dest='presets', help=presets_help) AP.add_argument('-p', '--presets', action='store', dest='presets', help=presets_help)
AP.add_argument('inputfile', metavar='INPUTFILE', nargs='?', help=inputfile_help) AP.add_argument('inputfile', metavar='INPUTFILE', nargs='?', help=inputfile_help)
@ -174,29 +183,38 @@ Si cet argument n'est pas spécifié, l'entrée standard est utilisée comme sou
presets = PRESET_ALIASES.get(o.presets, o.presets) presets = PRESET_ALIASES.get(o.presets, o.presets)
if presets not in PRESETS: if presets not in PRESETS:
raise ValueError("%s: argument invalide" % presets) raise ValueError("%s: argument invalide" % presets)
inputfile, follow, patterns = PRESETS.get(presets) inputfile, follow, opatterns, odefaults = PRESETS.get(presets)
else: else:
inputfile, follow, patterns = o.inputfile, o.follow, o.patterns inputfile, follow, opatterns, odefaults = o.inputfile, o.follow, o.patterns, o.defaults
if patterns is None: if opatterns is None:
patterns = DEFAULT_PATTERNS patterns = DEFAULT_PATTERNS
elif o.patterns is not None: else:
patterns = OrderedDict() patterns = OrderedDict()
for pf in o.patterns: for pf in opatterns:
mo = re.match('(.*):([a-zA-Z]*)$', pf) mo = re.match('(.*):([a-zA-Z,]*)$', pf)
if mo is not None: if mo is not None:
p = mo.group(1) p = mo.group(1)
of = mo.group(2) ofs = mo.group(2)
else: else:
p = pf p = pf
of = 'red' ofs = 'red'
if p == '': p = None if p == '': p = None
f = of.lower() ofs = filter(None, ofs.lower().split(','))
f = FORMAT_ALIASES.get(f, f) fs = None
for of in ofs:
f = FORMAT_ALIASES.get(of, of)
if f not in FORMATS: if f not in FORMATS:
raise ValueError("%s: format invalide" % of) raise ValueError("%s: format invalide" % of)
patterns[p] = FORMATS[f] f = FORMATS[f]
if o.defaults: if fs is None:
fs = f
else:
def wrapf(line, mo, curf=f, prevf=fs):
return curf(prevf(line, mo))
fs = wrapf
patterns[p] = fs
if odefaults:
for p, f in DEFAULT_PATTERNS.items(): for p, f in DEFAULT_PATTERNS.items():
patterns.setdefault(p, f) patterns.setdefault(p, f)