diff options
author | Russell Power <power@google.com> | 2018-10-03 10:39:07 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-10-03 10:43:30 -0700 |
commit | af1458a9c1a3bc8d49a1e55386950b4941ab1815 (patch) | |
tree | 6565231138814b8fe56a6122b2228fa34de72133 /tensorflow/python/platform | |
parent | 26ce26d127587bc1f5dc7950e22f7d935d372abf (diff) |
Fix filename/line number lookup for logging.
Log messages now show the correct file/function name/line number instead of that of the helper function.
PiperOrigin-RevId: 215586852
Diffstat (limited to 'tensorflow/python/platform')
-rw-r--r-- | tensorflow/python/platform/tf_logging.py | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/tensorflow/python/platform/tf_logging.py b/tensorflow/python/platform/tf_logging.py index 5962d2f220..59e60856ae 100644 --- a/tensorflow/python/platform/tf_logging.py +++ b/tensorflow/python/platform/tf_logging.py @@ -25,6 +25,7 @@ import logging as _logging import os as _os import sys as _sys import time as _time +import traceback as _traceback from logging import DEBUG from logging import ERROR from logging import FATAL @@ -36,13 +37,49 @@ import six from tensorflow.python.util.tf_export import tf_export - # Don't use this directly. Use _get_logger() instead. _logger = None _logger_lock = threading.Lock() +def _get_caller(offset=3): + """Returns a code and frame object for the lowest non-logging stack frame.""" + # Use sys._getframe(). This avoids creating a traceback object. + # pylint: disable=protected-access + f = _sys._getframe(offset) + # pylint: enable=protected-access + our_file = f.f_code.co_filename + f = f.f_back + while f: + code = f.f_code + if code.co_filename != our_file: + return code, f + f = f.f_back + return None, None + + +# The definition of `findCaller` changed in Python 3.2 +if _sys.version_info.major >= 3 and _sys.version_info.minor >= 2: + def _logger_find_caller(stack_info=False): # pylint: disable=g-wrong-blank-lines + code, frame = _get_caller(4) + sinfo = None + if stack_info: + sinfo = '\n'.join(_traceback.format_stack()) + if code: + return (code.co_filename, frame.f_lineno, code.co_name, sinfo) + else: + return '(unknown file)', 0, '(unknown function)', sinfo +else: + def _logger_find_caller(): # pylint: disable=g-wrong-blank-lines + code, frame = _get_caller(4) + if code: + return (code.co_filename, frame.f_lineno, code.co_name) + else: + return '(unknown file)', 0, '(unknown function)' + + def _get_logger(): + """Return TF logger instance.""" global _logger # Use double-checked locking to avoid taking lock unnecessarily. @@ -58,6 +95,9 @@ def _get_logger(): # Scope the TensorFlow logger to not conflict with users' loggers. logger = _logging.getLogger('tensorflow') + # Override findCaller on the logger to skip internal helper functions + logger.findCaller = _logger_find_caller + # Don't further configure the TensorFlow logger if the root logger is # already configured. This prevents double logging in those cases. if not _logging.getLogger().handlers: @@ -216,18 +256,10 @@ def log_if(level, msg, condition, *args): def _GetFileAndLine(): """Returns (filename, linenumber) for the stack frame.""" - # Use sys._getframe(). This avoids creating a traceback object. - # pylint: disable=protected-access - f = _sys._getframe() - # pylint: enable=protected-access - our_file = f.f_code.co_filename - f = f.f_back - while f: - code = f.f_code - if code.co_filename != our_file: - return (code.co_filename, f.f_lineno) - f = f.f_back - return ('<unknown>', 0) + code, f = _get_caller() + if not code: + return ('<unknown>', 0) + return (code.co_filename, f.f_lineno) def google2_log_prefix(level, timestamp=None, file_and_line=None): |