如何使用 pymysql 将日志上传到 mysql

How to upload logging to mysql using pymysql

我想收集并检查发生了什么错误,所以我正在尝试将日志上传到数据库中。我参考这个页面写了上传日志到mysql的代码。 python logging to database。 但是,我收到以下错误。哪一部分是错误的?另外,如果mysql有其他方便上传日志的方法,请告诉我。

import logging
import time
import pymysql

user = 'test'
passw = '******'
host = 'db'
port = ****
database = '****'
db_tbl_log = 'log'

log_file_path = 'C:\Users\Desktop\test_log.txt'
log_error_level = 'DEBUG'       # LOG error level (file)
log_to_db = True                    # LOG to database?

class LogDBHandler(logging.Handler):
    '''
    Customized logging handler that puts logs to the database.
    pymssql required
    '''
    def __init__(self, sql_conn, sql_cursor, db_tbl_log):
        logging.Handler.__init__(self)
        self.sql_cursor = sql_cursor
        self.sql_conn = sql_conn
        self.db_tbl_log = db_tbl_log

    def emit(self, record):
        # Set current time
        tm = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.created))
        # Clear the log message so it can be put to db via sql (escape quotes)
        self.log_msg = record.msg
        self.log_msg = self.log_msg.strip()
        self.log_msg = self.log_msg.replace('\'', '\'\'')
        # Make the SQL insert
        sql = 'INSERT INTO ' + self.db_tbl_log + ' (log_level, ' + \
            'log_levelname, log, created_at, created_by) ' + \
            'VALUES (' + \
            ''   + str(record.levelno) + ', ' + \
            '\'' + str(record.levelname) + '\', ' + \
            '\'' + str(self.log_msg) + '\', ' + \
            '(convert(datetime2(7), \'' + tm + '\')), ' + \
            '\'' + str(record.name) + '\')'
        try:
            self.sql_cursor.execute(sql)
            self.sql_conn.commit()
        # If error - print it out on screen. Since DB is not working - there's
        # no point making a log about it to the database :)
        except pymysql.Error as e:
            print("error: ", e)
            # print(sql)
            # print('CRITICAL DB ERROR! Logging to database not possible!')
# Main settings for the database logging use

if (log_to_db):
    # Make the connection to database for the logger
    log_conn = pymysql.connect(host=host,
                           port=port,
                           user=user,
                           password=passw,
                           database=database,
                           charset='utf8')
    log_cursor = log_conn.cursor()
    logdb = LogDBHandler(log_conn, log_cursor, db_tbl_log)

# Set logger
logging.basicConfig(filename=log_file_path)

# Set db handler for root logger
if (log_to_db):
    logging.getLogger('').addHandler(logdb)
# Register MY_LOGGER
log = logging.getLogger('MY_LOGGER')
log.setLevel(log_error_level)

# Example variable
test_var = 'This is test message'

# Log the variable contents as an error
log.error('This error occurred: %s' % test_var)

error: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''2021-02-22 16:52:06')), 'MY_LOGGER')' at line 1")

不要自己格式化SQL语句,你会漏掉很多情况。只需将它们作为第二个参数传递:

sql = f'INSERT INTO {self.db_tbl_log} (log_level, log_levelname, log, created_at, created_by) VALUES (%s, %s, %s, %s, %s)'
self.sql_cursor.execute(sql, (record.levelno, record.levelname, self.log_msg, tm, record.name))

%s是占位符,pymysql会将给定的参数一一转换为有效格式。