first commit

This commit is contained in:
Ruslan Grak
2025-01-07 10:00:02 +03:00
commit 626d8d3c56
349 changed files with 44175 additions and 0 deletions

6
smile_log/tools/__init__.py Executable file
View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# (C) 2020 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from .db_handler import *
from .db_logger import *

64
smile_log/tools/db_handler.py Executable file
View File

@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# (C) 2020 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import logging
from odoo import registry
class SmileDBHandler(logging.Handler):
def __init__(self, level=logging.NOTSET):
logging.Handler.__init__(self, level)
self._dbname_to_cr = {}
def _get_cursor(self, dbname):
cr = self._dbname_to_cr.get(dbname)
if not cr or (cr and cr.closed):
cr = registry(dbname).cursor()
cr.autocommit(True)
self._dbname_to_cr[dbname] = cr
return cr
def emit(self, record):
if not (record.args and isinstance(record.args, dict)):
return False
dbname = record.args.get('dbname', '')
cr = self._get_cursor(dbname)
res_id = record.args.get('res_id', 0)
pid = record.args.get('pid', 0)
uid = record.args.get('uid', 0)
model_name = record.args.get('model_name', '')
request = """INSERT INTO smile_log
(log_date, log_uid, model_name, res_id, pid, level, message)
VALUES (now() at time zone 'UTC', %s, %s, %s, %s, %s, %s)"""
params = (uid, model_name, res_id, pid, record.levelname, record.msg,)
try:
cr.execute(request, params)
except Exception:
# retry
cr = self._get_cursor(dbname)
cr.execute(request, params)
return True
def close(self):
logging.Handler.close(self)
for cr in self._dbname_to_cr.values():
try:
cr.execute(
"INSERT INTO smile_log "
"(log_date, log_uid, model_name, "
"res_id, pid, level, message) "
"VALUES (now() at time zone 'UTC', 0, '', "
"0, 0, 'INFO', 'Odoo server stopped')")
finally:
cr.close()
self._dbname_to_cr = {}
logging.getLogger('smile_log').addHandler(SmileDBHandler())

84
smile_log/tools/db_logger.py Executable file
View File

@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
# (C) 2020 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import datetime
import logging
import sys
from odoo import registry
from .misc import add_timing, add_trace
if sys.version_info > (3,):
long = int
class SmileDBLogger:
def __init__(self, dbname, model_name, res_id, uid=0):
assert isinstance(uid, (int, long)), 'uid should be an integer'
self._logger = logging.getLogger('smile_log')
pid = 0
try:
cr = registry(dbname).cursor()
cr.autocommit(True)
cr.execute(
"select relname from pg_class "
"where relname='smile_log_seq'")
if not cr.rowcount:
cr.execute("create sequence smile_log_seq")
cr.execute("select nextval('smile_log_seq')")
res = cr.fetchone()
pid = res and res[0] or 0
finally:
cr.close()
self._logger_start = datetime.datetime.now()
self._logger_args = {
'dbname': dbname, 'model_name': model_name,
'res_id': res_id, 'uid': uid, 'pid': pid}
@property
def pid(self):
return self._logger_args['pid']
def setLevel(self, level):
self._logger.setLevel(level)
def getEffectiveLevel(self):
return self._logger.getEffectiveLevel()
def debug(self, msg):
self._logger.debug(msg, self._logger_args)
def info(self, msg):
self._logger.info(msg, self._logger_args)
def warning(self, msg):
self._logger.warning(msg, self._logger_args)
def log(self, msg):
self._logger.log(msg, self._logger_args)
@add_trace
def error(self, msg):
self._logger.error(msg, self._logger_args)
@add_trace
def critical(self, msg):
self._logger.critical(msg, self._logger_args)
@add_trace
def exception(self, msg):
self._logger.exception(msg, self._logger_args)
@add_timing
def time_info(self, msg):
self._logger.info(msg, self._logger_args)
@add_timing
def time_debug(self, msg):
self._logger.debug(msg, self._logger_args)

23
smile_log/tools/misc.py Executable file
View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# (C) 2020 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import datetime
import traceback
def add_timing(original_method):
def new_method(self, msg):
delay = datetime.datetime.now() - self._logger_start
msg += " after %sh %smin %ss" % tuple(str(delay).split(':'))
return original_method(self, msg)
return new_method
def add_trace(original_method):
def new_method(self, msg):
stack = traceback.format_exc()
stack = stack.replace('%', '%%')
msg += '\n%s' % stack
return original_method(self, msg)
return new_method