Oracle数据库通过定义TYPE及Member对象来实现日志信息的分级管理 推荐
2013-01-31 10:29
1006 查看
调用路径:
存储过程-》调用函数初始化TYPE里变量-》存储过程调用具体级别的日志操作-》调用TYPES实现体TYPE BOBIES里的具体Member实现体-》调用公用的Member成员存储过程写入syslog表。
代码样例展示:
1、存储过程
片段解析:
初始化log的定义,其实现在type的内部;
调用log具体子过程
2、TYPE定义
上面初始化时调用的TY_LOGMANAGER是TYPE构造函数是的,整个TYPE的定义如下,注意其中的Member成员定义。
3、TYPE BOBY定义
上面的TYPE体中定义了各个级别的Log处理Member子过程,其具体实现则在TYPE BODY中进行,源码如下:
注意其实现中的公用过程的定义。
4、日志截图展示
可见上面初始化时候的类型为“system”,vc_logdesc字段则记录了我们在调用地方记录日志的文本提示信息,如操作的记录id、产品id、以及报错信息、ora0000等的方便我们排查的信息。
文章小结
由上面可以看到通过层层封装,最终我们的日志信息是写入了syslog表进行了统一管理,并通过TYPE定义了各个级别的日志写入柄对外提供各个级别日志的信息写入。
存储过程-》调用函数初始化TYPE里变量-》存储过程调用具体级别的日志操作-》调用TYPES实现体TYPE BOBIES里的具体Member实现体-》调用公用的Member成员存储过程写入syslog表。
代码样例展示:
1、存储过程
create or replace procedure sp_message_hisorderdata_create( p_l_date HsCrmType.LDate%TYPE, p_vc_customer hscrmtype.vc50%type) IS v_l_date HsCrmType.LDate%Type; v_l_currentdate HsCrmType.LDate%Type; v_vc_customer hscrmtype.vc50%type; v_l_count HsCrmType.LInt%Type; v_l_total HsCrmType.LInt%Type; v_vc_open_value HsCrmType.VC255%Type; v_vc_open_value_temp HsCrmType.VC255%Type; v_vc_customer_no HsCrmType.VC20%Type; vc_product_no HsCrmType.CKind%Type; vc_product_temp HsCrmType.CKind%Type; v_vc_prefix HsCrmType.CKind%Type; v_vc_temp1 HsCrmType.VC255%Type; v_vc_temp2 HsCrmType.VC255%Type; v_vc_temp3 HsCrmType.VC255%Type; v_vc_temp4 HsCrmType.VC255%TYPE; V_L_SPEAK_NO HsCrmType.LInt%Type; l_tyLog ty_logManager := ty_logManager('system','003'); begin l_tyLog.up_Enter('sp_message_hisorderdata_create开始'); v_vc_temp1 := chr(1)||' '||chr(1)||' '||chr(1)||' '||chr(1)||' '; v_vc_temp2 := chr(1)||' '||chr(1)||' '||chr(1)||' '; v_vc_temp3 := chr(1)||' '||chr(1)||' '; v_vc_temp4 := chr(1)||' '; --zhoudy 2013-01-30 添加初始化赋值 v_vc_open_value := ''; v_l_total := 0; V_L_SPEAK_NO := 0; v_l_date := nvl(p_l_date,0); v_vc_customer := nvl(p_vc_customer,' '); if v_l_date = 0 then v_l_date := to_number(to_char(SYSDATE-1,'YYYYMMDD')); end if; FOR r IN (SELECT a.vc_customer_no ,a.l_product_no ,'3' AS c_sourcetype ,a.l_de_begin_date AS l_de_begin_date ,a.l_de_end_date AS l_de_end_date ,(SELECT WMSYS.WM_CONCAT(b.vc_open_value) FROM hscrm_dbo.orderinfo b WHERE b.vc_customer_no=a.vc_customer_no AND b.l_product_no=a.l_product_no and b.l_product_no < 20000) AS vc_open_value ,'1' AS c_processtype FROM hscrm_dbo.speakforrelation a WHERE --a.l_create_date <= v_l_date --a.l_create_date <= 20101026 --and a.l_product_no < 20000 --and a.l_create_date <= 20101024 --and (a.vc_customer_no = v_vc_customer or v_vc_customer = ' ') --and a.l_product_no=11003 GROUP BY vc_customer_no,l_product_no,l_de_begin_date,l_de_end_date ) LOOP v_vc_prefix := substr(r.vc_customer_no,1,3); if v_vc_prefix = 'CRM' then v_vc_customer_no := substr(r.vc_customer_no,4); v_vc_open_value_temp := r.vc_open_value; vc_product_temp := substr(to_char(r.l_product_no),1,1); if vc_product_temp = '1' then v_l_total := v_l_total + 1; vc_product_no := substr(to_char(r.l_product_no),2); SELECT COUNT(*) INTO v_l_count FROM hscrm_dbo.smsserviceparam WHERE vc_smsno = to_char(r.l_product_no); CASE WHEN v_l_count = 0 THEN v_vc_open_value := ''; WHEN v_l_count = 1 THEN v_vc_open_value := REPLACE(r.vc_open_value,v_vc_temp1); WHEN v_l_count = 2 THEN v_vc_open_value := REPLACE(r.vc_open_value,v_vc_temp2); WHEN v_l_count = 3 THEN v_vc_open_value := REPLACE(r.vc_open_value,v_vc_temp3); WHEN v_l_count = 4 THEN v_vc_open_value := REPLACE(r.vc_open_value,v_vc_temp4); --zhoudy 20130131 ELSE v_vc_open_value := REPLACE(r.vc_open_value,v_vc_temp4); END CASE; v_vc_open_value := REGEXP_REPLACE(v_vc_open_value,' '); v_vc_open_value := REPLACE(v_vc_open_value,',',chr(1)); --V_L_SPEAK_NO := r.L_SPEAK_NO; INSERT INTO THJZX_DZGX_IN_HIS2(KHH,CPBH,DZLY,DZSJ,DQSJ,DZLX,CS,CJRQ) VALUES(v_vc_customer_no ,vc_product_no ,r.c_sourcetype ,r.l_de_begin_date ,r.l_de_end_date ,r.c_processtype ,v_vc_open_value ,v_l_date); end if; end if; COMMIT; END LOOP; commit; l_tyLog.up_Leave('sp_message_hisorderdata_create处理结束,成功生成数'||v_l_total); exception when others then rollback; l_tyLog.up_Error('sp_message_orderdata_create error:'||v_vc_customer_no||':'||V_L_SPEAK_NO||':'||v_l_date||':'||vc_product_no||':'|| v_vc_open_value||':'||SQLCODE); end sp_message_hisorderdata_create;
片段解析:
初始化log的定义,其实现在type的内部;
l_tyLog ty_logManager := ty_logManager('system','003');
调用log具体子过程
l_tyLog.up_Error('sp_message_orderdata_create error:'||v_vc_customer_no||':'||V_L_SPEAK_NO||':'||v_l_date||':'||vc_product_no||':'|| v_vc_open_value||':'||SQLCODE);
l_tyLog.up_Leave('sp_message_hisorderdata_create处理结束,成功生成数'||v_l_total);
2、TYPE定义
上面初始化时调用的TY_LOGMANAGER是TYPE构造函数是的,整个TYPE的定义如下,注意其中的Member成员定义。
CREATE OR REPLACE TYPE "TY_LOGMANAGER" AS OBJECT ( /* * $Header: $ * * * Overview: 日志管理器,封装LOG,规范化LOG的输出 实现了“多个Session的区别、性能问题定位、错误堆栈信息”, 设有LogLevel开关 * * NOTES: NULL *--系统支持的LOG基本设置 *C_LOG_DEBUG CONSTANT NUMBER(1) := 1; *C_LOG_INFO CONSTANT NUMBER(1) := 2; *C_LOG_WARN CONSTANT NUMBER(1) := 3; *C_LOG_ERROR CONSTANT NUMBER(1) := 4; *--当前系统LOG的设置 *C_CURR_LOG_LEVEL CONSTANT NUMBER(1) := C_LOG_DEBUG; *C_CURR_PER_LEVEL CONSTANT NUMBER(10) := 1000; --单位(百分之一秒)除以100即为秒数 */ ---成员属性 -- 对象生成的时间 C_CURR_LOG_LEVEL NUMBER, C_CURR_PER_LEVEL NUMBER, m_nStartTime NUMBER, m_nSessionID CHAR(20), m_varTerminal VARCHAR2(16), m_varBusinessCode CHAR(100), m_chOperator CHAR(20), ---成员函数 -- 构造函数 CONSTRUCTOR FUNCTION ty_logManager ( i_Operator IN CHAR DEFAULT NULL, i_varBusinessCode IN VARCHAR2 DEFAULT NULL ) RETURN SELF AS RESULT, -- 函数入口输出重要信息 MEMBER PROCEDURE up_Enter(i_varMsg IN VARCHAR2 DEFAULT NULL), -- 正常调用SP结束 MEMBER PROCEDURE up_Leave(i_varMsg IN VARCHAR2 DEFAULT NULL), -- 输出up_Debug信息到日志表 MEMBER PROCEDURE up_Debug(i_LogDesc IN VARCHAR2), -- 输出up_Info信息到日志表 MEMBER PROCEDURE up_Info(i_LogDesc IN VARCHAR2), -- 输出up_Warning信息到日志表 MEMBER PROCEDURE up_Warning(i_LogDesc IN VARCHAR2), -- 输出up_Error信息到日志表 MEMBER PROCEDURE up_Error(i_LogDesc IN VARCHAR2), -- 往T_LOG中插入记录 MEMBER PROCEDURE up_InsertLog ( i_LOGID IN NUMBER, i_LOGDATE IN CHAR, i_LOGTIME IN CHAR, i_LogLevel IN CHAR, i_ELAPSETIME IN NUMBER, i_SESSIONID IN CHAR, i_TERMINAL IN CHAR, i_Operator IN CHAR, i_LOGDESC IN VARCHAR2 ) )
3、TYPE BOBY定义
上面的TYPE体中定义了各个级别的Log处理Member子过程,其具体实现则在TYPE BODY中进行,源码如下:
注意其实现中的公用过程的定义。
CREATE OR REPLACE TYPE BODY ty_logManager IS /************************************************************************* 【函数功能】构造LOG对象,记录开始此对象生成的开始时间,并记录日志 【使用情况】构造函数,对象定义时自动调用 【参数说明】i_varBusinessCode IN VARCHAR2,一般传入调用的SP程序名或者业务对应的代号 【异常处理】出错时,处理所有异常,不抛出异常 *************************************************************************/ CONSTRUCTOR FUNCTION ty_logManager ( i_Operator IN CHAR DEFAULT NULL, i_varBusinessCode IN VARCHAR2 DEFAULT NULL ) RETURN SELF AS RESULT IS BEGIN m_nStartTime := dbms_utility.get_time; m_nSessionID := userenv('sessionid'); m_varTerminal := userenv('terminal'); m_varBusinessCode := i_varBusinessCode; m_chOperator := i_Operator; RETURN; EXCEPTION WHEN OTHERS THEN NULL; END; /************************************************************************* 【函数功能】 调用SP接口的入口,记录重要参数信息 【注意事项】一般在SP结束时调用 【参数说明】i_SPName IN VARCHAR2,一般传入调用的SP程序名 【异常处理】出错时,处理所有异常,不抛出异常 *************************************************************************/ MEMBER PROCEDURE up_Enter(i_varMsg IN VARCHAR2 DEFAULT NULL) IS BEGIN up_Info(i_varMsg || ',Enter.'); EXCEPTION WHEN OTHERS THEN NULL; END; /************************************************************************* 【函数功能】正常调用SP结束,记录时间统计信息 【异常处理】出错时,处理所有异常,不抛出异常 *************************************************************************/ MEMBER PROCEDURE up_Leave(i_varMsg IN VARCHAR2 DEFAULT NULL) IS BEGIN up_Info(i_varMsg || ',Leave.'); EXCEPTION WHEN OTHERS THEN NULL; END; /************************************************************************* 【函数功能】输出up_Debug信息到日志表 T_LOG 【注意事项】注意参数的长度和数据库一致 【异常处理】出错时,处理所有异常,不抛出异常。 *************************************************************************/ MEMBER PROCEDURE up_Debug(i_LogDesc IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; l_date CHAR(8); l_time CHAR(8); l_LogID NUMBER(10); BEGIN SELECT to_char(SYSDATE, 'yyyymmdd'), to_char(SYSDATE, 'hh24miss'), seq_syslog.NEXTVAL INTO l_date, l_time, l_LogID FROM dual; up_InsertLog(l_LogID, l_date, l_time, '1',--Debug (dbms_utility.get_time - m_nStartTime), m_nSessionID, m_varTerminal, m_chOperator, i_LOGDESC); COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; END; /************************************************************************* 【函数功能】输出up_Info信息到日志表 T_LOG 【注意事项】注意参数的长度和数据库一致 【异常处理】出错时,处理所有异常,不抛出异常 *************************************************************************/ MEMBER PROCEDURE up_Info(i_LogDesc IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; l_date CHAR(8); l_time CHAR(8); l_LogID NUMBER(10); BEGIN SELECT to_char(SYSDATE, 'yyyymmdd'), to_char(SYSDATE, 'hh24miss'), seq_syslog.NEXTVAL INTO l_date, l_time, l_LogID FROM dual; up_InsertLog(l_LogID, l_date, l_time, '2',--Info (dbms_utility.get_time - m_nStartTime), m_nSessionID, m_varTerminal, m_chOperator, i_LOGDESC); COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; END; /************************************************************************* 【函数功能】输出up_Warning信息到日志表 T_LOG 【注意事项】注意参数的长度和数据库一致 【异常处理】出错时,处理所有异常,不抛出异常 *************************************************************************/ MEMBER PROCEDURE up_Warning(i_LogDesc IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; l_date CHAR(8); l_time CHAR(8); l_LogID NUMBER(10); BEGIN SELECT to_char(SYSDATE, 'yyyymmdd'), to_char(SYSDATE, 'hh24miss'), seq_syslog.NEXTVAL INTO l_date, l_time, l_LogID FROM dual; up_InsertLog(l_LogID, l_date, l_time, '3',--Warn (dbms_utility.get_time - m_nStartTime), m_nSessionID, m_varTerminal, m_chOperator, i_LOGDESC); COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; END; /************************************************************************* 【函数功能】输出up_Error信息到日志表 T_LOG 【注意事项】注意参数的长度和数据库一致 【异常处理】出错时,处理所有异常,不抛出异常 *************************************************************************/ MEMBER PROCEDURE up_Error(i_LogDesc IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; l_date CHAR(8); l_time CHAR(8); l_LogID NUMBER(10); BEGIN SELECT to_char(SYSDATE, 'yyyymmdd'), to_char(SYSDATE, 'hh24miss'), seq_syslog.NEXTVAL INTO l_date, l_time, l_LogID FROM dual; up_InsertLog(l_LogID, l_date, l_time, '4',--Error (dbms_utility.get_time - m_nStartTime), m_nSessionID, m_varTerminal, m_chOperator, i_LOGDESC || CHR(10) || DBMS_UTILITY.FORMAT_Error_BACKTRACE); COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; END; /************************************************************************* 【函数功能】往日志表T_LOG中插入一条记录 【使用情况】建议外部不要直接调用 【异常处理】出错时,不处理任何异常 *************************************************************************/ MEMBER PROCEDURE up_InsertLog ( i_LOGID IN NUMBER, i_LOGDATE IN CHAR, i_LOGTIME IN CHAR, i_LogLevel IN CHAR, i_ELAPSETIME IN NUMBER, i_SESSIONID IN CHAR, i_TERMINAL IN CHAR, i_Operator IN CHAR, i_LOGDESC IN VARCHAR2 ) IS BEGIN C_CURR_LOG_LEVEL := to_number(sp_message_sysparameters_get(0,5029));--1 C_CURR_PER_LEVEL := to_number(sp_message_sysparameters_get(0,5030));--1000 IF C_CURR_LOG_LEVEL <= i_LogLevel OR C_CURR_PER_LEVEL <= i_ELAPSETIME THEN INSERT INTO syslog (l_serial_no ,l_date ,l_time ,c_loglevel ,l_elapsetime ,vc_sessionid ,vc_terminal ,vc_businesscode ,vc_operator_no ,vc_logdesc) VALUES (i_LOGID, i_LOGDATE, i_LOGTIME, i_LogLevel, i_ELAPSETIME, i_SESSIONID, i_TERMINAL, m_varBUSINESSCODE, i_Operator, i_LOGDESC); END IF; END; END;
4、日志截图展示
可见上面初始化时候的类型为“system”,vc_logdesc字段则记录了我们在调用地方记录日志的文本提示信息,如操作的记录id、产品id、以及报错信息、ora0000等的方便我们排查的信息。
文章小结
由上面可以看到通过层层封装,最终我们的日志信息是写入了syslog表进行了统一管理,并通过TYPE定义了各个级别的日志写入柄对外提供各个级别日志的信息写入。
相关文章推荐
- (一个代码学会c语言操作数据库)linux上通过c语言操作数据库实现基本的学生信息管理系统(增、删、查、改‘显示)
- [Oracle DB管理] 通过数据库的锁实现Java中DML的顺序批次执行
- oracle:通过触发器实现对数据库对象增删改动作的审计
- 2.配置通过数据库接收SaltStack批量管理日志
- JDBC通过DatabaseMetaData对象了解数据库信息
- 超详细Oracle 12c数据库对象管理操作
- jdbc,数据库案例:客户信息管理系统:jsp部分,数据库数据封装类,dao接口和实现
- 发布一个C#+ADOMD.NET实现查看分析服务数据库信息的类对象
- 基于flume的日志管理系统实现 推荐
- 两步实现Log4j记录java控制台输出的系统所有异常信息和自定义记录日志---->非常实用,强烈推荐阅读
- 源码-Oracle数据库管理-第十三章-子程序和包-Part 1(定义子程序)
- Greenplum+Hadoop学习笔记-14-定义数据库对象之创建与管理模式
- 2.配置通过数据库接收SaltStack批量管理日志
- Oracle 11g 通过创建物化视图实现不同数据库间的表数据同步
- 玩转mongodb(九):通过log4jmongo来实现分布式系统的日志统一管理
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
- JDBC通过DatabaseMetaData对象了解数据库信息
- OpenERP 7中通过销售团队设置来实现客户信息的管理权限
- Oracle信息安全管理架构帮助企业实现“由内到外”的整体安全
- Oracle对象类型(TYPE)之MEMBER