Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support inheritance log_format for child configs #95

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 60 additions & 5 deletions ngxtop/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,21 +105,76 @@ def detect_log_config(arguments):
error_exit('Access log file is not provided and ngxtop cannot detect it from your config file (%s).' % config)

log_formats = dict(get_log_formats(config_str))

nginx_global_config = detect_config_path()
with open(nginx_global_config) as f:
nginx_global_config_str = f.read()

nginx_global_log_formats = dict(get_log_formats(nginx_global_config_str))

if len(access_logs) == 1:
log_path, format_name = list(access_logs.items())[0]
if format_name == 'combined':
return log_path, LOG_FORMAT_COMBINED
if format_name not in log_formats:
if format_name not in dict(list(log_formats.items()) + list(nginx_global_log_formats.items())):
error_exit('Incorrect format name set in config for access log file "%s"' % log_path)
return log_path, log_formats[format_name]

if log_formats.get(format_name):
return log_path, log_formats[format_name]
else:
return log_path, nginx_global_log_formats[format_name]

if arguments['--access-log']:
log_path = arguments['--access-log']
format_name = access_logs[log_path]
if format_name not in dict(list(log_formats.items()) + list(nginx_global_log_formats.items())):
error_exit('Incorrect format name set in config for access log file "%s"' % log_path)
if log_formats.get(format_name):
return log_path, log_formats[format_name]
else:
return log_path, nginx_global_log_formats[format_name]

# multiple access logs configured, offer to select one
print('Multiple access logs detected in configuration:')
log_path = choose_one(list(access_logs.keys()), 'Select access log file to process: ')
format_name = access_logs[log_path]
if format_name not in log_formats:
if format_name not in dict(list(log_formats.items()) + list(nginx_global_log_formats.items())):
error_exit('Incorrect format name set in config for access log file "%s"' % log_path)
return log_path, log_formats[format_name]
if log_formats.get(format_name):
return log_path, log_formats[format_name]
else:
return log_path, nginx_global_log_formats[format_name]


def detect_log_config_by_name(arguments):
"""
Detect access log config (format) on nginx site. Offer user to select if multiple configs are detected.
:return: detected / selected config
"""
log_config = dict(detect_logs_configs_by_name(arguments))
if len(log_config) == 0:
error_exit('Config file for access log "%s" not found' % access_log)
elif len(log_config) > 1:
print('Multiple configs detected:')
configfile = choose_one(list(log_config.keys()), 'Select config file to process: ')
else:
configfile = list(log_config.keys())[0]
return configfile


def detect_logs_configs_by_name(arguments):
"""
Detect access log configs (format) on nginx site.
:return: iterator over ('detected config', 'detected config') tuple of found configs
"""
nginx_global_config_path = os.path.dirname(detect_config_path())
try:
proc = subprocess.Popen(['grep', '-r', arguments['--access-log'], nginx_global_config_path], stdout=subprocess.PIPE)
except Exception as e:
print(e)
stdout = proc.communicate()[0]
output = stdout#.decode('utf-8')
for conf in re.finditer(r'(\S*):\s*access_log', output):
yield conf.group(1), conf.group(1)


def build_pattern(log_format):
Expand Down
7 changes: 5 additions & 2 deletions ngxtop/ngxtop.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
ngxtop [options] query <query> ...

Options:
-l <file>, --access-log <file> access log file to parse.
-l <file>, --access-log <file> access log file to parse (full path!!! or use $PWD/).
-f <format>, --log-format <format> log format as specify in log_format directive. [default: combined]
--no-follow ngxtop default behavior is to ignore current lines in log
and only watch for new lines as they are written to the access log.
Expand Down Expand Up @@ -74,7 +74,7 @@
from docopt import docopt
import tabulate

from .config_parser import detect_log_config, detect_config_path, extract_variables, build_pattern
from .config_parser import detect_log_config, detect_config_path, extract_variables, build_pattern, detect_log_config_by_name
from .utils import error_exit


Expand Down Expand Up @@ -350,6 +350,9 @@ def process(arguments):
access_log = 'stdin'
if access_log is None:
access_log, log_format = detect_log_config(arguments)
if access_log is not None and arguments.get('--config') is None and not arguments.get('info'):
arguments['--config'] = detect_log_config_by_name(arguments)
access_log, log_format = detect_log_config(arguments)

logging.info('access_log: %s', access_log)
logging.info('log_format: %s', log_format)
Expand Down
2 changes: 0 additions & 2 deletions ngxtop/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ def choose_one(choices, prompt):
for idx, choice in enumerate(choices):
print('%d. %s' % (idx + 1, choice))
selected = None
if sys.version[0] == '3':
raw_input = input
while not selected or selected <= 0 or selected > len(choices):
selected = raw_input(prompt)
try:
Expand Down