# -*- coding: utf-8 -*-
import logging
import sys
import inspect
from datetime import datetime
class OptimizedFormatter(logging.Formatter):
def format(self, record):
try:
# 获取调用者信息
if not hasattr(record, 'module') or not hasattr(record, 'funcName'):
frame = self._cached_caller_frame()
module = inspect.getmodule(frame)
record.module = module.__name__ if module else 'unknown'
record.funcName = frame.f_code.co_name # 添加获取函数名的逻辑
# 参数统一处理
args_str = self._process_args(record)
if args_str:
record.msg = u"%s ⎸ %s" % (record.msg, args_str)
return super(OptimizedFormatter, self).format(record)
except Exception as e:
return u"⚠️ Format Error | Err: %s | Raw: %s" % (e, record.getMessage())
def _cached_caller_frame(self):
"""带缓存优化的帧查找"""
stack = inspect.stack()
for frame_info in reversed(stack):
frame = frame_info[0]
if inspect.getmodule(frame).__name__ != __name__:
return frame
return inspect.currentframe()
def _process_args(self, record):
"""处理所有参数类型"""
parts = []
if hasattr(record, 'positional_args') and record.positional_args:
parts.extend(self._safe_repr(a) for a in record.positional_args)
if hasattr(record, 'extra') and record.extra:
parts.extend(u"%s=%s" % (k, self._safe_repr(v))
for k, v in record.extra.iteritems())
return u" ⎸ ".join(parts) if parts else u""
def _safe_repr(self, value):
"""安全类型转换(增强编码处理)"""
try:
if isinstance(value, dict):
return u"{%s}" % u",".join(u"%s:%s" % (self._safe_repr(k), self._safe_repr(v))
for k, v in value.iteritems())
elif isinstance(value, (list, tuple)):
return u"[%s]" % u",".join(self._safe_repr(x) for x in value)
return self._safe_str(value)
except:
return u""
@staticmethod
def _safe_str(obj):
"""安全字符串转换(解决编码问题)"""
try:
if isinstance(obj, str):
return obj.decode('utf-8', 'replace')
return unicode(obj)
except UnicodeDecodeError:
return u"<非UTF-8字节数据>"
except:
return u"<无法转换对象>"
class SimpleLogger(object):
_initialized = False
@classmethod
def _ensure_init(cls):
if not cls._initialized:
root = logging.getLogger()
root.setLevel(logging.DEBUG)
if not root.handlers:
handler = logging.StreamHandler()
handler.setFormatter(OptimizedFormatter(
fmt=u'[%(asctime)s] [%(levelname)s] %(module)s:%(funcName)s:%(lineno)d ➤ %(message)s',
datefmt='%H:%M:%S'
))
root.addHandler(handler)
cls._initialized = True
@classmethod
def _log(cls, level, msg, *args, **kwargs):
cls._ensure_init()
try:
msg = cls._preprocess_message(msg)
formatted_msg = cls._format_message(msg, args)
logger = logging.getLogger()
logger.log(
level,
formatted_msg,
extra={'extra': kwargs, 'positional_args': args}
)
except Exception as e:
sys.stderr.write(u"Log Error: %s\n" % unicode(e))
@staticmethod
def _preprocess_message(msg):
if isinstance(msg, str):
try:
return msg.decode('utf-8')
except UnicodeDecodeError:
return msg.decode('latin-1', 'replace')
return unicode(msg)
@classmethod
def _format_message(cls, msg, args):
try:
if args and '%' in msg:
return msg % args
except (TypeError, ValueError):
pass
if args:
return u" ".join([msg] + [OptimizedFormatter._safe_str(a) for a in args])
return msg
@classmethod
def debug(cls, msg, *args, **kwargs):
cls._log(logging.DEBUG, msg, *args, **kwargs)
@classmethod
def info(cls, msg, *args, **kwargs):
cls._log(logging.INFO, msg, *args, **kwargs)
@classmethod
def warning(cls, msg, *args, **kwargs):
cls._log(logging.WARNING, msg, *args, **kwargs)
@classmethod
def error(cls, msg, *args, **kwargs):
cls._log(logging.ERROR, msg, *args, **kwargs)
if __name__ == "__main__":
# 测试中文日志
SimpleLogger.info(u"用户登录", u"张三", ip="192.168.1.100")
# 测试混合参数
SimpleLogger.error("错误发生在 %s", u"配置文件", code=500, detail={"line": 42})
# 测试二进制数据
bad_data = '\xe6\x97\xa0' # UTF-8编码的"无"
SimpleLogger.warning("无效数据", bad_data)
IyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KaW1wb3J0IGxvZ2dpbmcKaW1wb3J0IHN5cwppbXBvcnQgaW5zcGVjdApmcm9tIGRhdGV0aW1lIGltcG9ydCBkYXRldGltZQoKCmNsYXNzIE9wdGltaXplZEZvcm1hdHRlcihsb2dnaW5nLkZvcm1hdHRlcik6CiAgICBkZWYgZm9ybWF0KHNlbGYsIHJlY29yZCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIOiOt+WPluiwg+eUqOiAheS/oeaBrwogICAgICAgICAgICBpZiBub3QgaGFzYXR0cihyZWNvcmQsICdtb2R1bGUnKSBvciBub3QgaGFzYXR0cihyZWNvcmQsICdmdW5jTmFtZScpOgogICAgICAgICAgICAgICAgZnJhbWUgPSBzZWxmLl9jYWNoZWRfY2FsbGVyX2ZyYW1lKCkKICAgICAgICAgICAgICAgIG1vZHVsZSA9IGluc3BlY3QuZ2V0bW9kdWxlKGZyYW1lKQogICAgICAgICAgICAgICAgcmVjb3JkLm1vZHVsZSA9IG1vZHVsZS5fX25hbWVfXyBpZiBtb2R1bGUgZWxzZSAndW5rbm93bicKICAgICAgICAgICAgICAgIHJlY29yZC5mdW5jTmFtZSA9IGZyYW1lLmZfY29kZS5jb19uYW1lICAjIOa3u+WKoOiOt+WPluWHveaVsOWQjeeahOmAu+i+kQoKICAgICAgICAgICAgIyDlj4LmlbDnu5/kuIDlpITnkIYKICAgICAgICAgICAgYXJnc19zdHIgPSBzZWxmLl9wcm9jZXNzX2FyZ3MocmVjb3JkKQogICAgICAgICAgICBpZiBhcmdzX3N0cjoKICAgICAgICAgICAgICAgIHJlY29yZC5tc2cgPSB1IiVzIOKOuCAlcyIgJSAocmVjb3JkLm1zZywgYXJnc19zdHIpCgogICAgICAgICAgICByZXR1cm4gc3VwZXIoT3B0aW1pemVkRm9ybWF0dGVyLCBzZWxmKS5mb3JtYXQocmVjb3JkKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgcmV0dXJuIHUi4pqg77iPIEZvcm1hdCBFcnJvciB8IEVycjogJXMgfCBSYXc6ICVzIiAlIChlLCByZWNvcmQuZ2V0TWVzc2FnZSgpKQoKICAgIGRlZiBfY2FjaGVkX2NhbGxlcl9mcmFtZShzZWxmKToKICAgICAgICAiIiLluKbnvJPlrZjkvJjljJbnmoTluKfmn6Xmib4iIiIKICAgICAgICBzdGFjayA9IGluc3BlY3Quc3RhY2soKQogICAgICAgIGZvciBmcmFtZV9pbmZvIGluIHJldmVyc2VkKHN0YWNrKToKICAgICAgICAgICAgZnJhbWUgPSBmcmFtZV9pbmZvWzBdCiAgICAgICAgICAgIGlmIGluc3BlY3QuZ2V0bW9kdWxlKGZyYW1lKS5fX25hbWVfXyAhPSBfX25hbWVfXzoKICAgICAgICAgICAgICAgIHJldHVybiBmcmFtZQogICAgICAgIHJldHVybiBpbnNwZWN0LmN1cnJlbnRmcmFtZSgpCgogICAgZGVmIF9wcm9jZXNzX2FyZ3Moc2VsZiwgcmVjb3JkKToKICAgICAgICAiIiLlpITnkIbmiYDmnInlj4LmlbDnsbvlnosiIiIKICAgICAgICBwYXJ0cyA9IFtdCiAgICAgICAgCiAgICAgICAgaWYgaGFzYXR0cihyZWNvcmQsICdwb3NpdGlvbmFsX2FyZ3MnKSBhbmQgcmVjb3JkLnBvc2l0aW9uYWxfYXJnczoKICAgICAgICAgICAgcGFydHMuZXh0ZW5kKHNlbGYuX3NhZmVfcmVwcihhKSBmb3IgYSBpbiByZWNvcmQucG9zaXRpb25hbF9hcmdzKQogICAgICAgIAogICAgICAgIGlmIGhhc2F0dHIocmVjb3JkLCAnZXh0cmEnKSBhbmQgcmVjb3JkLmV4dHJhOgogICAgICAgICAgICBwYXJ0cy5leHRlbmQodSIlcz0lcyIgJSAoaywgc2VsZi5fc2FmZV9yZXByKHYpKSAKICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBrLCB2IGluIHJlY29yZC5leHRyYS5pdGVyaXRlbXMoKSkKICAgICAgICAKICAgICAgICByZXR1cm4gdSIg4o64ICIuam9pbihwYXJ0cykgaWYgcGFydHMgZWxzZSB1IiIKCiAgICBkZWYgX3NhZmVfcmVwcihzZWxmLCB2YWx1ZSk6CiAgICAgICAgIiIi5a6J5YWo57G75Z6L6L2s5o2i77yI5aKe5by657yW56CB5aSE55CG77yJIiIiCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHZhbHVlLCBkaWN0KToKICAgICAgICAgICAgICAgIHJldHVybiB1Inslc30iICUgdSIsIi5qb2luKHUiJXM6JXMiICUgKHNlbGYuX3NhZmVfcmVwcihrKSwgc2VsZi5fc2FmZV9yZXByKHYpKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBrLCB2IGluIHZhbHVlLml0ZXJpdGVtcygpKQogICAgICAgICAgICBlbGlmIGlzaW5zdGFuY2UodmFsdWUsIChsaXN0LCB0dXBsZSkpOgogICAgICAgICAgICAgICAgcmV0dXJuIHUiWyVzXSIgJSB1IiwiLmpvaW4oc2VsZi5fc2FmZV9yZXByKHgpIGZvciB4IGluIHZhbHVlKQogICAgICAgICAgICByZXR1cm4gc2VsZi5fc2FmZV9zdHIodmFsdWUpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gdSIiCgogICAgQHN0YXRpY21ldGhvZAogICAgZGVmIF9zYWZlX3N0cihvYmopOgogICAgICAgICIiIuWuieWFqOWtl+espuS4sui9rOaNou+8iOino+WGs+e8lueggemXrumimO+8iSIiIgogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShvYmosIHN0cik6CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqLmRlY29kZSgndXRmLTgnLCAncmVwbGFjZScpCiAgICAgICAgICAgIHJldHVybiB1bmljb2RlKG9iaikKICAgICAgICBleGNlcHQgVW5pY29kZURlY29kZUVycm9yOgogICAgICAgICAgICByZXR1cm4gdSI86Z2eVVRGLTjlrZfoioLmlbDmja4+IgogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuIHUiPOaXoOazlei9rOaNouWvueixoT4iCgoKY2xhc3MgU2ltcGxlTG9nZ2VyKG9iamVjdCk6CiAgICBfaW5pdGlhbGl6ZWQgPSBGYWxzZQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIF9lbnN1cmVfaW5pdChjbHMpOgogICAgICAgIGlmIG5vdCBjbHMuX2luaXRpYWxpemVkOgogICAgICAgICAgICByb290ID0gbG9nZ2luZy5nZXRMb2dnZXIoKQogICAgICAgICAgICByb290LnNldExldmVsKGxvZ2dpbmcuREVCVUcpCiAgICAgICAgICAgIGlmIG5vdCByb290LmhhbmRsZXJzOgogICAgICAgICAgICAgICAgaGFuZGxlciA9IGxvZ2dpbmcuU3RyZWFtSGFuZGxlcigpCiAgICAgICAgICAgICAgICBoYW5kbGVyLnNldEZvcm1hdHRlcihPcHRpbWl6ZWRGb3JtYXR0ZXIoCiAgICAgICAgICAgICAgICAgICAgZm10PXUnWyUoYXNjdGltZSlzXSBbJShsZXZlbG5hbWUpc10gJShtb2R1bGUpczolKGZ1bmNOYW1lKXM6JShsaW5lbm8pZCDinqQgJShtZXNzYWdlKXMnLAogICAgICAgICAgICAgICAgICAgIGRhdGVmbXQ9JyVIOiVNOiVTJwogICAgICAgICAgICAgICAgKSkKICAgICAgICAgICAgICAgIHJvb3QuYWRkSGFuZGxlcihoYW5kbGVyKQogICAgICAgICAgICBjbHMuX2luaXRpYWxpemVkID0gVHJ1ZQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIF9sb2coY2xzLCBsZXZlbCwgbXNnLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgIGNscy5fZW5zdXJlX2luaXQoKQogICAgICAgIHRyeToKICAgICAgICAgICAgbXNnID0gY2xzLl9wcmVwcm9jZXNzX21lc3NhZ2UobXNnKQogICAgICAgICAgICBmb3JtYXR0ZWRfbXNnID0gY2xzLl9mb3JtYXRfbWVzc2FnZShtc2csIGFyZ3MpCiAgICAgICAgICAgIAogICAgICAgICAgICBsb2dnZXIgPSBsb2dnaW5nLmdldExvZ2dlcigpCiAgICAgICAgICAgIGxvZ2dlci5sb2coCiAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgIGZvcm1hdHRlZF9tc2csCiAgICAgICAgICAgICAgICBleHRyYT17J2V4dHJhJzoga3dhcmdzLCAncG9zaXRpb25hbF9hcmdzJzogYXJnc30KICAgICAgICAgICAgKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZSh1IkxvZyBFcnJvcjogJXNcbiIgJSB1bmljb2RlKGUpKQoKICAgIEBzdGF0aWNtZXRob2QKICAgIGRlZiBfcHJlcHJvY2Vzc19tZXNzYWdlKG1zZyk6CiAgICAgICAgaWYgaXNpbnN0YW5jZShtc2csIHN0cik6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJldHVybiBtc2cuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3I6CiAgICAgICAgICAgICAgICByZXR1cm4gbXNnLmRlY29kZSgnbGF0aW4tMScsICdyZXBsYWNlJykKICAgICAgICByZXR1cm4gdW5pY29kZShtc2cpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgX2Zvcm1hdF9tZXNzYWdlKGNscywgbXNnLCBhcmdzKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIGFyZ3MgYW5kICclJyBpbiBtc2c6CiAgICAgICAgICAgICAgICByZXR1cm4gbXNnICUgYXJncwogICAgICAgIGV4Y2VwdCAoVHlwZUVycm9yLCBWYWx1ZUVycm9yKToKICAgICAgICAgICAgcGFzcwogICAgCiAgICAgICAgaWYgYXJnczoKICAgICAgICAgICAgcmV0dXJuIHUiICIuam9pbihbbXNnXSArIFtPcHRpbWl6ZWRGb3JtYXR0ZXIuX3NhZmVfc3RyKGEpIGZvciBhIGluIGFyZ3NdKQogICAgICAgIHJldHVybiBtc2cKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBkZWJ1ZyhjbHMsIG1zZywgKmFyZ3MsICoqa3dhcmdzKToKICAgICAgICBjbHMuX2xvZyhsb2dnaW5nLkRFQlVHLCBtc2csICphcmdzLCAqKmt3YXJncykKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBpbmZvKGNscywgbXNnLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgIGNscy5fbG9nKGxvZ2dpbmcuSU5GTywgbXNnLCAqYXJncywgKiprd2FyZ3MpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgd2FybmluZyhjbHMsIG1zZywgKmFyZ3MsICoqa3dhcmdzKToKICAgICAgICBjbHMuX2xvZyhsb2dnaW5nLldBUk5JTkcsIG1zZywgKmFyZ3MsICoqa3dhcmdzKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGVycm9yKGNscywgbXNnLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgIGNscy5fbG9nKGxvZ2dpbmcuRVJST1IsIG1zZywgKmFyZ3MsICoqa3dhcmdzKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICAjIOa1i+ivleS4reaWh+aXpeW/lwogICAgU2ltcGxlTG9nZ2VyLmluZm8odSLnlKjmiLfnmbvlvZUiLCB1IuW8oOS4iSIsIGlwPSIxOTIuMTY4LjEuMTAwIikKICAgIAogICAgIyDmtYvor5Xmt7flkIjlj4LmlbAKICAgIFNpbXBsZUxvZ2dlci5lcnJvcigi6ZSZ6K+v5Y+R55Sf5ZyoICVzIiwgdSLphY3nva7mlofku7YiLCBjb2RlPTUwMCwgZGV0YWlsPXsibGluZSI6IDQyfSkKICAgIAogICAgIyDmtYvor5Xkuozov5vliLbmlbDmja4KICAgIGJhZF9kYXRhID0gJ1x4ZTZceDk3XHhhMCcgICMgVVRGLTjnvJbnoIHnmoQi5pegIgogICAgU2ltcGxlTG9nZ2VyLndhcm5pbmcoIuaXoOaViOaVsOaNriIsIGJhZF9kYXRhKQ==