def create_native_stderr_log_handler( log_level: LogLevel, native: Native, stream: Optional[TextIO] = None) -> NativeHandler: try: native.setup_stderr_logger(log_level.level) except Exception as e: print(f"Error setting up pantsd logger: {e!r}", file=sys.stderr) raise e return NativeHandler(log_level, native, stream)
class NativeHandler(StreamHandler): """This class is installed as a Python logging module handler (using the logging.addHandler method) and proxies logs to the Rust logging infrastructure.""" def __init__( self, log_level: LogLevel, stream: Optional[TextIO] = None, native_filename: Optional[str] = None, ): if stream is not None and native_filename is not None: raise RuntimeError("NativeHandler must output to either a stream or a file, not both") super().__init__(stream) self.native = Native() self.native_filename = native_filename self.setLevel(log_level.level) if stream: try: self.native.setup_stderr_logger(log_level.level) except Exception as e: print(f"Error setting up pantsd logger: {e!r}", file=sys.stderr) raise e def emit(self, record: LogRecord) -> None: self.native.write_log( self.format(record), record.levelno, f"{record.name}:pid={os.getpid()}" ) def flush(self) -> None: self.native.flush_log() def __repr__(self) -> str: return ( f"NativeHandler(id={id(self)}, level={self.level}, filename={self.native_filename}, " f"stream={self.stream})" )