Defining a PL/SQL-based Notification Method

Creating a PL/SQL-based notification method consists of four steps:

  1. Define the PL/SQL procedure.
  2. Create the PL/SQL procedure on the Management Repository.
  3. Register your PL/SQL procedure as a new notification method.
  4. Assign the notification method to an incident rule.

Example 6-9 PL/SQL Procedure Required Information

Name Open trouble ticket
Description Notification method to open a trouble ticket in the event
PLSQL Procedure ticket_sys.ticket_ops.open_ticket

Example 6-10 PL/SQL Script

-- Assume log_table is created by following DDL
-- CREATE TABLE log_table (message VARCHAR2(4000)) ;
-- Define PL/SQL notification method for Events
CREATE OR REPLACE PROCEDURE log_table_notif_proc(s IN GC$NOTIF_EVENT_MSG)
IS
  l_categories gc$category_string_array;
  l_category_codes gc$category_string_array;
  l_attrs gc$notif_event_attr_array;
  l_ca_obj gc$notif_corrective_action_job;
BEGIN
  INSERT INTO log_table VALUES ('notification_type: ' || s.msg_info.notification_type);
  INSERT INTO log_table VALUES ('repeat_count: ' || s.msg_info.repeat_count);
  INSERT INTO log_table VALUES ('ruleset_name: ' || s.msg_info.ruleset_name);
  INSERT INTO log_table VALUES ('rule_name: ' || s.msg_info.rule_name);
  INSERT INTO log_table VALUES ('rule_owner: ' || s.msg_info.rule_owner);
  INSERT INTO log_table VALUES ('message: ' || s.msg_info.message);
  INSERT INTO log_table VALUES ('message_url: ' || s.msg_info.message_url);
  INSERT INTO log_table VALUES ('event_instance_guid: ' || s.event_payload.event_instance_guid);
  INSERT INTO log_table VALUES ('event_type: ' || s.event_payload.event_type);
  INSERT INTO log_table VALUES ('event_name: ' || s.event_payload.event_name);
  INSERT INTO log_table VALUES ('event_msg: ' || s.event_payload.event_msg);
  INSERT INTO log_table VALUES ('source_obj_type: ' || s.event_payload.source.source_type);
  INSERT INTO log_table VALUES ('source_obj_name: ' || s.event_payload.source.source_name);
  INSERT INTO log_table VALUES ('source_obj_url: ' || s.event_payload.source.source_url);
  INSERT INTO log_table VALUES ('target_name: ' || s.event_payload.target.target_name);
  INSERT INTO log_table VALUES ('target_url: ' || s.event_payload.target.target_url);
  INSERT INTO log_table VALUES ('severity: ' || s.event_payload.severity);  INSERT INTO log_table VALUES ('severity_code: ' || s.event_payload.severity_code);
  INSERT INTO log_table VALUES ('event_reported_date: ' || to_char(s.event_payload.reported_date, 'D MON DD HH24:MI:SS'));

  l_categories := s.event_payload.categories;
  IF l_categories IS NOT NULL
  THEN
    FOR c IN 1..l_categories.COUNT
    LOOP
      INSERT INTO log_table VALUES ('category ' || c || ' - ' || l_categories(c));
    END LOOP;
  END IF;

  l_category_codes := s.event_payload.category_codes;
  IF l_categories IS NOT NULL
  THEN
    FOR c IN 1..l_category_codes.COUNT
    LOOP
      INSERT INTO log_table VALUES ('category_code ' || c || ' - ' || l_category_codes(c));
    END LOOP;
  END IF;

  l_attrs := s.event_payload.event_attrs;
  IF l_attrs IS NOT NULL
  THEN
    FOR c IN 1..l_attrs.COUNT
    LOOP
        INSERT INTO log_table VALUES ('EV.ATTR name=' || l_attrs(c).name || ' value=' || l_attrs(c).value || ' nls_value=' || l_attrs(c).nls_value);    END LOOP;
  END IF;

COMMIT ;
END ;
/

Example 6-11 PL/SQL Script to Log Events to a Table

CREATE TABLE event_log (
  notification_type      VARCHAR2(32),
  repeat_count           NUMBER,
  ruleset_name           VARCHAR2(256),
  rule_owner             VARCHAR2(256),
  rule_name              VARCHAR2(256),
  message                VARCHAR2(4000),
  message_url            VARCHAR2(4000),
  event_instance_guid    RAW(16),
  event_type             VARCHAR2(20),
  event_name             VARCHAR2(512),
  event_msg              VARCHAR2(4000),
  categories             VARCHAR2(4000),
  source_obj_type        VARCHAR2(120),
  source_obj_name        VARCHAR2(256),
  source_obj_url         VARCHAR2(4000),
  severity               VARCHAR2(128),
  severity_code          VARCHAR2(32),
  target_name            VARCHAR2(256),
  target_type            VARCHAR2(128),
  target_url             VARCHAR2(4000),
  host_name              VARCHAR2(256),
  timezone               VARCHAR2(64),
  occured                DATE,
  ca_guid                RAW(16),
  ca_name                VARCHAR2(128),
  ca_owner               VARCHAR2(256),
  ca_type                VARCHAR2(256),
  ca_status              VARCHAR2(64),
  ca_status_code         NUMBER,
  ca_job_step_output     VARCHAR2(4000),
  ca_execution_guid      RAW(16),
  ca_stage_change_guid   RAW(16)
)
;

CREATE OR REPLACE PROCEDURE log_event(s IN GC$NOTIF_EVENT_MSG)
IS
   l_categories gc$category_string_array;
   l_ca_obj gc$notif_corrective_action_job;
   l_categories_new VARCHAR2(1000);
BEGIN
    -- save event categories
   l_categories := s.event_payload.categories;
        IF l_categories IS NOT NULL
   THEN
     FOR c IN 1..l_categories.COUNT
     LOOP
       l_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||',');
     END LOOP;
   END IF;

   -- save event message
   IF s.msg_info.notification_type = 'NOTIF_CA' AND s.event_payload.corrective_action IS NOT NULL
   THEN
     l_ca_obj := s.event_payload.corrective_action;
      INSERT INTO event_log (notification_type, repeat_count, ruleset_name, rule_name, rule_owner, message, message_url, event_instance_guid, event_type, event_name, event_msg, categories, source_obj_type, source_obj_name, source_obj_url, severity, severity_code, target_name, target_type, target_url, host_name, timezone, occured, ca_guid, ca_name, ca_owner, ca_type, ca_status, ca_status_code, ca_job_step_output, ca_execution_guid, ca_stage_change_guid)
      VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_name,s.msg_info.rule_owner, s.msg_info.message, s.msg_info.message_url, s.event_payload.event_instance_guid, s.event_payload.event_type, s.event_payload.event_name, s.event_payload.event_msg, l_categories_new, s.event_payload.source.source_type, s.event_payload.source.source_name, s.event_payload.source.source_url, s.event_payload.severity, s.event_payload.severity_code, s.event_payload.target.target_name, s.event_payload.target.target_type, s.event_payload.target.target_url, s.event_payload.target.host_name, s.event_payload.target.target_timezone, s.event_payload.occurrence_date, l_ca_obj.JOB_GUID, l_ca_obj.JOB_NAME, l_ca_obj.JOB_OWNER, l_ca_obj.JOB_TYPE, l_ca_obj.JOB_STATUS, l_ca_obj.JOB_STATUS_CODE, l_ca_obj.JOB_STEP_OUTPUT, l_ca_obj.JOB_EXECUTION_GUID, l_ca_obj.JOB_STATE_CHANGE_GUID);   ELSE
      INSERT INTO event_log (notification_type, repeat_count, ruleset_name, rule_name, rule_owner, message, message_url, event_instance_guid, event_type, event_name, event_msg, categories, source_obj_type, source_obj_name, source_obj_url, severity, severity_code, target_name, target_type, target_url, host_name, timezone, occured, ca_guid, ca_name, ca_owner, ca_type, ca_status, ca_status_code, ca_job_step_output, ca_execution_guid, ca_stage_change_guid)
      VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_name, s.msg_info.rule_owner, s.msg_info.message, s.msg_info.message_url, s.event_payload.event_instance_guid, s.event_payload.event_type, s.event_payload.event_name, s.event_payload.event_msg, l_categories_new, s.event_payload.source.source_type, s.event_payload.source.source_name, s.event_payload.source.source_url, s.event_payload.severity, s.event_payload.severity_code, s.event_payload.target.target_name, s.event_payload.target.target_type, s.event_payload.target.target_url, s.event_payload.target.host_name, s.event_payload.target.target_timezone, s.event_payload.occurrence_date, null,null,null,null,null,null,null,null,null);
   END IF;
   COMMIT;
END log_event;
/

Example 6-12 PL/SQL Script to Log Incidents to a Table

CREATE TABLE incident_log ( 
  notification_type      VARCHAR2(32), 
  repeat_count           NUMBER, 
  ruleset_name           VARCHAR2(256), 
  rule_owner             VARCHAR2(256), 
  rule_name              VARCHAR2(256), 
  message                VARCHAR2(4000), 
  message_url            VARCHAR2(4000), 
  incident_id            VARCHAR2(128), 
  ticket_url             VARCHAR2(4000), 
  assoc_event_cnt        NUMBER, 
  severity               VARCHAR2(128), 
  severity_code          VARCHAR2(32), 
  priority               VARCHAR2(128), 
  priority_code          VARCHAR2(32), 
  status                 VARCHAR2(32), 
  categories             VARCHAR2(1000), 
  target_name            VARCHAR2(256), 
  target_type            VARCHAR2(128), 
  host_name              VARCHAR2(256), 
  timezone               VARCHAR2(64), 
  occured                DATE 
) 
; 
   CREATE OR REPLACE PROCEDURE log_incident(s IN GC$NOTIF_INCIDENT_MSG) 
IS 
   l_src_info_array GC$NOTIF_SOURCE_INFO_ARRAY; 
   l_src_info  GC$NOTIF_SOURCE_INFO; 
   l_categories gc$category_string_array; 
   l_target_obj GC$NOTIF_TARGET; 
   l_target_name VARCHAR2(256); 
   l_target_type VARCHAR2(256); 
   l_target_timezone VARCHAR2(256); 
   l_hostname VARCHAR2(256); 
   l_categories_new VARCHAR2(1000); 
BEGIN 
     -- Save Incident categories 
  IF l_categories IS NOT NULL 
   THEN 
     FOR c IN 1..l_categories.COUNT 
     LOOP 
       l_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||','); 
     END LOOP; 
   END IF; 

   -- GET target info 
   l_src_info_array := s.incident_payload.incident_attrs.source_info_arr; 
   IF l_src_info_array IS NOT NULL 
   THEN 
     FOR I IN 1..l_src_info_array.COUNT 
     LOOP 
       IF l_src_info_array(I).TARGET IS NOT NULL 
       THEN 
         l_target_name := l_src_info_array(I).TARGET.TARGET_NAME; 
         l_target_type := l_src_info_array(I).TARGET.TARGET_TYPE; 
         l_target_timezone := l_src_info_array(I).TARGET.TARGET_TIMEZONE; 
         l_hostname := l_src_info_array(I).TARGET.HOST_NAME; 
      END IF; 
     END LOOP; 
   END IF; 

   -- save Incident notification message    INSERT INTO incident_log(notification_type, repeat_count, ruleset_name, rule_owner, rule_name, message, message_url, incident_id, ticket_url, assoc_event_cnt, severity, severity_code, priority, priority_code, status, categories, target_name, target_type, host_name, timezone, occured) 
   VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_owner, s.msg_info.rule_name, s.msg_info.message, s.msg_info.message_url, s.incident_payload.incident_attrs.id, s.incident_payload.ticket_url, s.incident_payload.assoc_event_count, s.incident_payload.incident_attrs.severity, s.incident_payload.incident_attrs.severity_code, s.incident_payload.incident_attrs.priority, s.incident_payload.incident_attrs.priority_code, s.incident_payload.incident_attrs.STATUS, l_categories_new, l_target_name, l_target_type, l_hostname,l_target_timezone, s.incident_payload.incident_attrs.creation_date); 
   COMMIT; 
END log_incident; 
/

Example 6-13 PL/SQL Script to Log Problems to a Table

CREATE TABLE problem_log ( 
  notification_type      VARCHAR2(32), 
  repeat_count           NUMBER, 
  ruleset_name           VARCHAR2(256), 
  rule_owner             VARCHAR2(256), 
  rule_name              VARCHAR2(256), 
  message                VARCHAR2(4000), 
  message_url            VARCHAR2(4000), 
  problem_key            VARCHAR2(850), 
  assoc_incident_cnt     NUMBER, 
  problem_id             NUMBER, 
  owner                  VARCHAR2(256), 
  severity               VARCHAR2(128), 
  severity_code          VARCHAR2(32), 
  priority               VARCHAR2(128), 
  priority_code          VARCHAR2(32), 
  status                 VARCHAR2(32), 
  categories             VARCHAR2(1000), 
  target_name            VARCHAR2(256), 
  target_type            VARCHAR2(128), 
  host_name              VARCHAR2(256),   timezone               VARCHAR2(64), 
  occured                DATE 
) 
; 
     CREATE OR REPLACE PROCEDURE log_problem(s IN GC$NOTIF_PROBLEM_MSG) 
IS 
   l_src_info_array GC$NOTIF_SOURCE_INFO_ARRAY; 
   l_src_info  GC$NOTIF_SOURCE_INFO; 
   l_categories gc$category_string_array; 
   l_target_obj GC$NOTIF_TARGET; 
   l_target_name VARCHAR2(256); 
   l_target_type VARCHAR2(256); 
   l_target_timezone VARCHAR2(256); 
   l_hostname VARCHAR2(256); 
   l_categories_new VARCHAR2(1000); 
BEGIN 
     -- Save Problem categories 
  l_categories := s.problem_payload.problem_attrs.categories; 
  IF l_categories IS NOT NULL 
   THEN 
     FOR c IN 1..l_categories.COUNT 
     LOOP 
       l_categories_new := (l_categories_new|| c || ' - ' || l_categories(c)||','); 
     END LOOP; 
   END IF; 

   -- GET target info 
   l_src_info_array := s.problem_payload.problem_attrs.source_info_arr; 
   IF l_src_info_array IS NOT NULL 
   THEN 
     FOR I IN 1..l_src_info_array.COUNT 
     LOOP 
       IF l_src_info_array(I).TARGET IS NOT NULL 
       THEN 
         l_target_name := l_src_info_array(I).TARGET.TARGET_NAME; 
         l_target_type := l_src_info_array(I).TARGET.TARGET_TYPE; 
         l_target_timezone := l_src_info_array(I).TARGET.TARGET_TIMEZONE; 
         l_hostname := l_src_info_array(I).TARGET.HOST_NAME; 
      END IF; 
     END LOOP; 
   END IF; 

  -- save Problem notification message 
   INSERT INTO problem_log(notification_type, repeat_count, ruleset_name, rule_owner, rule_name, message, message_url, problem_key, assoc_incident_cnt, problem_id, owner,  severity, severity_code, priority, priority_code, status, categories, target_name, target_type, host_name, timezone, occured) 
   VALUES (s.msg_info.notification_type, s.msg_info.repeat_count, s.msg_info.ruleset_name, s.msg_info.rule_owner, s.msg_info.rule_name, s.msg_info.message, s.msg_info.message_url, s.problem_payload.problem_key,            s.problem_payload.ASSOC_INCIDENT_COUNT, s.problem_payload.problem_attrs.id,            s.problem_payload.problem_attrs.owner, s.problem_payload.problem_attrs.severity,            s.problem_payload.problem_attrs.severity_code, s.problem_payload.problem_attrs.PRIORITY, s.problem_payload.problem_attrs.PRIORITY_CODE, s.problem_payload.problem_attrs.status, l_categories_new, l_target_name, l_target_type, l_hostname,l_target_timezone, s.problem_payload.problem_attrs.CREATION_DATE); 
   COMMIT; 
END log_problem; 
/

Step 1: Define the PL/SQL Procedure

The procedure must have one of the following signatures depending on the type of notification that will be received.

For Events:

PROCEDURE event_proc(event_msg IN gc$notif_event_msg)

For Incidents:

PROCEDURE incident_proc(incident_msg IN gc$notif_incident_msg)

For Problems:

PROCEDURE problem_proc(problem_msg IN gc$notif_problem_msg)

Note:

The notification method based on a PL/SQL procedure must be configured by an administrator with Super Administrator privileges before a user can select it while creating/editing a incident rule.

For more information on passing specific types of information to scripts or PL/SQL procedures, see the following sections:

"Passing Information to a PL/SQL Procedure"

"Passing Corrective Action Status Change Information"

"Passing Job Execution Status Information"

Step 2: Create the PL/SQL procedure on the Management Repository.

Create the PL/SQL procedure on the repository database using one of the following procedure specifications:

PROCEDURE event_proc(event_msg IN gc$notif_event_msg)

PROCEDURE incident_proc(incident_msg IN gc$notif_incident_msg)

PROCEDURE problem_proc(problem_msg IN gc$notif_problem_msg)

The PL/SQL procedure must be created on the repository database using the database account of the repository owner (such as SYSMAN)

If an error is encountered during the running of the procedure, the Notification System can be instructed to retry the sending of the notification to the procedure by raising a user-defined exception that uses the error code -20000. The procedure initially retried after one minute, then two minutes, then three minutes and so on, until the notification is a day old, at which point it will be purged.

Step 3: Register your PL/SQL procedure as a new notification method.

Log in as a Super Administrator. From the Setup menu, choose Notifications and then Notification Methods to access the Notification Methods page. From this page, you can define a new notification based on 'PL/SQL Procedure'. See Sending Notifications Using PL/SQL Procedures.

Make sure to use a fully qualified name that includes the schema owner, package name and procedure name. The procedure will be executed by the repository owner and so the repository owner must have execute permission on the procedure.

Create a notification method based on your PL/SQL procedure. The following information is required when defining the method:

  • Name

  • Description

  • PL/SQL Procedure

You must enter a fully qualified procedure name (for example, OWNER.PKGNAME.PROCNAME) and ensure that the owner of the Management Repository has execute privilege on the procedure.

An example of the required information is shown in Example 6-9.

Figure 6-1 illustrates how to add a PL/SQL-based notification method from the Enterprise Manager UI.

Figure 6-1 Adding a PL/SQL Procedure


adding a pl/sql procedure

Step 4: Assign the notification method to an incident rule.

You can edit an existing rule (or create a new incident rule). From the Setup menu, select Incidents and then select Incident Rules. The Incident Rules page displays. From here, you can add an action to a rule specifying the new PL/SQL procedure found under Advanced Notification Method.

There can be more than one PL/SQL-based method configured for your Enterprise Manager environment.

See "Passing Information to a PL/SQL Procedure" for more information about how incident, event, and problem information is passed to the PLSQL procedure.