Избегайте ошибок в журнале аудита OpenERP - PullRequest
3 голосов
/ 31 августа 2010

Я бы хотел управлять активностью пользователя OpenERP, установив модуль AuditRail.
После создания некоторых правил (определите, какой пользователь, какой объект и какая деятельность (создание, обновление ..) будет отслеживаться).Я обновляю продукт, чтобы убедиться, что он работает.
Когда я пытался обновить продукт, я получил системную ошибку.При просмотре журнала я получаю
[2010-08-31 12: 53: 35,042] Курсор явно не закрыт
[2010-08-31 12: 53: 35,043] Курсор создан в / home /Пилигрим / Рабочая / Источники / Аддоны / Audittrail / Audittrail.py: 204

Здесь строка, которая вызывает ошибку, Я получаю комментарий

def __del__(self):
    if not self.__closed:
        # Oops. 'self' has not been closed explicitly.
        # The cursor will be deleted by the garbage collector,
        # but the database connection is not put back into the connection
        # pool, preventing some operation on the database like dropping it.
        # This can also lead to a server overload.
        msg = "Cursor not closed explicitly\n"  \
              "Cursor was created at %s:%s" % self.__caller
        log(msg, netsvc.LOG_WARNING)
        self.close()

Так как я новичок в Python, я не знаю, как преодолеть эту проблему?
Любой намек, чтобы преодолеть это?
Спасибо

Ответы [ 3 ]

4 голосов
/ 31 августа 2010

t было бы важно увидеть исходный код, чтобы понять, что происходит. Но из того, что вы опубликовали, похоже, что предыдущий курсор явно не был закрыт.

cr = sqldb.db_connect(dbname).cursor()
.........
cr.close()
cr = None

Я бы посоветовал вам взломать audtrail.py, чтобы найти где бы вы ни создавали курсор, и где бы вы его не закрывали. Типичная проблема возникает при неправильной обработке исключений, в результате чего код перепрыгивает через обычное закрытие.

Попробуйте поместить предложение try, кроме и finally вокруг сомнительной операции курсора. Это должно помочь вам обойти проблему.

2 голосов
/ 06 октября 2010

Я думаю, что найду ответ.Смотрите пример

def a():  
  try:
    print 'before return '
    return 1
  finally:
    print 'in finally'

call a ()

before return 
in finally
1

Это нормально.ХОРОШО.Попробуйте другой пример (извлечение кода из audittrail.py)

def do_something_with_db(db):
   // open cusror again
   cr = db.cursor()
   // do somethign
   // close cursor internally
   cr.close()
def execute(db)
   // 1, open connection and open cursor
   cr = db.cursor
   try:
        //2, do something with db, seeing that this method will open cursor again
       return do_something_with_db(db)
   finally:
       cr.close()

Видя, что реализация do_something_with_db пытается открыть курсор (можно назвать соединение), но текущая не является явно закрытой.Таким образом, решение простое: передайте текущее значение cr

Before
**do_something_with_db(db)**
after
**do_something_with_db(cr)**

Теперь ошибка исчезла.

@ Дон Киркби: Да, мы должны поэкспериментировать с try ... finally

1 голос
/ 02 сентября 2010

Можете ли вы запустить OpenERP в отладчике, таком как PyDev плагин для Eclipse ? Я считаю, что наиболее эффективный способ выследить проблемы. Я не использовал модуль контрольного журнала, но я быстро взглянул на исходный код , и кажется, что курсор открывается в начале log_fct(). (Я бы ожидал, что он сообщит в строке 207, какую версию вы используете?) Вот что я считаю соответствующим кодом:

def log_fct(self, db, uid, passwd, object, method, fct_src, *args):
    logged_uids = []
    pool = pooler.get_pool(db)
    cr = pooler.get_db(db).cursor() # line 207 in version 5.0.12

    # ...

    if method in ('create'):

        # ...

        cr.close()
        return res_id

    # ...

    cr.close()

Похоже, что в методе есть несколько операторов return, но каждый из них, кажется, сначала вызывает cr.close(), поэтому я не вижу никаких очевидных проблем. Попробуйте запустить его в отладчике с точкой останова в этом методе. Если это невозможно, вы можете попробовать записать в журнал что-то вроде этого:

    logger = netsvc.Logger()
    logger.notifyChannel('audittrail', netsvc.LOG_INFO, 'something happened')

Обновление: Вы прокомментировали, что это происходит под большой нагрузкой. Возможно, генерируется исключение, и курсор не закрывается. Вы можете использовать оператор try ... finally , чтобы убедиться, что курсор всегда закрыт. Вот как будет выглядеть приведенный выше пример после его преобразования:

def log_fct(self, db, uid, passwd, object, method, fct_src, *args):
    logged_uids = []
    pool = pooler.get_pool(db)
    cr = pooler.get_db(db).cursor() # line 207 in version 5.0.12
    try:

        # ...

        if method in ('create'):

            # ...

            return res_id

        # ...

    finally:
        cr.close()
...