- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
939 lines
26 KiB
Python
939 lines
26 KiB
Python
"""
|
|
Java java.util.logging standard library APIs implemented in Python.
|
|
java.util.logging package - Logger, Level, Handler, Formatter, etc.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .._core import Stub
|
|
from .lang import RuntimeException, Exception as _JavaException
|
|
from .security import BasicPermission
|
|
import typing as _typing
|
|
import sys as _sys
|
|
import datetime as _datetime
|
|
import io as _io
|
|
import threading as _threading
|
|
import traceback as _traceback
|
|
import os as _os
|
|
|
|
__all__ = [
|
|
"Logger", "Level",
|
|
"Handler", "ConsoleHandler", "FileHandler", "StreamHandler",
|
|
"SocketHandler", "MemoryHandler",
|
|
"Formatter", "SimpleFormatter", "XMLFormatter",
|
|
"LogRecord", "LogManager", "Filter", "ErrorManager",
|
|
"LoggingMXBean", "LoggingPermission",
|
|
"OFF", "SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "FINER", "FINEST", "ALL",
|
|
]
|
|
|
|
import sys as _sys
|
|
import threading as _threading
|
|
|
|
|
|
# ============================================================
|
|
# Level Constants
|
|
# ============================================================
|
|
|
|
class _Integer:
|
|
"""Wrapper to emulate Integer.MIN_VALUE / MAX_VALUE"""
|
|
MIN_VALUE = -2147483648
|
|
MAX_VALUE = 2147483647
|
|
|
|
|
|
OFF = _Integer.MAX_VALUE
|
|
SEVERE = 1000
|
|
WARNING = 900
|
|
INFO = 800
|
|
CONFIG = 700
|
|
FINE = 500
|
|
FINER = 400
|
|
FINEST = 300
|
|
ALL = _Integer.MIN_VALUE
|
|
|
|
|
|
# ============================================================
|
|
# Level
|
|
# ============================================================
|
|
|
|
class Level(Stub):
|
|
"""java.util.logging.Level"""
|
|
def __init__(self, name, value, resource_bundle_name=None):
|
|
super().__init__()
|
|
self._name = name
|
|
self._value = value
|
|
self._resource_bundle_name = resource_bundle_name
|
|
|
|
def getName(self):
|
|
return self._name
|
|
|
|
def intValue(self):
|
|
return self._value
|
|
|
|
def getResourceBundleName(self):
|
|
return self._resource_bundle_name
|
|
|
|
def toString(self):
|
|
return self._name
|
|
|
|
def hashCode(self):
|
|
return self._value
|
|
|
|
def equals(self, other):
|
|
if not isinstance(other, Level):
|
|
return False
|
|
return self._value == other._value
|
|
|
|
def parse(self, name):
|
|
name_upper = name.upper()
|
|
level_map = {
|
|
"OFF": Level.OFF,
|
|
"SEVERE": Level.SEVERE,
|
|
"WARNING": Level.WARNING,
|
|
"INFO": Level.INFO,
|
|
"CONFIG": Level.CONFIG,
|
|
"FINE": Level.FINE,
|
|
"FINER": Level.FINER,
|
|
"FINEST": Level.FINEST,
|
|
"ALL": Level.ALL,
|
|
}
|
|
if name_upper in level_map:
|
|
return level_map[name_upper]
|
|
try:
|
|
return Level(name, int(name))
|
|
except ValueError:
|
|
raise IllegalArgumentException(f"Bad level name: {name}")
|
|
|
|
def __lt__(self, other):
|
|
if isinstance(other, Level):
|
|
return self._value < other._value
|
|
return NotImplemented
|
|
|
|
def __le__(self, other):
|
|
if isinstance(other, Level):
|
|
return self._value <= other._value
|
|
return NotImplemented
|
|
|
|
def __gt__(self, other):
|
|
if isinstance(other, Level):
|
|
return self._value > other._value
|
|
return NotImplemented
|
|
|
|
def __ge__(self, other):
|
|
if isinstance(other, Level):
|
|
return self._value >= other._value
|
|
return NotImplemented
|
|
|
|
# Static level instances
|
|
OFF = None
|
|
SEVERE = None
|
|
WARNING = None
|
|
INFO = None
|
|
CONFIG = None
|
|
FINE = None
|
|
FINER = None
|
|
FINEST = None
|
|
ALL = None
|
|
|
|
|
|
# ============================================================
|
|
# Initialize static Level instances
|
|
# ============================================================
|
|
|
|
Level.OFF = Level("OFF", _Integer.MAX_VALUE)
|
|
Level.SEVERE = Level("SEVERE", 1000)
|
|
Level.WARNING = Level("WARNING", 900)
|
|
Level.INFO = Level("INFO", 800)
|
|
Level.CONFIG = Level("CONFIG", 700)
|
|
Level.FINE = Level("FINE", 500)
|
|
Level.FINER = Level("FINER", 400)
|
|
Level.FINEST = Level("FINEST", 300)
|
|
Level.ALL = Level("ALL", _Integer.MIN_VALUE)
|
|
|
|
|
|
# ============================================================
|
|
# LogRecord
|
|
# ============================================================
|
|
|
|
class LogRecord(Stub):
|
|
"""java.util.logging.LogRecord"""
|
|
def __init__(self, level, msg):
|
|
super().__init__()
|
|
self._level = level if isinstance(level, Level) else Level.INFO
|
|
self._logger_name = ""
|
|
self._message = msg
|
|
self._millis = _datetime.datetime.now().timestamp() * 1000
|
|
self._thread_id = _threading.get_ident()
|
|
self._source_class_name = None
|
|
self._source_method_name = None
|
|
self._thrown = None
|
|
self._parameters = None
|
|
self._resource_bundle = None
|
|
self._resource_bundle_name = None
|
|
self._sequence_number = id(self)
|
|
self._long_thread_id = _threading.get_ident()
|
|
|
|
def getLevel(self):
|
|
return self._level
|
|
|
|
def setLevel(self, level):
|
|
self._level = level
|
|
|
|
def getLoggerName(self):
|
|
return self._logger_name
|
|
|
|
def setLoggerName(self, name):
|
|
self._logger_name = name
|
|
|
|
def getMessage(self):
|
|
return self._message
|
|
|
|
def setMessage(self, msg):
|
|
self._message = msg
|
|
|
|
def getMillis(self):
|
|
return self._millis
|
|
|
|
def setMillis(self, millis):
|
|
self._millis = millis
|
|
|
|
def getThreadID(self):
|
|
return self._thread_id
|
|
|
|
def setThreadID(self, thread_id):
|
|
self._thread_id = thread_id
|
|
|
|
def getSourceClassName(self):
|
|
return self._source_class_name
|
|
|
|
def setSourceClassName(self, name):
|
|
self._source_class_name = name
|
|
|
|
def getSourceMethodName(self):
|
|
return self._source_method_name
|
|
|
|
def setSourceMethodName(self, name):
|
|
self._source_method_name = name
|
|
|
|
def getThrown(self):
|
|
return self._thrown
|
|
|
|
def setThrown(self, thrown):
|
|
self._thrown = thrown
|
|
|
|
def getParameters(self):
|
|
return self._parameters
|
|
|
|
def setParameters(self, params):
|
|
self._parameters = params
|
|
|
|
def getResourceBundle(self):
|
|
return self._resource_bundle
|
|
|
|
def setResourceBundle(self, bundle):
|
|
self._resource_bundle = bundle
|
|
|
|
def getResourceBundleName(self):
|
|
return self._resource_bundle_name
|
|
|
|
def setResourceBundleName(self, name):
|
|
self._resource_bundle_name = name
|
|
|
|
def getSequenceNumber(self):
|
|
return self._sequence_number
|
|
|
|
def setSequenceNumber(self, seq):
|
|
self._sequence_number = seq
|
|
|
|
def getLongThreadID(self):
|
|
return self._long_thread_id
|
|
|
|
def setLongThreadID(self, thread_id):
|
|
self._long_thread_id = thread_id
|
|
|
|
|
|
# ============================================================
|
|
# Filter
|
|
# ============================================================
|
|
|
|
class Filter(Stub):
|
|
"""java.util.logging.Filter"""
|
|
def isLoggable(self, record):
|
|
return True
|
|
|
|
|
|
# ============================================================
|
|
# Formatter
|
|
# ============================================================
|
|
|
|
class Formatter(Stub):
|
|
"""java.util.logging.Formatter"""
|
|
def format(self, record):
|
|
raise NotImplementedError
|
|
|
|
def getHead(self, handler):
|
|
return ""
|
|
|
|
def getTail(self, handler):
|
|
return ""
|
|
|
|
def formatMessage(self, record):
|
|
msg = record.getMessage()
|
|
params = record.getParameters()
|
|
if params:
|
|
try:
|
|
return msg % params
|
|
except Exception:
|
|
pass
|
|
return msg
|
|
|
|
|
|
class SimpleFormatter(Formatter):
|
|
"""java.util.logging.SimpleFormatter"""
|
|
def format(self, record):
|
|
import datetime as dt
|
|
ts = dt.datetime.fromtimestamp(record.getMillis() / 1000.0)
|
|
ts_str = ts.strftime("%Y-%m-%d %H:%M:%S")
|
|
msg = self.formatMessage(record)
|
|
thrown = record.getThrown()
|
|
result = f"{ts_str} {record.getLevel().getName()} {record.getLoggerName()}: {msg}"
|
|
if thrown is not None:
|
|
result += "\n" + "".join(_traceback.format_exception(
|
|
type(thrown), thrown, getattr(thrown, '__traceback__', None)
|
|
))
|
|
return result
|
|
|
|
|
|
class XMLFormatter(Formatter):
|
|
"""java.util.logging.XMLFormatter"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
from xml.sax.saxutils import escape
|
|
|
|
def format(self, record):
|
|
ts = _datetime.datetime.fromtimestamp(record.getMillis() / 1000.0)
|
|
ts_str = ts.strftime("%Y-%m-%dT%H:%M:%S")
|
|
from xml.sax.saxutils import escape
|
|
msg = escape(self.formatMessage(record))
|
|
logger_name = escape(record.getLoggerName() or "")
|
|
level_name = record.getLevel().getName()
|
|
|
|
parts = [
|
|
"<record>",
|
|
f" <date>{ts_str}</date>",
|
|
f" <millis>{int(record.getMillis())}</millis>",
|
|
f" <sequence>{record.getSequenceNumber()}</sequence>",
|
|
f" <logger>{logger_name}</logger>",
|
|
f" <level>{level_name}</level>",
|
|
f" <class>{escape(record.getSourceClassName() or '')}</class>",
|
|
f" <method>{escape(record.getSourceMethodName() or '')}</method>",
|
|
f" <thread>{record.getThreadID()}</thread>",
|
|
f" <message>{msg}</message>",
|
|
]
|
|
|
|
thrown = record.getThrown()
|
|
if thrown is not None:
|
|
import traceback
|
|
tb_str = "".join(traceback.format_exception(
|
|
type(thrown), thrown, getattr(thrown, '__traceback__', None)
|
|
))
|
|
parts.append(f" <exception>{escape(tb_str)}</exception>")
|
|
|
|
parts.append("</record>")
|
|
return "\n".join(parts)
|
|
|
|
def getHead(self, handler):
|
|
return '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE log SYSTEM "logger.dtd">\n<log>\n'
|
|
|
|
def getTail(self, handler):
|
|
return "</log>\n"
|
|
|
|
|
|
# ============================================================
|
|
# ErrorManager
|
|
# ============================================================
|
|
|
|
class ErrorManager(Stub):
|
|
"""java.util.logging.ErrorManager"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def error(self, message, exception, error_code):
|
|
_sys.stderr.write(f"ErrorManager: {message}\n")
|
|
if exception:
|
|
_traceback.print_exception(type(exception), exception,
|
|
getattr(exception, '__traceback__', None))
|
|
|
|
GENERIC_FAILURE = 0
|
|
WRITE_FAILURE = 1
|
|
FLUSH_FAILURE = 2
|
|
CLOSE_FAILURE = 3
|
|
OPEN_FAILURE = 4
|
|
FORMAT_FAILURE = 5
|
|
|
|
|
|
# ============================================================
|
|
# Handler
|
|
# ============================================================
|
|
|
|
class Handler(Stub):
|
|
"""java.util.logging.Handler"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._level = Level.ALL
|
|
self._filter = None
|
|
self._formatter = None
|
|
self._encoding = None
|
|
self._error_manager = ErrorManager()
|
|
self._closed = False
|
|
|
|
def publish(self, record):
|
|
raise NotImplementedError
|
|
|
|
def flush(self):
|
|
pass
|
|
|
|
def close(self):
|
|
self._closed = True
|
|
|
|
def isLoggable(self, record):
|
|
if self._closed:
|
|
return False
|
|
if record.getLevel().intValue() < self._level.intValue():
|
|
return False
|
|
if self._filter is not None:
|
|
return self._filter.isLoggable(record)
|
|
return True
|
|
|
|
def setLevel(self, level):
|
|
self._level = level
|
|
|
|
def getLevel(self):
|
|
return self._level
|
|
|
|
def setFilter(self, filter_):
|
|
self._filter = filter_
|
|
|
|
def getFilter(self):
|
|
return self._filter
|
|
|
|
def setFormatter(self, formatter):
|
|
self._formatter = formatter
|
|
|
|
def getFormatter(self):
|
|
return self._formatter
|
|
|
|
def setEncoding(self, encoding):
|
|
self._encoding = encoding
|
|
|
|
def getEncoding(self):
|
|
return self._encoding
|
|
|
|
def setErrorManager(self, em):
|
|
self._error_manager = em
|
|
|
|
def getErrorManager(self):
|
|
return self._error_manager
|
|
|
|
def reportError(self, msg, ex, code):
|
|
if self._error_manager:
|
|
self._error_manager.error(msg, ex, code)
|
|
|
|
|
|
class StreamHandler(Handler):
|
|
"""java.util.logging.StreamHandler"""
|
|
def __init__(self, out=None, formatter=None):
|
|
super().__init__()
|
|
if formatter is None:
|
|
formatter = SimpleFormatter()
|
|
self.setFormatter(formatter)
|
|
self._output = out or _sys.stderr
|
|
self._writer = None
|
|
if self._output is not None:
|
|
if isinstance(self._output, _io.TextIOBase):
|
|
self._writer = self._output
|
|
elif isinstance(self._output, _io.BufferedWriter):
|
|
self._writer = _io.TextIOWrapper(self._output)
|
|
else:
|
|
self._writer = _io.TextIOWrapper(_io.BufferedWriter(self._output))
|
|
|
|
def publish(self, record):
|
|
if not self.isLoggable(record):
|
|
return
|
|
try:
|
|
msg = self.getFormatter().format(record)
|
|
if self._writer is not None:
|
|
self._writer.write(msg + "\n")
|
|
else:
|
|
print(msg, file=_sys.stderr)
|
|
self.flush()
|
|
except Exception as e:
|
|
self.reportError("Error publishing record", e, ErrorManager.WRITE_FAILURE)
|
|
|
|
def flush(self):
|
|
if self._writer is not None:
|
|
try:
|
|
self._writer.flush()
|
|
except Exception:
|
|
pass
|
|
|
|
def close(self):
|
|
self.flush()
|
|
if self._writer is not None:
|
|
try:
|
|
self._writer.close()
|
|
except Exception:
|
|
pass
|
|
super().close()
|
|
|
|
def setOutputStream(self, out):
|
|
self._output = out
|
|
if isinstance(out, _io.TextIOBase):
|
|
self._writer = out
|
|
elif isinstance(out, _io.BufferedWriter):
|
|
self._writer = _io.TextIOWrapper(out)
|
|
else:
|
|
self._writer = _io.TextIOWrapper(_io.BufferedWriter(out))
|
|
|
|
|
|
class ConsoleHandler(StreamHandler):
|
|
"""java.util.logging.ConsoleHandler"""
|
|
def __init__(self):
|
|
super().__init__(_sys.stderr, SimpleFormatter())
|
|
self.setLevel(Level.INFO)
|
|
|
|
|
|
class FileHandler(Handler):
|
|
"""java.util.logging.FileHandler"""
|
|
def __init__(self, pattern=None, append=None, limit=0, count=1):
|
|
super().__init__()
|
|
self._pattern = pattern or "logging.log"
|
|
self._limit = limit
|
|
self._count = count
|
|
self._append = append or False
|
|
self._files = []
|
|
|
|
if "%u" in self._pattern or "%g" in self._pattern:
|
|
self._current_filename = self._pattern.replace("%u", "0").replace("%g", "0")
|
|
else:
|
|
self._current_filename = self._pattern
|
|
|
|
try:
|
|
mode = "a" if self._append else "w"
|
|
self._file = open(self._current_filename, mode, encoding="utf-8")
|
|
self._writer = self._file
|
|
except Exception as e:
|
|
self._file = None
|
|
self._writer = None
|
|
self.reportError("Cannot open file", e, ErrorManager.OPEN_FAILURE)
|
|
|
|
self._formatter = SimpleFormatter()
|
|
|
|
def publish(self, record):
|
|
if not self.isLoggable(record):
|
|
return
|
|
if self._writer is None:
|
|
return
|
|
try:
|
|
msg = self.getFormatter().format(record)
|
|
self._writer.write(msg + "\n")
|
|
self.flush()
|
|
except Exception as e:
|
|
self.reportError("Error publishing record", e, ErrorManager.WRITE_FAILURE)
|
|
|
|
def flush(self):
|
|
if self._writer is not None:
|
|
try:
|
|
self._writer.flush()
|
|
except Exception:
|
|
pass
|
|
|
|
def close(self):
|
|
self.flush()
|
|
if self._writer is not None:
|
|
try:
|
|
self._writer.close()
|
|
except Exception:
|
|
pass
|
|
super().close()
|
|
|
|
|
|
class SocketHandler(Handler):
|
|
"""java.util.logging.SocketHandler"""
|
|
def __init__(self, host, port):
|
|
super().__init__()
|
|
self._host = host
|
|
self._port = port
|
|
self._sock = None
|
|
self._output_stream = None
|
|
|
|
def connect(self):
|
|
import socket
|
|
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
self._sock.connect((self._host, self._port))
|
|
self._output_stream = self._sock.makefile("wb")
|
|
|
|
def publish(self, record):
|
|
if not self.isLoggable(record):
|
|
return
|
|
if self._output_stream is None:
|
|
try:
|
|
self.connect()
|
|
except Exception as e:
|
|
self.reportError("Cannot connect", e, ErrorManager.OPEN_FAILURE)
|
|
return
|
|
try:
|
|
msg = self.getFormatter().format(record)
|
|
self._output_stream.write(msg.encode() + b"\n")
|
|
self.flush()
|
|
except Exception as e:
|
|
self.reportError("Error sending record", e, ErrorManager.WRITE_FAILURE)
|
|
|
|
def flush(self):
|
|
if self._output_stream is not None:
|
|
try:
|
|
self._output_stream.flush()
|
|
except Exception:
|
|
pass
|
|
|
|
def close(self):
|
|
self.flush()
|
|
if self._output_stream is not None:
|
|
try:
|
|
self._output_stream.close()
|
|
except Exception:
|
|
pass
|
|
if self._sock is not None:
|
|
try:
|
|
self._sock.close()
|
|
except Exception:
|
|
pass
|
|
super().close()
|
|
|
|
|
|
class MemoryHandler(Handler):
|
|
"""java.util.logging.MemoryHandler"""
|
|
def __init__(self, target=None, size=1000, push_level=Level.SEVERE):
|
|
super().__init__()
|
|
self._target = target
|
|
self._size = size
|
|
self._push_level = push_level
|
|
self._buffer = []
|
|
|
|
def publish(self, record):
|
|
if not self.isLoggable(record):
|
|
return
|
|
self._buffer.append(record)
|
|
if len(self._buffer) >= self._size:
|
|
self.push()
|
|
elif record.getLevel().intValue() >= self._push_level.intValue():
|
|
self.push()
|
|
|
|
def push(self):
|
|
if self._target is not None:
|
|
for rec in self._buffer:
|
|
self._target.publish(rec)
|
|
self._buffer.clear()
|
|
self._target.flush()
|
|
|
|
def flush(self):
|
|
self.push()
|
|
|
|
def close(self):
|
|
self.push()
|
|
if self._target is not None:
|
|
self._target.close()
|
|
super().close()
|
|
|
|
def setPushLevel(self, level):
|
|
self._push_level = level
|
|
|
|
def getPushLevel(self):
|
|
return self._push_level
|
|
|
|
def setTarget(self, target):
|
|
self._target = target
|
|
|
|
def getTarget(self):
|
|
return self._target
|
|
|
|
|
|
# ============================================================
|
|
# Logger
|
|
# ============================================================
|
|
|
|
class Logger(Stub):
|
|
"""java.util.logging.Logger"""
|
|
_loggers = {}
|
|
_root = None
|
|
_global_logger = None
|
|
|
|
def __init__(self, name, resource_bundle_name=None):
|
|
super().__init__()
|
|
self._name = name
|
|
self._resource_bundle_name = resource_bundle_name
|
|
self._level = None
|
|
self._parent = None
|
|
self._handlers = []
|
|
self._filter = None
|
|
self._use_parent_handlers = True
|
|
|
|
@staticmethod
|
|
def getGlobal():
|
|
if Logger._global_logger is None:
|
|
Logger._global_logger = Logger("global")
|
|
return Logger._global_logger
|
|
|
|
@staticmethod
|
|
def getLogger(name, resource_bundle_name=None):
|
|
if not name:
|
|
if Logger._root is None:
|
|
Logger._root = Logger("", resource_bundle_name)
|
|
return Logger._root
|
|
if name not in Logger._loggers:
|
|
logger = Logger(name, resource_bundle_name)
|
|
Logger._loggers[name] = logger
|
|
logger._parent = Logger.getLogger("", None)
|
|
return Logger._loggers[name]
|
|
|
|
def getName(self):
|
|
return self._name
|
|
|
|
def getParent(self):
|
|
return self._parent
|
|
|
|
def setParent(self, parent):
|
|
self._parent = parent
|
|
|
|
def setLevel(self, level):
|
|
self._level = level
|
|
|
|
def getLevel(self):
|
|
return self._level
|
|
|
|
def isLoggable(self, level):
|
|
if self._level is not None:
|
|
return level.intValue() >= self._level.intValue()
|
|
if self._parent is not None:
|
|
return self._parent.isLoggable(level)
|
|
return level.intValue() >= Level.INFO.intValue()
|
|
|
|
def addHandler(self, handler):
|
|
if handler not in self._handlers:
|
|
self._handlers.append(handler)
|
|
|
|
def removeHandler(self, handler):
|
|
if handler in self._handlers:
|
|
self._handlers.remove(handler)
|
|
|
|
def getHandlers(self):
|
|
return self._handlers
|
|
|
|
def setUseParentHandlers(self, use):
|
|
self._use_parent_handlers = use
|
|
|
|
def getUseParentHandlers(self):
|
|
return self._use_parent_handlers
|
|
|
|
def setFilter(self, filter_):
|
|
self._filter = filter_
|
|
|
|
def getFilter(self):
|
|
return self._filter
|
|
|
|
def getResourceBundle(self):
|
|
return None
|
|
|
|
def getResourceBundleName(self):
|
|
return self._resource_bundle_name
|
|
|
|
def log(self, level, msg_or_supplier, *args):
|
|
if isinstance(level, Level):
|
|
if self.isLoggable(level):
|
|
if callable(msg_or_supplier) and not args:
|
|
msg = msg_or_supplier()
|
|
else:
|
|
msg = msg_or_supplier
|
|
record = LogRecord(level, msg)
|
|
record.setLoggerName(self._name)
|
|
record.setParameters(args or None)
|
|
self._log(record)
|
|
else:
|
|
# log(LogRecord)
|
|
self._log(level)
|
|
|
|
def _log(self, record):
|
|
if self._filter is not None and not self._filter.isLoggable(record):
|
|
return
|
|
for handler in self._handlers:
|
|
if handler.isLoggable(record):
|
|
handler.publish(record)
|
|
if self._use_parent_handlers and self._parent is not None:
|
|
self._parent._log(record)
|
|
|
|
def severe(self, msg):
|
|
self.log(Level.SEVERE, msg)
|
|
|
|
def warning(self, msg):
|
|
self.log(Level.WARNING, msg)
|
|
|
|
def info(self, msg):
|
|
self.log(Level.INFO, msg)
|
|
|
|
def config(self, msg):
|
|
self.log(Level.CONFIG, msg)
|
|
|
|
def fine(self, msg):
|
|
self.log(Level.FINE, msg)
|
|
|
|
def finer(self, msg):
|
|
self.log(Level.FINER, msg)
|
|
|
|
def finest(self, msg):
|
|
self.log(Level.FINEST, msg)
|
|
|
|
def entering(self, source_class, source_method, param=None):
|
|
msg = f"ENTRY {source_class}.{source_method}"
|
|
if param is not None:
|
|
msg += f" {param}"
|
|
self.log(Level.FINER, msg)
|
|
|
|
def exiting(self, source_class, source_method, result=None):
|
|
msg = f"RETURN {source_class}.{source_method}"
|
|
if result is not None:
|
|
msg += f" {result}"
|
|
self.log(Level.FINER, msg)
|
|
|
|
def throwing(self, source_class, source_method, thrown):
|
|
record = LogRecord(Level.FINER, "THROW")
|
|
record.setLoggerName(self._name)
|
|
record.setSourceClassName(source_class)
|
|
record.setSourceMethodName(source_method)
|
|
record.setThrown(thrown)
|
|
self._log(record)
|
|
|
|
def logp(self, level, source_class, source_method, msg, *params):
|
|
if self.isLoggable(level):
|
|
record = LogRecord(level, msg)
|
|
record.setLoggerName(self._name)
|
|
record.setSourceClassName(source_class)
|
|
record.setSourceMethodName(source_method)
|
|
record.setParameters(params or None)
|
|
self._log(record)
|
|
|
|
def logrb(self, level, source_class, source_method, bundle_name, msg, *params):
|
|
if self.isLoggable(level):
|
|
record = LogRecord(level, msg)
|
|
record.setLoggerName(self._name)
|
|
record.setSourceClassName(source_class)
|
|
record.setSourceMethodName(source_method)
|
|
record.setResourceBundleName(bundle_name)
|
|
record.setParameters(params or None)
|
|
self._log(record)
|
|
|
|
@staticmethod
|
|
def getAnonymousLogger(resource_bundle_name=None):
|
|
logger = Logger("", resource_bundle_name)
|
|
return logger
|
|
|
|
|
|
# ============================================================
|
|
# LogManager
|
|
# ============================================================
|
|
|
|
class LogManager(Stub):
|
|
"""java.util.logging.LogManager"""
|
|
_singleton = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._loggers = {}
|
|
self._properties = {}
|
|
|
|
@staticmethod
|
|
def getLogManager():
|
|
if LogManager._singleton is None:
|
|
LogManager._singleton = LogManager()
|
|
return LogManager._singleton
|
|
|
|
def addLogger(self, logger):
|
|
name = logger.getName()
|
|
if name in self._loggers:
|
|
return False
|
|
self._loggers[name] = logger
|
|
return True
|
|
|
|
def getLogger(self, name):
|
|
return self._loggers.get(name)
|
|
|
|
def getLoggers(self):
|
|
return list(self._loggers.values())
|
|
|
|
def readConfiguration(self, input_stream=None):
|
|
pass
|
|
|
|
def readConfiguration(self, ins):
|
|
pass
|
|
|
|
def reset(self):
|
|
for logger in self._loggers.values():
|
|
for handler in logger.getHandlers()[:]:
|
|
handler.close()
|
|
logger.removeHandler(handler)
|
|
logger.setLevel(None)
|
|
|
|
def checkAccess(self):
|
|
pass
|
|
|
|
def addPropertyChangeListener(self, listener):
|
|
pass
|
|
|
|
def removePropertyChangeListener(self, listener):
|
|
pass
|
|
|
|
LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"
|
|
|
|
def getProperty(self, name):
|
|
return self._properties.get(name)
|
|
|
|
|
|
# ============================================================
|
|
# LoggingMXBean
|
|
# ============================================================
|
|
|
|
class LoggingMXBean(Stub):
|
|
"""java.util.logging.LoggingMXBean"""
|
|
def getLoggerLevel(self, logger_name):
|
|
logger = LogManager.getLogManager().getLogger(logger_name)
|
|
if logger and logger.getLevel():
|
|
return logger.getLevel().getName()
|
|
return ""
|
|
|
|
def setLoggerLevel(self, logger_name, level_name):
|
|
logger = LogManager.getLogManager().getLogger(logger_name)
|
|
if logger:
|
|
level = Level()
|
|
logger.setLevel(level.parse(level_name))
|
|
|
|
def getParentLogger(self, logger_name):
|
|
logger = LogManager.getLogManager().getLogger(logger_name)
|
|
if logger and logger.getParent():
|
|
return logger.getParent().getName()
|
|
return ""
|
|
|
|
def getLoggerNames(self):
|
|
return list(LogManager.getLogManager()._loggers.keys())
|
|
|
|
|
|
# ============================================================
|
|
# LoggingPermission
|
|
# ============================================================
|
|
|
|
class LoggingPermission(BasicPermission):
|
|
"""java.util.logging.LoggingPermission"""
|
|
def __init__(self, name, actions=None):
|
|
super().__init__(name, actions)
|
|
|
|
|
|
class IllegalArgumentException(RuntimeException):
|
|
"""java.lang.IllegalArgumentException"""
|
|
pass |