调用路径:
存储过程-》调用函数初始化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)||' ';
-
-
- 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_product_no < 20000
-
-
-
- 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);
-
- 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));
-
- 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
- *
- *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;
- *
- *C_CURR_LOG_LEVEL CONSTANT NUMBER(1) := C_LOG_DEBUG;
- *C_CURR_PER_LEVEL CONSTANT NUMBER(10) := 1000;
- */
-
-
-
- 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),
-
-
- MEMBER PROCEDURE up_Leave(i_varMsg IN VARCHAR2 DEFAULT NULL),
-
-
- MEMBER PROCEDURE up_Debug(i_LogDesc IN VARCHAR2),
-
-
- MEMBER PROCEDURE up_Info(i_LogDesc IN VARCHAR2),
-
-
- MEMBER PROCEDURE up_Warning(i_LogDesc IN VARCHAR2),
-
-
- MEMBER PROCEDURE up_Error(i_LogDesc IN VARCHAR2),
-
-
- 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',
- (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',
- (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',
- (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',
- (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));
- C_CURR_PER_LEVEL := to_number(sp_message_sysparameters_get(0,5030));
- 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定义了各个级别的日志写入柄对外提供各个级别日志的信息写入。
本文转自danni505 51CTO博客,原文链接:http://blog.51cto.com/danni505/1130084,如需转载请自行联系原作者