1. 程式人生 > >通過Oracle的email實現資料庫自動告警

通過Oracle的email實現資料庫自動告警


一、郵件配置部分

1、建立訪問控制列表

BEGIN

dbms_network_acl_admin.create_acl(acl =>email_server_ftoa.xml'

,description =>'FTOA'

,principal =>'SYSTEM'

,is_grant =>TRUE

,privilege =>'connect'

,start_date =>NULL

    ,end_date => NULL);

END;

/

PL/SQL procedure successfully completed

注意:

(1)這裡privilege要用小寫,否則出現ORA-24245

錯誤:

(2)ACL格式中xml字尾要小寫,否則出現ORA-46059錯誤

2、伺服器授權

BEGIN

dbms_network_acl_admin.assign_acl(acl =>'ftoa_email_server.xml'

,host =>'10.41.128.1'

,lower_port =>85

,upper_port =>85);

END;

/

PL/SQL procedure successfully completed

注意:

(1)acl名稱與上面create的要一樣,否則出現ORA-31001 : 資源控制代碼或路徑名 "/sys/acls/******.xml"

無效 錯誤;

(2)訪問埠需要正確,否則應用發郵件時會出現ORA-24247:網路訪問被訪問控制列表 (ACL)拒絕 錯誤

3、傳送郵件的通用儲存過程

照搬了網上一個現成的儲存過程,蠻好用的

CREATEORREPLACEPROCEDURE P_SENDMAIL(P_TXT       VARCHAR2,

P_SUB      VARCHAR2,

P_SENDOR   VARCHAR2,

P_RECEIVER VARCHAR2,

P_USER     VARCHAR2DEFAULTNULL,

P_PASS      VARCHAR2DEFAULTNULL,

P_FILENAME VARCHAR2

DEFAULTNULL,

P_ENCODE   VARCHAR2DEFAULT'bit 7')

AUTHIDCURRENT_USERIS

/*

作用:用oracle傳送郵件

主要功能:1、支援多收件人。

2、支援中文

3、支援抄送人

4、支援大於32K的附件

5、支援多行正文

6、支援多附件

7、支援文字附件和二進位制附件

8、支援HTML格式

9、支援

作者:suk

引數說明:

p_txt :郵件正文

p_sub: 郵件標題

p_SendorAddress : 傳送人郵件地址

p_ReceiverAddress : 接收地址,可以同時傳送到多個地址上,地址之間用","或者";"隔開

p_EmailServer : 郵件伺服器地址,可以是域名或者IP

p_Port :郵件伺服器埠

p_need_smtp:是否需要smtp認證,0表示不需要,1表示需要

p_user:smtp驗證需要的使用者名稱

p_pass:smtp驗證需要的密碼

p_filename:附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"

可以有多個附件,附件名稱只見用逗號或者分號分隔

p_encode:附件編碼轉換格式,其中 p_encode='bit 7' 表示文字型別附件

p_encode='base64'表示二進位制型別附件

注意:

1、對於文字型別的附件,不能用base64的方式傳送,否則出錯

2、對於多個附件只能用同一種格式傳送

*/

二、應用部分

1、建立郵件待發送表、傳送歷史表

droptable MAIL_TOSEND;

createtable MAIL_TOSEND

(

idVARCHAR2(32)notnull,

fsr  VARCHAR2(100),

jsr  VARCHAR2(4000),

csr  VARCHAR2(4000),

yjnr VARCHAR2(2000),

czrq DATE,

pch  VARCHAR2(100)notnull

);

altertable MAIL_TOSENDaddconstraintPK_MAIL_TOSENDprimarykey (ID, PCH)  usingindex;

commentoncolumnMAIL_TOSEND.id is'序列SEQ_TXID產生';

commentoncolumnMAIL_TOSEND.fsr is'傳送人,預設是admin_sx';

commentoncolumnMAIL_TOSEND.jsr is'接收人,可多個用逗號分隔';

commentoncolumnMAIL_TOSEND.csr is'抄送人,可多個用逗號分隔';

commentoncolumnMAIL_TOSEND.yjnr is'郵件內容,html原始碼';

commentoncolumnMAIL_TOSEND.czrq is'操作日期';

commentoncolumnMAIL_TOSEND.pch is'批次號';

droptable MAIL_SENT;

createtable MAIL_SENT

(

idVARCHAR2(32)notnull,

fsr  VARCHAR2(100),

jsr  VARCHAR2(4000),

csr  VARCHAR2(4000),

yjnr VARCHAR2(2000),

czrq DATE,

fsrq DATE,

fszt NUMBER(1)notnull,

bcxx VARCHAR2(4000),

pch  VARCHAR2(100)notnull

);

altertable MAIL_SENTaddconstraint PK_MAIL_SENTprimarykey (PCH,ID, FSZT)usingindex;

commentoncolumnMAIL_SENT.id is'序列號';

commentoncolumnMAIL_SENT.fsr is'傳送人';

commentoncolumnMAIL_SENT.jsr is'接收人';

commentoncolumnMAIL_SENT.csr is'抄送人';

commentoncolumnMAIL_SENT.yjnr is'郵件內容';

commentoncolumnMAIL_SENT.czrq is'操作日期';

commentoncolumnMAIL_SENT.fsrq is'傳送日期';

commentoncolumnMAIL_SENT.fszt is'傳送狀態1:成功 0';

commentoncolumnMAIL_SENT.bcxx is'報錯資訊';

commentoncolumnMAIL_SENT.pch is'批次號';

2、收集告警資訊併發送郵件的儲存過程

根據個人需求不同,選擇不同的收集物件,我這裡主要跟蹤3個內容:

(1)GoldenGate的錯誤

--建立GoldenGate日誌外部表

createorreplacedirectory gg_dir as'/gg';

droptable ggserr_log_ext;

createtable ggserr_log_ext

(

txt varchar2(2000)

)

organizationexternal

(

type oracle_loader

defaultdirectory gg_dir

accessparameters

(

records delimitedby newline

fields terminatedby "\r\n"

)

location('ggserr.log'));

--收集GoldenGate故障

select WM_CONCAT(MSG)from(

select'<br> <br/> GoldenGate同步故障:<br> <br /> 開始時間:'||to_char(min(dt),'yyyy-mm-ddhh24:mi:ss')

||'<br> <br />故障資訊:'||ERRMSG MSG

from (Select TO_DATE(SUBSTR(TXT,1,19),'YYYY-MM-DD HH24:MI:SS')DT,SUBSTR(TXT,INSTR(TXT,',')+2) ERRMSG

from ggserr_log_extwhere txtlike'%ERROR%'AND TXTNOTLIKE'%ABEND%')

groupby ERRMSGhavingmax(dt)>sysdate-1/24 );

(2)alert告警

--建立alert外部表

createorreplacedirectory alert_dir as'/orahome/app/oracle/diag/rdbms/sxcz/sxcz/trace';

droptable alert_log_ext;

createtable alert_log_ext

(

text varchar2(2000)

)

organizationexternal

(

type oracle_loader

defaultdirectory alert_dir

accessparameters

(

records delimitedby newline

fields terminatedby "\r\n"

)

location('alert_sxcz.log'));

--收集ALERT日誌告警

with t_alertas

(select ROWNUM r,casewhen text like'%__:__:__ 20__%'then'DT'ELSE'EXCEPTION'ENDASTYPE,TEXT

from alert_log_ext

where UPPER(text)like'%ORA-%'

OR textlike'%__:__:__ 20__%')

select WM_CONCAT(MSG)from(

select V_MSG2||'<br><br /> Alert告警:<br> <br />  開始時間:'||to_char(min(start_time),'yyyy-mm-dd hh24:mi:ss')

||'-'||to_char(max(start_time),'yyyy-mm-dd hh24:mi:ss')

||'<br> <br />告警資訊:'||text MSG

from

(

select r,casewhen start_time isnullthenlag(to_date(start_time,'Dy Mon DDHH24:MI:SS YYYY','NLS_DATE_LANGUAGE=AMERICAN') ignorenulls) over(orderby r) else to_date(start_time,'Dy Mon DD HH24:MI:SS YYYY','NLS_DATE_LANGUAGE=AMERICAN')end start_time,textfrom

(

select r,type,text,lagtype,casewhen lagtype='DT'then Lag(text,1) OVER(ORDERBY R)elsenullend start_timefrom

(

select r,TYPE,text,lag(type,1) OVER(ORDERBY R) lagtype

from t_alert

)

) wheretype='EXCEPTION'

)

groupby text);

(2)broken狀態的job

select WM_CONCAT('<br> <br /> JOB停止執行:<br> <br /> JOB_ID:'||JOB||'<br> <br />USER:'||log_user

||'<br> <br /> STOP_TIME:'||TO_CHAR(LAST_DATE,'YYYY-MM-DDHH24:MI:SS')

||'<br> <br /> CONTENTS:'||CHR(13)||CHR(9)||WHAT)

from dba_jobs

where BROKEN='Y'AND LOG_USER NOT IN('SYS','SYSTEM');

   這個程式還涉及到不同的告警傳送給不同的使用者,內容重複的告警如何處理等具體處理,不在一一表述,還是這句話,根據自己的需求做處理。

3、把寫好的儲存過程放在job或者伺服器crontab裡定時執行,這是我收到的郵件