Python通过Thread锁实现并发日志入库

使用线程锁来实现一个简单写日志到数据库的功能,通过threading锁来实现线程安全,代码如下:

#-*-utf-8-*-
import logging, datetime, time
from multiprocessing import Queue, Process
import cx_Oracle
import threading

class LogInfo(object):
    def __init__(self, logTime, scriptName, logType, message):
        self.logTime = logTime
        self.scriptName = scriptName
        self.logType = logType
        self.message = message

    def __str__(self):
        return self.scriptName + " " + self.logType + " " + str(self.message)


def insertLog(LogInfo):
    with cx_Oracle.connect("system/1234@orcl") as conn:
        cursor = conn.cursor()
        sqlStr = "insert into SYSTEM.etl_logs values (to_timestamp('%s', 'YYYY-MM-DD HH24:MI:SS.FF'), '%s', '%s', '%s')"
        cursor.execute(sqlStr % (LogInfo.logTime, LogInfo.scriptName, LogInfo.logType, LogInfo.message))
        conn.commit()


class Log2DB(object):
    instance = None
    def __new__(cls):
        if cls.instance:
            return cls.instance
        cls.instance = object.__new__(cls)
        cls.instance.queue = Queue()
        cls.instance._lock = threading.RLock()
        return cls.instance

    def flag(self, text):
        time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%S.%f')
        log = LogInfo(time, 'a', 'flag', text)
        self._insert(log)

    def info(self, text):
        time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%S.%f')
        log = LogInfo(time, 'b', 'info', text)
        self._insert(log)

    def error(self, text):
        time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%S.%f')
        log = LogInfo(time, 'c', 'error', text)
        self._insert(log)

    def warn(self, text):
        time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%S.%f')
        log = LogInfo(time, 'd', 'warn', text)
        self._insert(log)

    def _insert(self, log):
        self._lock.acquire()
        try:
            print(log)
            insertLog(log)
        except Exception as e:
            print(str(e.args))
        finally:
            self._lock.release()


log2db = Log2DB()

def a():
    for i in range(1000):
        log2db.flag("a"+str(i))

def b():
    for i in range(1000):
        log2db.info(i)  


if __name__ == '__main__':
    ap = Process(target=a)
    ap.start()
    bp = Process(target=b)
    bp.start()
    ap.join()
    bp.join()

不过效率也就一般了,基本上3秒才能写入一条记录,后来加了时间打印了一下发现是写DB的过程太耗时导致,需要考虑批量提交比较好,下一篇准备实现一个无阻塞的日志入库的程序。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页