Создание обработчика журнала для подключения к Oracle?

Поэтому сейчас мне нужно создать и реализовать расширение модуля регистрации Python, который будет использоваться для входа в нашу базу данных. По сути, у нас есть несколько приложений на Python (все они работают в фоновом режиме), которые в настоящее время регистрируют случайную путаницу текстовых файлов. Что делает почти невозможным выяснить, не удалось ли определенное приложение или нет.

Задача, поставленная передо мной, состоит в том, чтобы переместить указанную запись в текстовые файлы в оракуловую БД Таблицы уже были определены, и где вещи должны быть зарегистрированы, но прямо сейчас, я смотрю на добавление другого обработчика регистрации, который будет регистрировать в БД.

Я использую python 2.5.4 и cx_Oracle, и приложения в целом могут работать как сервис / демон или как прямое приложение.

Мне просто интересно узнать, что было бы наилучшим способом сделать это. Несколько вопросов:

  1. Если какие-либо ошибки происходят с cx_Oracle, где эти ошибки должны быть зарегистрированы? Если его нет, то лучше всего пойти и сделать отступление регистратора к текстовому файлу по умолчанию?

  2. Некоторое время назад мы начали требовать, чтобы люди использовали sys.stderr / stdout.write вместо print, поэтому в худшем случае мы не столкнулись бы с какими-либо проблемами, поскольку печать стала устаревшей. Есть ли способ беспрепятственно сделать так, чтобы все тысячи вызовов sys.std направлялись прямо в регистратор, и чтобы регистратор брал слабину?

  3. Должен ли скрипт автоматически выполнять коммит после каждого зарегистрированного сообщения? (будет несколько десятков секунд в секунду.)

  4. Каков наилучший способ реализации нового обработчика для системы регистрации? Наследование от базового класса Handler кажется самым простым.

Любые идеи / предложения будут отличными.

1 ответ

Решение
  1. Если ошибки происходят с cx_Oracle, вероятно, лучше всего записать их в текстовый файл.
  2. Вы можете попробовать перенаправить sys.stdout и sys.stderr на файловые объекты, которые записывают все, что им написано, в регистратор.
  3. Я предполагаю, что вы действительно хотите совершать после каждого события, если у вас нет веских причин не делать этого. Кроме того, вы можете буферизовать несколько событий и записывать их все в одну транзакцию очень часто.
  4. Ниже приведен пример, который использует mx.ODBC, вы, вероятно, можете адаптировать его к cx_Oracle без особых проблем. Я думаю, что он должен быть совместим с Python DB-API 2.0.

Автономный дистрибутив журналирования Python (до того, как логирование было добавлено в Python) находится по адресу http://www.red-dove.com/python_logging.html и, хотя пакет журналирования в Python гораздо более актуален, автономный дистрибутив содержит тест каталог, в котором есть много полезных примеров производных классов-обработчиков.

#!/usr/bin/env python
#
# Copyright 2001-2009 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the standalone Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. An example handler - DBHandler -
which writes to an Python DB API 2.0 data source. You'll need to set this
source up before you run the test.

Copyright (C) 2001-2009 Vinay Sajip. All Rights Reserved.
"""
import sys, string, time, logging

class DBHandler(logging.Handler):
    def __init__(self, dsn, uid='', pwd=''):
        logging.Handler.__init__(self)
        import mx.ODBC.Windows
        self.dsn = dsn
        self.uid = uid
        self.pwd = pwd
        self.conn = mx.ODBC.Windows.connect(self.dsn, self.uid, self.pwd)
        self.SQL = """INSERT INTO Events (
                        Created,
                        RelativeCreated,
                        Name,
                        LogLevel,
                        LevelText,
                        Message,
                        Filename,
                        Pathname,
                        Lineno,
                        Milliseconds,
                        Exception,
                        Thread
                   )
                   VALUES (
                        %(dbtime)s,
                        %(relativeCreated)d,
                        '%(name)s',
                        %(levelno)d,
                        '%(levelname)s',
                        '%(message)s',
                        '%(filename)s',
                        '%(pathname)s',
                        %(lineno)d,
                        %(msecs)d,
                        '%(exc_text)s',
                        '%(thread)s'
                   );
                   """
        self.cursor = self.conn.cursor()

    def formatDBTime(self, record):
        record.dbtime = time.strftime("#%m/%d/%Y#", time.localtime(record.created))

    def emit(self, record):
        try:
            #use default formatting
            self.format(record)
            #now set the database time up
            self.formatDBTime(record)
            if record.exc_info:
                record.exc_text = logging._defaultFormatter.formatException(record.exc_info)
            else:
                record.exc_text = ""
            sql = self.SQL % record.__dict__
            self.cursor.execute(sql)
            self.conn.commit()
        except:
            import traceback
            ei = sys.exc_info()
            traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
            del ei

    def close(self):
        self.cursor.close()
        self.conn.close()
        logging.Handler.close(self)

dh = DBHandler('Logging')
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
logger.addHandler(dh)
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
logger.debug("Pack my %s with five dozen %s", "box", "liquor jugs")
try:
    import math
    math.exp(1000)
except:
    logger.exception("Problem with %s", "math.exp")
Другие вопросы по тегам