def __init__(self, file_name): super().__init__(file_name) self._writer = None self._fieldnames = None self._warned_once = set() self._disable_warnings = False self.tabular = TabularInput()
class TextOutput(FileOutput): """Text file output for logger. :param file_name: The file this output should log to. :param with_timestamp: Whether to log a timestamp before the data. """ def __init__(self, file_name, with_timestamp=True): super().__init__(file_name, 'a') self._with_timestamp = with_timestamp self.tabular = TabularInput() @property def types_accepted(self): """Accept str and scalar objects.""" return (str, ) + np.ScalarType @property def keys_accepted(self): """Accept all keys.""" return r'^' def record(self, key, value, prefix=''): """Log data to text file.""" if not key: if isinstance(value, str): out = prefix + value if self._with_timestamp: now = datetime.datetime.now(dateutil.tz.tzlocal()) timestamp = now.strftime('%Y-%m-%d %H:%M:%S') out = '%s | %s' % (timestamp, out) self._log_file.write(out + '\n') else: raise ValueError('Unacceptable type') else: self.tabular.record(key, value) def dump(self, step=None): """Flush data to log file.""" if not self.tabular.empty: self._log_file.write(str(self.tabular) + '\n') self.tabular.clear() self._log_file.flush()
class StdOutput(LogOutput): """Standard console output for the logger. :param with_timestamp: Whether to log a timestamp before non-tabular data. """ def __init__(self, with_timestamp=True): self._with_timestamp = with_timestamp self.tabular = TabularInput() @property def types_accepted(self): """Accept str and scalar objects.""" return (str, ) + np.ScalarType @property def keys_accepted(self): """Accept all keys.""" return r'^' def record(self, key, value, prefix=''): """Log data to console.""" if not key: if isinstance(value, str): out = prefix + value if self._with_timestamp: now = datetime.datetime.now(dateutil.tz.tzlocal()) timestamp = now.strftime('%Y-%m-%d %H:%M:%S') out = '%s | %s' % (timestamp, out) print(out) else: raise ValueError('Unacceptable type') else: self.tabular.record(key, value) def dump(self, step=None): """Flush data to standard output stream.""" if not self.tabular.empty: print(str(self.tabular)) self.tabular.clear() sys.stdout.flush()
def __init__(self, file_name, with_timestamp=True): super().__init__(file_name, 'a') self._with_timestamp = with_timestamp self.tabular = TabularInput()
def __init__(self, with_timestamp=True): self._with_timestamp = with_timestamp self.tabular = TabularInput()
class CsvOutput(FileOutput): """CSV file output for logger. :param file_name: The file this output should log to. """ def __init__(self, file_name): super().__init__(file_name) self._writer = None self._fieldnames = None self._warned_once = set() self._disable_warnings = False self.tabular = TabularInput() @property def types_accepted(self): """Accept str and scalar objects.""" return (str, ) + np.ScalarType @property def keys_accepted(self): """Accept all keys.""" return r'^' def record(self, key, value, prefix=''): """Log data to a csv file.""" self.tabular.record(key, value) def dump(self, step=None): """Flush data to log file.""" if self.tabular.empty: return to_csv = self.tabular.as_primitive_dict if not to_csv.keys() and not self._writer: return if not self._writer: self._fieldnames = set(to_csv.keys()) self._writer = csv.DictWriter(self._log_file, fieldnames=self._fieldnames, extrasaction='ignore') self._writer.writeheader() if to_csv.keys() != self._fieldnames: self._warn('Inconsistent TabularInput keys detected. ' 'CsvOutput keys: {}. ' 'TabularInput keys: {}. ' 'Did you change key sets after your first ' 'logger.log(TabularInput)?'.format( set(self._fieldnames), set(to_csv.keys()))) self._writer.writerow(to_csv) self._log_file.flush() self.tabular.clear() def _warn(self, msg): """Warns the user using warnings.warn. The stacklevel parameter needs to be 3 to ensure the call to logger.log is the one printed. """ if not self._disable_warnings and msg not in self._warned_once: warnings.warn(colorize(msg, 'yellow'), CsvOutputWarning, stacklevel=3) self._warned_once.add(msg) return msg def disable_warnings(self): """Disable logger warnings for testing.""" self._disable_warnings = True
"""Logger module. This module instantiates a global logger singleton. """ from dowel.histogram import Histogram from dowel.logger import Logger, LoggerWarning, LogOutput from dowel.simple_outputs import StdOutput, TextOutput from dowel.tabular_input import TabularInput from dowel.csv_output import CsvOutput # noqa: I100 from dowel.tensor_board_output import TensorBoardOutput logger = Logger() tabular = TabularInput() __all__ = [ 'Histogram', 'Logger', 'CsvOutput', 'StdOutput', 'TextOutput', 'LogOutput', 'LoggerWarning', 'TabularInput', 'TensorBoardOutput', 'logger', 'tabular', ]