1 # Copyright 2015 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 """tensorboard_logging provides logging that is also written to the events file. 16 17 Any messages logged via this module will be logged both via the platform logging 18 mechanism and to the SummaryWriter set via `set_summary_writer`. This is useful 19 for logging messages that you might want to be visible from inside TensorBoard 20 or that should be permanently associated with the training session. 21 22 You can use this just like the logging module: 23 24 >>> tensorboard_logging.set_summary_writer(summary_writer) 25 >>> tensorboard_logging.info("my %s", "message") 26 >>> tensorboard_logging.log(tensorboard_logging.WARN, "something") 27 """ 28 29 from __future__ import absolute_import 30 from __future__ import division 31 from __future__ import print_function 32 33 import time 34 35 from tensorflow.core.util import event_pb2 36 from tensorflow.python.platform import tf_logging as logging 37 38 DEBUG = 'DEBUG' 39 INFO = 'INFO' 40 WARN = 'WARN' 41 ERROR = 'ERROR' 42 FATAL = 'FATAL' 43 44 # Messages with levels below this verbosity will not be logged. 45 _verbosity = WARN 46 47 # A value meaning 'not set yet' so we can use None to mean 'user actively told 48 # us they don't want a SummaryWriter'. 49 _sentinel_summary_writer = object() 50 51 # The SummaryWriter instance to use when logging, or None to not log, or 52 # _sentinel_summary_writer to indicate that the user hasn't called 53 # set_summary_writer yet. 54 _summary_writer = _sentinel_summary_writer 55 56 # Map from the tensorboard_logging logging enum values to the proto's enum 57 # values. 58 _LEVEL_PROTO_MAP = { 59 DEBUG: event_pb2.LogMessage.DEBUGGING, 60 INFO: event_pb2.LogMessage.INFO, 61 WARN: event_pb2.LogMessage.WARN, 62 ERROR: event_pb2.LogMessage.ERROR, 63 FATAL: event_pb2.LogMessage.FATAL, 64 } 65 66 # Map from the tensorboard_logging module levels to the logging module levels. 67 _PLATFORM_LOGGING_LEVEL_MAP = { 68 DEBUG: logging.DEBUG, 69 INFO: logging.INFO, 70 WARN: logging.WARN, 71 ERROR: logging.ERROR, 72 FATAL: logging.FATAL 73 } 74 75 76 def get_verbosity(): 77 return _verbosity 78 79 80 def set_verbosity(verbosity): 81 _check_verbosity(verbosity) 82 global _verbosity 83 _verbosity = verbosity 84 85 86 def _check_verbosity(verbosity): 87 if verbosity not in _LEVEL_PROTO_MAP: 88 raise ValueError('Level %s is not a valid tensorboard_logging level' % 89 verbosity) 90 91 92 def set_summary_writer(summary_writer): 93 """Sets the summary writer that events will be logged to. 94 95 Calling any logging methods inside this module without calling this method 96 will fail. If you don't want to log, call `set_summary_writer(None)`. 97 98 Args: 99 summary_writer: Either a SummaryWriter or None. None will cause messages not 100 to be logged to any SummaryWriter, but they will still be passed to the 101 platform logging module. 102 """ 103 global _summary_writer 104 _summary_writer = summary_writer 105 106 107 def _clear_summary_writer(): 108 """Makes all subsequent log invocations error. 109 110 This is only used for testing. If you want to disable TensorBoard logging, 111 call `set_summary_writer(None)` instead. 112 """ 113 global _summary_writer 114 _summary_writer = _sentinel_summary_writer 115 116 117 def log(level, message, *args): 118 """Conditionally logs `message % args` at the level `level`. 119 120 Note that tensorboard_logging verbosity and logging verbosity are separate; 121 the message will always be passed through to the logging module regardless of 122 whether it passes the tensorboard_logging verbosity check. 123 124 Args: 125 level: The verbosity level to use. Must be one of 126 tensorboard_logging.{DEBUG, INFO, WARN, ERROR, FATAL}. 127 message: The message template to use. 128 *args: Arguments to interpolate to the message template, if any. 129 130 Raises: 131 ValueError: If `level` is not a valid logging level. 132 RuntimeError: If the `SummaryWriter` to use has not been set. 133 """ 134 if _summary_writer is _sentinel_summary_writer: 135 raise RuntimeError('Must call set_summary_writer before doing any ' 136 'logging from tensorboard_logging') 137 _check_verbosity(level) 138 proto_level = _LEVEL_PROTO_MAP[level] 139 if proto_level >= _LEVEL_PROTO_MAP[_verbosity]: 140 log_message = event_pb2.LogMessage(level=proto_level, 141 message=message % args) 142 event = event_pb2.Event(wall_time=time.time(), log_message=log_message) 143 144 if _summary_writer: 145 _summary_writer.add_event(event) 146 147 logging.log(_PLATFORM_LOGGING_LEVEL_MAP[level], message, *args) 148 149 150 def debug(message, *args): 151 log(DEBUG, message, *args) 152 153 154 def info(message, *args): 155 log(INFO, message, *args) 156 157 158 def warn(message, *args): 159 log(WARN, message, *args) 160 161 162 def error(message, *args): 163 log(ERROR, message, *args) 164 165 166 def fatal(message, *args): 167 log(FATAL, message, *args) 168