1# Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Logging and debugging utilities.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21import os 22import sys 23import traceback 24 25# TODO(mdan): Use a custom logger class. 26from tensorflow.python.platform import tf_logging as logging 27from tensorflow.python.util.tf_export import tf_export 28 29VERBOSITY_VAR_NAME = 'AUTOGRAPH_VERBOSITY' 30DEFAULT_VERBOSITY = 0 31 32verbosity_level = None # vlog-like. Takes precedence over the env variable. 33echo_log_to_stdout = False 34 35# In interactive Python, logging echo is enabled by default. 36if hasattr(sys, 'ps1') or hasattr(sys, 'ps2'): 37 echo_log_to_stdout = True 38 39 40@tf_export('autograph.set_verbosity') 41def set_verbosity(level, alsologtostdout=False): 42 """Sets the AutoGraph verbosity level. 43 44 _Debug logging in AutoGraph_ 45 46 More verbose logging is useful to enable when filing bug reports or doing 47 more in-depth debugging. 48 49 There are two means to control the logging verbosity: 50 51 * The `set_verbosity` function 52 53 * The `AUTOGRAPH_VERBOSITY` environment variable 54 55 `set_verbosity` takes precedence over the environment variable. 56 57 For example: 58 59 ```python 60 import os 61 import tensorflow as tf 62 63 os.environ['AUTOGRAPH_VERBOSITY'] = 5 64 # Verbosity is now 5 65 66 tf.autograph.set_verbosity(0) 67 # Verbosity is now 0 68 69 os.environ['AUTOGRAPH_VERBOSITY'] = 1 70 # No effect, because set_verbosity was already called. 71 ``` 72 73 Logs entries are output to [absl](https://abseil.io)'s 74 [default output](https://abseil.io/docs/python/guides/logging), 75 with `INFO` level. 76 Logs can be mirrored to stdout by using the `alsologtostdout` argument. 77 Mirroring is enabled by default when Python runs in interactive mode. 78 79 Args: 80 level: int, the verbosity level; larger values specify increased verbosity; 81 0 means no logging. When reporting bugs, it is recommended to set this 82 value to a larger number, like 10. 83 alsologtostdout: bool, whether to also output log messages to `sys.stdout`. 84 """ 85 global verbosity_level 86 global echo_log_to_stdout 87 verbosity_level = level 88 echo_log_to_stdout = alsologtostdout 89 90 91@tf_export('autograph.trace') 92def trace(*args): 93 """Traces argument information at compilation time. 94 95 `trace` is useful when debugging, and it always executes during the tracing 96 phase, that is, when the TF graph is constructed. 97 98 _Example usage_ 99 100 ```python 101 import tensorflow as tf 102 103 for i in tf.range(10): 104 tf.autograph.trace(i) 105 # Output: <Tensor ...> 106 ``` 107 108 Args: 109 *args: Arguments to print to `sys.stdout`. 110 """ 111 print(*args) 112 113 114def get_verbosity(): 115 global verbosity_level 116 if verbosity_level is not None: 117 return verbosity_level 118 return int(os.getenv(VERBOSITY_VAR_NAME, DEFAULT_VERBOSITY)) 119 120 121def has_verbosity(level): 122 return get_verbosity() >= level 123 124 125def _output_to_stdout(msg, *args, **kwargs): 126 print(msg % args) 127 if kwargs.get('exc_info', False): 128 traceback.print_exc() 129 130 131def error(level, msg, *args, **kwargs): 132 if has_verbosity(level): 133 logging.error(msg, *args, **kwargs) 134 if echo_log_to_stdout: 135 _output_to_stdout('ERROR: ' + msg, *args, **kwargs) 136 137 138def log(level, msg, *args, **kwargs): 139 if has_verbosity(level): 140 logging.info(msg, *args, **kwargs) 141 if echo_log_to_stdout: 142 _output_to_stdout(msg, *args, **kwargs) 143 144 145def warn(msg, *args, **kwargs): 146 logging.warn(msg, *args, **kwargs) 147 if echo_log_to_stdout: 148 _output_to_stdout('WARNING: ' + msg, *args, **kwargs) 149 sys.stdout.flush() 150