创建日志处理程序以连接到Oracle? [英] Creating a logging handler to connect to Oracle?

查看:115
本文介绍了创建日志处理程序以连接到Oracle?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以现在我需要创建并实现将用于登录到我们的数据库的Python日志模块的扩展。基本上我们有几个python应用程序(所有运行在后台)当前登录到一个随机的mishmash文本文件。这使得几乎不可能发现某个应用程序是否失败。



给我的问题是将记录文本文件移动到oracle数据库。这些表已经被定义了,在哪里需要记录到目前为止,我正在看一下添加另一个将记录到DB的日志处理程序。



我正在使用python 2.5.4和cx_Oracle,一般应用程序可以作为服务/守护程序或直接应用程序运行。



我只是主要想知道最好的办法是什么。几个问题:


  1. 如果cx_Oracle发生任何错误,这些错误应该记录到哪里?如果它的下降最好只是去记录器撤退到默认文本文件?


  2. 稍后我们开始强制人们使用sys.stderr /stdout.write而不是打印,所以最坏的情况我们不会遇到任何打印成为不赞成的问题。有没有办法无缝地使所有成千上万的sys.std调用直接输入到记录器,并使记录器拾起松动?


  3. 之后每个记录的消息,脚本应该自动执行提交吗? (将有几十秒)。


  4. 为日志系统实现新的处理程序是最好的方法?从基本的Handler类继承似乎是最简单的。


任何想法/建议都会很棒。

解决方案


  1. 如果cx_Oracle发生错误,最好将它们记录到文本文件。 / li>
  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 

#版权所有2001-2009由Vinay Sajip。版权所有。

#特此授予使用,复制,修改和分发本软件及其
#文档的权利,
#,条件是上述版权通知出现在所有副本中,并且
#版权声明和本许可声明都出现在
#支持文件中,并且Vinay Sajip
#的名称不用于广告或宣传中分发
#的软件,没有具体的书面许可。
#VINAY SAJIP不对本软件提供所有担保,包括
#所有暗示的适销性和适用性的保证。在任何情况下,
#VINAY SAJIP对任何特殊的,间接的或后果性的损害或
负责任何损失使用,数据或利润损失的任何损失,无论在任何行动中是否b $ b#合同,疏忽或其他侵权行为,造成与本软件的使用或性能有关的或与之相关的。

#此文件是独立的Python日志分发的一部分。请参阅
#http://www.red-dove.com/python_logging.html


日志记录模块的测试工具。一个示例处理程序 - DBHandler -
写入Python DB API 2.0数据源您需要在运行测试之前设置
源。

版权所有(C)2001-2009 Vinay Sajip。保留所有权利

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,
消息,
文件名,
路径名,
Lineno,
毫秒,
异常,
线程

VALUES(
%(dbtime)s,
%(relativeCreated)d,
'%(name)s',
%(levelno)d,
'%(levelname) ',
'%(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默认格式
self.format(record)
#now设置数据库时间
self.formatDBTime(record)
如果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()
除了:
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爱我的%s的%s ,sphinx,quartz)
logger.debug(打包我的%s与五打%s,盒,酒壶)
尝试:
导入数学
math.exp(1000)
除了:
logger.exception(%s的问题,math.exp)
pre>

So right now i need to create and implement an extension of the Python logging module that will be used to log to our database. Basically we have several python applications(that all run in the background) that currently log to a random mishmash of text files. Which makes it almost impossible to find out if a certain application failed or not.

The problem given to me is to move said logging to text files to an oracle DB. The tables have already been defined, and where things need to be logged to but right now, im looking at adding another logging handler that will log to the DB.

I am using python 2.5.4 and cx_Oracle and the applications in general can be ether run as a service/daemon or a straight application.

I'm just mainly curious about what would be the best possible way to go about this. Few questions:

  1. If any errors occur with cx_Oracle, where should these errors be logged to? If its down would it be best to just go and have the logger retreat to the default text file?

  2. Awhile back we started enforcing that people use sys.stderr/stdout.write instead of print, so worst case scenario we wouldn't run into any issues with print becoming deprecated. Is there a way to seamlessly make all of the thousands of sys.std calls be piped directly into the logger, and have the logger pickup the slack?

  3. After every logged message, should the script automatically do a commit? (there's going to be several dozen a second.)

  4. What is the best way to implement a new handler for the logging system? Inheriting from the basic Handler class seems to be easiest.

Any ideas / suggestions would be great.

解决方案

  1. If errors occur with cx_Oracle, it's probably best to log these to a text file.
  2. You could try redirecting sys.stdout and sys.stderr to file-like objects which log whatever's written to them to a logger.
  3. I would guess you do want to commit after each event, unless you have strong reasons for not doing this. Alternatively, you can buffer several events and write them all in a single transaction every so often.
  4. Below is an example which uses mx.ODBC, you can probably adapt this to cx_Oracle without too much trouble. It's meant to be Python DB-API 2.0 compliant, I think.

The standalone Python logging distribution (before logging was added to Python) is at http://www.red-dove.com/python_logging.html and although the logging package in Python is much more up to date, the standalone distribution contains a test directory which has a lot of useful examples of derived handler classes.

#!/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")

这篇关于创建日志处理程序以连接到Oracle?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆