0

我在一个脚本上随机收到此异常,该脚本使用 mysql-connector 接收要插入 mysql 数据库的项目:

Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 77, in emit
Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 77, in emit
Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 79, in emit
Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 79, in emit
Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 79, in emit
    logging.FileHandler.emit(self, record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 930, in emit
    StreamHandler.emit(self, record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 874, in emit
    self.handleError(record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 801, in handleError
    None, sys.stderr)
  File "/opt/python/current2/lib/python2.7/traceback.py", line 124, in print_exception
    _print(file, 'Traceback (most recent call last):')
RuntimeError: maximum recursion depth exceeded
Logged from file foo.py, line 47

我也偶尔会得到:

Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 77, in emit
Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 77, in emit
    if self.shouldRollover(record):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 156, in shouldRollover
    msg = "%s\n" % self.format(record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 723, in format
    return fmt.format(record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 464, in format
    record.message = record.getMessage()
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 322, in getMessage
    if not isinstance(msg, basestring):
Traceback (most recent call last):
  File "/opt/python/current2/lib/python2.7/logging/handlers.py", line 79, in emit
    logging.FileHandler.emit(self, record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 930, in emit
    StreamHandler.emit(self, record)
  File "/opt/python/current2/lib/python2.7/logging/__init__.py", line 874, in emit
    self.handleError(record)
RuntimeError: <unprintable RuntimeError object>
Logged from file foo.py, line 47

编码:

import sys
import datetime
import mysql.connector
import config
from logwatch import log
import time, os

class DBConnection:
    _dbconn = None

    @staticmethod
    def get_instance():
        if not DBConnection._dbconn:
            DBConnection._dbconn = DBConnection()
        return DBConnection._dbconn

    def __init__(self):
        self.connection = None

    def connect(self):
        if not self.connection:
            self.connection = mysql.connector.connect(**config.CONFIG)

    def get_cursor(self):
        retries = 2
        while retries > 0:
            try:
                self.connect()
                cursor = self.connection.cursor(buffered=True)
                return cursor
            except mysql.connector.errors.InterfaceError, iErr:
                log.error("%s: Connection failed. Retrying. " % iErr)
                self.connection = None
                retries -= 1
                if retries == 0:
                    raise

    def execute(self, query, params=None):
        cursor = self.get_cursor()
        cursor.execute(query, params)
        return cursor.rowcount

    def commit(self):
        try:
            self.commit()
        except Exception, cExc:
            log.error("Error committing the operation to MySQL: %s" % cExc)

def foo(**kwargs):
    dml = None
    values = None
    rows = None

    if kwargs['action'] == "check":
        dml = "SELECT `log_type` FROM `register` WHERE `record_num` = \
        %s AND `log_type` IN ('1', '3')" % kwargs['record_num']
        log.info("%s %s Checking if record exists in F/U or SA of db: %s" % (kwargs['rectype'], kwargs['record_num'], dml))

    if kwargs['action'] == "moveto":
        sections = ['Trash','Follow up','Problem','Scheduled Actions','Information']
        if kwargs['section'] == 0:
            dml = "UPDATE `register` SET `log_type` = %s WHERE `record_num` = %s"
            values = (kwargs['section'], kwargs['record_num'])
        else:
            dml = "UPDATE `register` SET `log_type` = %s, `comments` = %s WHERE `record_num` = %s"
            values = (kwargs['section'], kwargs['status'], kwargs['record_num'])
        log.info("%s %s Moving to section '%s' %d: %s" %\
        (kwargs['rectype'], kwargs['record_num'], sections[kwargs['section']], kwargs['section'], (dml % values) ))

    if kwargs['action'] == "schedule":
        yyyymmdd = datetime.datetime.strptime(kwargs['start_date'], '%d%b%y').strftime('%Y-%m-%d')
        start_hour = kwargs['start_time'][0:2]
        dml = "INSERT INTO `register` (`record_num`,`title`,`sch_date`, \
        `sch_time`,`rectype`,`log_type`,`user_id`,`entry`,`site`,`comments`,`category`) VALUES \
        (%s, %s, %s, %s, %s, 3, 'FOO', 2, %s, %s, 63)"
        values = (kwargs['record_num'], kwargs['title'], yyyymmdd, kwargs['start_time'], kwargs['rectype'], get_site_flag(start_hour), kwargs['comment'])
        log.info("%s %s Adding to scheduled actions up for review: %s" % (kwargs['rectype'], kwargs['record_num'], (dml % values) ))

    if kwargs['action'] == "update_to_schedule":
        yyyymmdd = datetime.datetime.strptime(kwargs['start_date'], '%d%b%y').strftime('%Y-%m-%d')
        start_hour = kwargs['start_time'][0:2]
        dml = "UPDATE `register` SET `title` = %s,`sch_date` = %s, \
        `sch_time` = %s,`rectype` = %s,`log_type` = '3',`user_id` = 'FOO', \
        `entry` = '2',`site` = %s WHERE `record_num` = %s LIMIT 1"
        values = (kwargs['title'], yyyymmdd, kwargs['start_time'], kwargs['rectype'], get_site_flag(start_hour), kwargs['record_num'])
        log.info("%s %s Updating to scheduled actions for review: %s" % (kwargs['rectype'], kwargs['record_num'], (dml % values) ))

    if kwargs['action'] == "update_to_follow":
        dml = "UPDATE `register` SET `title` = %s,`rectype` = %s, \
        `log_type` = '1',`user_id` = 'FOO', `entry` = '2', \
        `site` = 'M' WHERE `record_num` = %s LIMIT 1"
        values = (kwargs['title'], kwargs['rectype'], kwargs['record_num'])
        log.info("%s %s Updating to follow up for review: %s" % (kwargs['rectype'], kwargs['record_num'], (dml % values) ))

    if kwargs['action'] == "follow-up":
        dml = "INSERT INTO `register` (`record_num`,`title`,`sch_date`, \
        `rectype`,`log_type`,`user_id`,`entry`,`site`,`comments`,`category`) VALUES \
        (%s, %s, NOW(), %s, 1, 'FOO', 2, 'M',%s, 63)"
        values = (kwargs['record_num'], kwargs['title'], kwargs['rectype'], kwargs['comment'] + ', Please follow-up')
        log.info("%s %s Adding to follow up for review: %s" % (kwargs['rectype'], kwargs['record_num'], (dml % values) ))    
    try:
            connection = DBConnection.get_instance()
            rows = connection.execute(dml, values)
            connection.commit()
            log.info("%s %s EXECUTE affected %s rows." % (kwargs['rectype'], kwargs['record_num'], rows))
    except:
        log.error("Error: could not execute %s on db for %s %s.,%s" % ((dml % values), kwargs['rectype'], kwargs['record_num'], str(sys.exc_info())))
    return rows

第 47 行是:

log.error("Error committing the operation to MySQL: %s" % cExc)

我应该将其封装在其他东西中吗?抱歉,我不知道 python,我知道 Java,我只是想修复我采用的这个脚本。还有其他随机异常,但一次一步,这些似乎在每次提交时都会流入?试图弄清楚这是否是脚本似乎无法在重压下插入数据库的原因,提交是该脚本的新添加,是其他人尝试修复的。

每当脚本无法插入数据库时​​,我们也会得到:

(<class 'mysql.connector.errors.OperationalError'>, OperationalError(), <traceback object at 0x2aaaaaf76050>)  
(<class 'mysql.connector.errors.InterfaceError'>, InterfaceError(), <traceback object at 0x2aaaaaf75ab8>)

这通过上面的 log.error 行而不是转储异常的 stdout 错误文件显示在官方日志记录中。

任何帮助将不胜感激,谢谢。

4

1 回答 1

0

这看起来像罪魁祸首:

def commit(self):
    try:
        self.commit()
    except Exception, cExc:
        log.error("Error committing the operation to MySQL: %s" % cExc)

这是一个无限循环,直到您的递归深度超过系统的限制(通常为 1000)。最后,由于您要捕获所有异常,因此您最终会在

log.error("Error committing the operation to MySQL: %s" % cExc)

尝试

# self.commit() - WRONG
self.connection.commit()

还要考虑在提交后不捕获所有异常(被认为是非常糟糕的做法)。替换为所有 mysql 异常的基类

try:
    self.commit()
except mysql.connector.Error as e:
    log.error("Error committing the operation to MySQL: %s" % e)
于 2015-05-10T23:53:29.267 回答