您的位置:首页 > 数据库 > Oracle

Oracle数据库通过定义TYPE及Member对象来实现日志信息的分级管理 推荐

2013-01-31 10:29 1006 查看
调用路径:

存储过程-》调用函数初始化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定义了各个级别的日志写入柄对外提供各个级别日志的信息写入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Oracle 数据库 记录 TYPE
相关文章推荐