1 PACKAGE BODY fnd_oam_collection AS
2 /* $Header: AFOAMCLB.pls 120.7 2007/01/03 20:02:35 ravmohan noship $ */
3 -- Some Constants to define the various agents we will be pinging
4 AOLJ_DB_POOL constant number := 1;
5 PLSQL_AGNT constant number := 2;
6 SERVLET_AGNT constant number := 3;
7 JSP constant number := 4;
8 TCF constant number := 5;
9 JTF constant number := 6;
10 DISCOVERER constant number := 7;
11 PHP constant number := 8;
12 REPORT constant number := 9;
13 FORMS constant number := 10;
14 FWK constant number := 11;
15
16 AGENT_MIN constant number := PLSQL_AGNT;
17 AGENT_MAX constant number := PHP;
18
19 -- Some constants to define status values
20 STATUS_NORMAL constant number := 0;
21 STATUS_WARNING constant number := 1;
22 STATUS_ERROR constant number := 2;
23 STATUS_INACTIVE constant number := 3;
24 STATUS_UNKNOWN constant number := 4;
25
26 -- Some constants to define operator codes
27 OPER_E constant varchar2(1) := 'E';
28 OPER_G constant varchar2(1) := 'G';
29 OPER_L constant varchar2(1) := 'L';
30 OPER_I constant varchar2(1) := 'I';
31
32 -- internal constant for group id for Applications Systems Status Group
33 APP_SYS_STATUS constant number := 7;
34
35 -- internal type used for computation of rollup status
36 TYPE st_table IS TABLE OF number index by binary_integer;
37
38 -- Module name for this package
39 MODULE constant varchar2(200) := 'fnd.plsql.FND_OAM_COLLECTION';
40
41 PROCEDURE debug (p_txt varchar2)
42 IS
43
44 BEGIN
45 --dbms_output.put_line(p_txt);
46 null;
47 END debug;
48
49 --
50 -- Checks if currently we are in the context of a concurrent
51 -- request (i.e. FNDOAMCOL execution) or not.
52 --
53 FUNCTION is_request RETURN boolean
54 IS
55 v_conc_req_id fnd_concurrent_requests.request_id%TYPE;
56 v_retu boolean := false;
57 BEGIN
58 -- check if its concurrent request
59 select fnd_global.conc_request_id into v_conc_req_id from dual;
60 if v_conc_req_id > 0 then
61 v_retu := true;
62 end if;
63 return v_retu;
64 END is_request;
65
66 --
67 -- Gets the current user id
68 --
69 FUNCTION get_user_id RETURN number
70 IS
71 v_userid number;
72 v_conc_req_id number;
73 BEGIN
74 -- check if its concurrent request
75 select fnd_global.conc_request_id into v_conc_req_id from dual;
76 if v_conc_req_id > 0 then
77 select fcr.requested_by into v_userid
78 from fnd_concurrent_requests fcr
79 where fcr.request_id = v_conc_req_id;
80 else
81 select fnd_global.user_id into v_userid from dual;
82 if (v_userid < 0 or v_userid is null) then
83 v_userid := 0; -- default
84 end if;
85 end if;
86
87 return v_userid;
88 EXCEPTION
89 when others then
90 v_userid := 0;
91 return v_userid;
92 END get_user_id;
93
94 --
95 -- Checks to see if the value for the given metric needs to be
96 -- collected
97 --
98 -- Note:
99 -- For use for Dashbaord Collection Program only.
100 --
101 FUNCTION is_collection_enabled (p_metric_short_name varchar2) RETURN boolean
102 IS
103 v_is_supported fnd_oam_metval.is_supported%TYPE;
104 v_collection_enabled_flag fnd_oam_metval.collection_enabled_flag%TYPE;
105 v_retu boolean := TRUE;
106 BEGIN
107 select nvl(is_supported,'Y'), nvl(collection_enabled_flag,'Y')
108 into v_is_supported, v_collection_enabled_flag
109 from fnd_oam_metval
110 where metric_short_name = p_metric_short_name
111 and rownum = 1;
112
113 if (v_is_supported = 'N' or v_collection_enabled_flag = 'N') then
114 v_retu := FALSE;
115 end if;
116
117 --if (v_retu) then
118 -- dbms_output.put_line('COLLECTION_ENABLED: ' || p_metric_short_name || ': '|| 'TRUE');
119 --else
120 -- dbms_output.put_line('COLLECTION_ENABLED: ' || p_metric_short_name || ': '|| 'FALSE');
121 --end if;
122
123 return v_retu;
124 EXCEPTION
125 when no_data_found then
126 --dbms_output.put_line('COLLECTION_ENABLED: ' || p_metric_short_name || ': ' || 'FALSE');
127 return FALSE;
128 END is_collection_enabled;
129
130 --
131 -- Checks to see if the value for the given service instance needs to
132 -- be collected
133 --
134 FUNCTION is_collection_enabled (
135 p_application_id number,
136 p_concurrent_queue_name varchar2) RETURN boolean
137 IS
138 v_collection_enabled_flag fnd_oam_svci_info.collection_enabled_flag%TYPE;
139 v_retu boolean := TRUE;
140 BEGIN
141 select nvl(collection_enabled_flag, 'Y')
142 into v_collection_enabled_flag
143 from fnd_oam_svci_info
144 where application_id = p_application_id
145 and concurrent_queue_name = p_concurrent_queue_name;
146 if (v_collection_enabled_flag = 'N') then
147 v_retu := FALSE;
148 end if;
149
150 --if (v_retu) then
151 -- dbms_output.put_line('COLLECTION_ENABLED: ' || p_concurrent_queue_name || ': '|| 'TRUE');
152 --else
153 -- dbms_output.put_line('COLLECTION_ENABLED: ' || p_concurrent_queue_name || ': '|| 'FALSE');
154 --end if;
155
156 return v_retu;
157 EXCEPTION
158 when no_data_found then
159 --dbms_output.put_line('COLLECTION_ENABLED: ' || p_concurrent_queue_name || ': ' || 'TRUE');
160 return TRUE;
161 END is_collection_enabled;
162
163 --
164 -- Returns the operator symbol based on the threshold operator code
165 --
166 FUNCTION get_operator_symbol(p_threshold_operator varchar2) RETURN varchar2
167 IS
168 v_retu varchar2(10) := '=';
169 BEGIN
170 if p_threshold_operator = OPER_E then
171 v_retu := '=';
172 elsif p_threshold_operator = OPER_G then
173 v_retu := '>';
174 elsif p_threshold_operator = OPER_L then
175 v_retu := '<';
176 elsif p_threshold_operator = OPER_I then
177 v_retu := 'IN';
178 end if;
179
180 return v_retu;
181 END get_operator_symbol;
182
183 --
184 -- Checks the metric value against specified threshold to see if
185 -- an alert needs to be raised for the given metric
186 --
187 FUNCTION shall_raise_alert(p_metric_short_name varchar2) RETURN boolean
188 IS
189 v_retu boolean := FALSE;
190 l_metric_type fnd_oam_metval.metric_type%TYPE;
191 l_threshold_operator fnd_oam_metval.threshold_operator%TYPE;
192 l_threshold_value fnd_oam_metval.threshold_value%TYPE;
193 l_operator_symbol varchar2(10);
194 BEGIN
195 --if (is_alert_enabled(p_metric_short_name)) then
196 select metric_type, threshold_operator, threshold_value
197 into l_metric_type, l_threshold_operator, l_threshold_value
198 from fnd_oam_metval
199 where metric_short_name = p_metric_short_name
200 and rownum = 1;
201
202 if (l_threshold_operator is not null and
203 l_threshold_value is not null) then
204 l_operator_symbol := get_operator_symbol(l_threshold_operator);
205
206 declare
207 v_raise_alert number := 0;
208 v_check_sql varchar2(1024);
209 v_value_column varchar2(50);
210 begin
211 --determine the column our threshold value should measure against
212 if (l_metric_type = 'I') then -- Numeric metric
213 v_value_column := 'metric_value';
214 elsif (l_metric_type = 'S') then -- Status metric
215 v_value_column := 'status_code';
216 end if;
217
218 -- construct threshold check sql and execute
219 -- bug #4670957 - ilawler
220 -- converted literals to use binds where possible
221 begin
222 if (l_threshold_operator = OPER_I) then
223 --can't bind a list, use string concat
224 v_check_sql := 'select 1 from fnd_oam_metval where metric_short_name = :1 and '||
225 v_value_column||' '||l_operator_symbol ||' '||'('||l_threshold_value||')';
226 execute immediate v_check_sql
227 into v_raise_alert
228 using p_metric_short_name;
229 else
230 --use bind for =,<,> since they're the majority case.
231 v_check_sql := 'select 1 from fnd_oam_metval where metric_short_name = :1 and '||
232 v_value_column||' '||l_operator_symbol ||' '||':2';
233 execute immediate v_check_sql
234 into v_raise_alert
235 using p_metric_short_name, l_threshold_value;
236 end if;
237 exception
238 when no_data_found then
239 v_raise_alert := 0;
240 end;
241
242 -- convert the number into a boolean
243 if v_raise_alert = 1 then
244 v_retu := TRUE;
245 end if;
246 end;
247 end if;
248 --end if;
249
250 --if (v_retu) then
251 --dbms_output.put_line('RAISE_ALERT: ' || p_metric_short_name || ': '||'TYPE: '||l_metric_type||' OP: '||l_operator_symbol||' '||'THRSHVAL: '||l_threshold_value|| ' :TRUE');
252 --else
253 --dbms_output.put_line('RAISE_ALERT: ' || p_metric_short_name || ': '||'TYPE: '||l_metric_type||' OP:'||l_operator_symbol||' '||'THRSHVAL: '||l_threshold_value|| ' :FALSE');
254 --end if;
255
256 return v_retu;
257 END shall_raise_alert;
258
259 --
260 -- Checks the status code for the given service instance against threshold
261 -- value to see if an alert needs to be raised.
262 --
263 FUNCTION shall_raise_alert(p_application_id number,
264 p_concurrent_queue_name varchar2)
265 RETURN boolean
266 IS
267 v_retu boolean := FALSE;
268 l_threshold_value fnd_oam_svci_info.threshold_value%TYPE;
269 BEGIN
270 --if (is_alert_enabled(p_application_id, p_concurrent_queue_name)) then
271 select threshold_value
272 into l_threshold_value
273 from fnd_oam_svci_info
274 where application_id = p_application_id
275 and concurrent_queue_name = p_concurrent_queue_name;
276
277 if (l_threshold_value is not null) then
278 declare
279 v_raise_alert number := 0;
280 v_check_sql varchar2(1024);
281 begin
282 -- construct threshold check sql and execute
283 -- bug #4670957 - ilawler
284 -- converted literals to use binds where possible
285 v_check_sql := 'select 1 from fnd_oam_app_sys_status where ' ||
286 'application_id = :1 and concurrent_queue_name = :2 and ' ||
287 'status_code IN ' || '('||l_threshold_value||')';
288 --dbms_output.put_line('CHK_SQL: ' || v_check_sql);
289
290 begin
291 execute immediate v_check_sql
292 into v_raise_alert
293 using p_application_id, p_concurrent_queue_name;
294 exception
295 when no_data_found then
296 v_raise_alert := 0;
297 end;
298
299 if v_raise_alert = 1 then
300 v_retu := TRUE;
301 end if;
302 end;
303 end if;
304 --end if;
305
306 --if (v_retu) then
307 --dbms_output.put_line('RAISE_ALERT: ' ||p_concurrent_queue_name|| ': '||'THRSHVAL: '||l_threshold_value|| ' :TRUE');
308 --else
309 --dbms_output.put_line('RAISE_ALERT: ' ||p_concurrent_queue_name|| ': '||'THRSHVAL: '||l_threshold_value|| ' :FALSE');
310 --end if;
311
312 return v_retu;
313 END shall_raise_alert;
314
315 --
316 --
317 -- Name
318 -- construct_url
319 --
320 -- Purpose
321 -- Constructs a url to ping for the given agent. This is an internal
322 -- procedure only.
323 --
324 -- Input Arguments
325 -- 1) agent: type of agent for which the url is required. Valid values
326 -- are AOLJ_DB_POOL, WEB_AGNT, SERVLET_AGNT, JSP, TCF, JTF, DISCOVERER,
327 -- PHP, REPORT, FWK.
328 --
329 -- Output Arguments
330 --
331 -- Returns
332 -- The URL for the given agent. For example for PHP (personal home page)
333 -- 'http://<host>:<port>/OA_HTML/US/ICXINDEX.htm' is returned. If the URL
334 -- cannot be constructed, null is returned.
335 --
336 -- Notes:
337 --
338 --
339 FUNCTION construct_url(agent in number) RETURN varchar2
340 IS
341 v_url varchar2(1000) := null;
342 v_err varchar2(2000);
343 valid_agent boolean := true;
344 BEGIN
345 if agent = AOLJ_DB_POOL then
346 v_url := fnd_web_config.jsp_agent;
347 if v_url is not null then
348 v_url := v_url || 'jsp/fnd/AoljDbcPoolStatus.jsp';
349 end if;
350 elsif agent = PLSQL_AGNT then
351 v_url := fnd_web_config.plsql_agent;
352 if v_url is not null then
353 v_url := v_url || 'fnd_web.ping';
354 end if;
355 elsif agent = SERVLET_AGNT or agent = TCF then
356 -- we'll first try to retrieve value of 'APPS_SERVLET_AGENT' profile
357 -- option. If this value is not available then we will use the base
358 -- web server url to construct the url to ping for servlet agent.
359 begin
360 select pov.profile_option_value
361 into v_url
362 from fnd_profile_options po,
363 fnd_profile_option_values pov
364 where po.profile_option_name = 'APPS_SERVLET_AGENT'
365 and pov.application_id = po.application_id
366 and pov.profile_option_id = po.profile_option_id
367 and pov.level_id = 10001;
368 exception
369 when others then
370 null;
371 end;
372 if v_url is null then
373 v_url := fnd_web_config.web_server;
374 if v_url is not null then
375 v_url := v_url || 'oa_servlets';
376 end if;
377 end if;
378 if v_url is not null then
379 v_url := fnd_web_config.trail_slash(v_url);
380 if agent = SERVLET_AGNT then
381 v_url := v_url || 'oracle.apps.fnd.test.HelloWorldServlet';
382 elsif agent = TCF then
383 v_url := v_url || 'oracle.apps.fnd.tcf.SocketServer';
384 end if;
385 end if;
386 elsif agent = JSP then
387 v_url := fnd_web_config.jsp_agent;
388 if v_url is not null then
389 v_url := v_url || 'jsp/fnd/fndping.jsp?dbc=' || fnd_web_config.database_id;
390 end if;
391 elsif agent = JTF then
392 v_url := fnd_web_config.jsp_agent;
393 if v_url is not null then
394 v_url := v_url || 'jtflogin.jsp';
395 end if;
396 elsif agent = DISCOVERER then
397 --v_url := fnd_web_config.web_server;
398 --if v_url is not null then
399 -- v_url := v_url || 'servlets/discoservlet';
400 --end if;
401 v_url := fnd_profile.value('ICX_DISCOVERER_VIEWER_LAUNCHER');
402 elsif agent = PHP then
403 v_url := fnd_web_config.jsp_agent;
404 if v_url is not null then
405 v_url := v_url || 'US/ICXINDEX.htm';
406 end if;
407 elsif agent = REPORT then
408 -- retrieve ICX_REPORT_LANCHER and ICX_REPORT_SERVER profile option
409 -- values to construct the reports server url.
410 declare
411 v_launcher varchar(1000);
412 v_server varchar(100);
413 begin
414 select pov.profile_option_value
415 into v_launcher
416 from fnd_profile_options po,
417 fnd_profile_option_values pov
418 where po.profile_option_name = 'ICX_REPORT_LAUNCHER'
419 and pov.application_id = po.application_id
420 and pov.profile_option_id = po.profile_option_id
421 and pov.level_id = 10001;
422
423 select pov.profile_option_value
424 into v_server
425 from fnd_profile_options po,
426 fnd_profile_option_values pov
427 where po.profile_option_name = 'ICX_REPORT_SERVER'
428 and pov.application_id = po.application_id
429 and pov.profile_option_id = po.profile_option_id
430 and pov.level_id = 10001;
431
432 if v_launcher is not null and v_server is not null then
433 v_url := fnd_web_config.trail_slash(v_launcher);
434 v_url := v_url || 'showenv?server=' || v_server;
435 end if;
436 exception
437 when others then
438 null;
439 end;
440 elsif agent = FWK then
441 v_url := fnd_web_config.web_server;
442 elsif agent = FORMS then
443 -- retrieve ICX_FORMS_LAUNCHER profile option
444 -- values to construct the reports server url.
445 declare
446 v_launcher varchar(1000);
447 begin
448 select pov.profile_option_value
449 into v_launcher
450 from fnd_profile_options po,
451 fnd_profile_option_values pov
452 where po.profile_option_name = 'ICX_FORMS_LAUNCHER'
453 and pov.application_id = po.application_id
454 and pov.profile_option_id = po.profile_option_id
455 and pov.level_id = 10001;
456
457 if v_launcher is not null then
458 v_url := v_launcher;
459 end if;
460 exception
461 when others then
462 null;
463 end;
464 else
465 valid_agent := false;
466 end if;
467
468 if (v_url is null) and valid_agent then
469 fnd_file.put_line(fnd_file.log, fnd_message.get);
470 end if;
471 return v_url;
472 END construct_url;
473
474
475 --
476 -- Name
477 -- get_agent_status
478 --
479 -- Purpose
480 -- Returns the status for a given agent. This is for internal purpose only.
481 --
482 -- Input Arguments
483 -- 1) agent: type of agent for which the url is required. Valid values
484 -- are AOLJ_DB_POOL, WEB_AGNT, SERVLET_AGNT, JSP, TCF, JTF, DISCOVERER,
485 -- PHP, REPORT, FWK.
486 --
487 -- Output Arguments
488 --
489 -- Returns
490 -- The status for the given agent. 0 - normal, 1 - warning, 2 - error,
491 -- 3 - unknown
492 --
493 -- Notes:
494 --
495 --
496 FUNCTION get_agent_status (agent in number) RETURN number
497 IS
498 v_status number := STATUS_UNKNOWN;
499 v_url varchar2(2000) := null;
500 v_response varchar2(4000) := null;
501 BEGIN
502 -- compose a pingable url
503 v_url := construct_url(agent);
504 --dbms_output.put_line('URL: ' || v_url);
505
506 if v_url is null then
507 return STATUS_WARNING; -- status warning if unable to construct url,
508 -- probably some profile option is not set
509 end if;
510
511 -- Check if SSL, if so make it unavailable for now (bug 2905278)
512 if (instr(v_url, 'https:', 1, 1) = 1) then
513 return STATUS_UNKNOWN;
514 end if;
515 -- End (bug 2905278)
516
517
518 -- now make a network call
519 v_response := utl_http.request(v_url);
520
521 -- now parse the response to determine status based on agent.
522 if agent = PLSQL_AGNT then
523 declare
524 v_index number := -1;
525 begin
526 v_index := instr(v_response, 'FND_WEB.PING', 1, 2);
527 if v_index <= 0 then
528 v_status := STATUS_ERROR;
529 else
530 v_status := STATUS_NORMAL;
531 end if;
532 end;
533 elsif agent = SERVLET_AGNT then
534 declare
535 v_index number := -1;
536 begin
537 v_index := instr(v_response, 'HelloWorldServlet', 1, 1);
538 if v_index <= 0 then
539 v_status := STATUS_ERROR;
540 else
541 v_status := STATUS_NORMAL;
542 end if;
543 end;
544 elsif agent = JSP then
545 declare
546 v_index number := -1;
547 begin
548 v_index := instr(v_response, 'AOL_VERSION', 1, 1);
549 if v_index <= 0 then
550 v_status := STATUS_ERROR;
551 else
552 v_status := STATUS_NORMAL;
553 end if;
554 end;
555 elsif agent = REPORT then
556 declare
557 v_index number := -1;
558 begin
559 v_index := instr(v_response, 'SERVER_NAME', 1, 1);
560 if v_index <= 0 then
561 v_status := STATUS_ERROR;
562 else
563 v_status := STATUS_NORMAL;
564 end if;
565 end;
566 elsif agent = JTF or agent = DISCOVERER
567 or agent = PHP or agent = TCF or agent = FORMS then
568 declare
569 v_index number := -1;
570 begin
571 v_index := instr(v_response, 'Bad Request', 1, 1);
572 if v_index <= 0 then
573 v_index := instr(v_response, '404 Not Found', 1, 1);
574 end if;
575 if v_index <= 0 then
576 v_index := instr(v_response, '500 Internal Server Error', 1, 1);
577 end if;
578 if v_index <= 0 then
579 v_status := STATUS_NORMAL;
580 else
581 v_status := STATUS_ERROR;
582 end if;
583 end;
584 end if;
585
586 return v_status;
587 EXCEPTION
588 when utl_http.init_failed then
589 --dbms_output.put_line('INIT_FAILED');
590 return STATUS_UNKNOWN;
591 when utl_http.request_failed then
592 --dbms_output.put_line('REQUEST_FAILED');
593 return STATUS_ERROR;
594 when others then
595 return STATUS_UNKNOWN;
596 END get_agent_status;
597
598 --
599 -- Name
600 -- insert_app_sys_status_internal
601 -- Purpose
602 -- This procedure is for internal use of this package only!
603 -- This procedure will insert a row into fnd_oam_app_sys_status
604 --
605 -- Input Arguments
606 -- p_metric_short_name varchar2
607 -- p_application_id number
608 -- p_concurrent_queue_short_name varchar2
609 -- p_name varchar2
610 -- p_type varchar2
611 -- p_status_code number
612 -- p_node_name varchar2
613 --
614 -- Output Arguments
615 --
616 -- Input/Output Arguments
617 --
618 -- Notes:
619 -- This is an internal convenience method only for this package and should
620 -- not be exposed.
621 --
622 PROCEDURE insert_app_sys_status_internal (
623 p_metric_short_name in varchar2,
624 p_application_id number,
625 p_concurrent_queue_short_name varchar2,
626 p_name varchar2,
627 p_type varchar2,
628 p_status_code in number,
629 p_node_name in varchar2)
630 IS
631 v_userid number;
632 BEGIN
633 v_userid := get_user_id;
634
635 insert into fnd_oam_app_sys_status (metric_short_name, application_id,
636 concurrent_queue_name, name, type, status_code, node_name, last_updated_by,
637 last_update_date, last_update_login)
638 values
639 (p_metric_short_name,
640 p_application_id,
641 p_concurrent_queue_short_name,
642 p_name,
643 p_type,
644 p_status_code,
645 p_node_name,
646 v_userid, sysdate, 0);
647 END insert_app_sys_status_internal;
648
649 --
650 -- Name
651 -- update_metric_internal
652 -- Purpose
653 -- This procedure is for internal use of this package only!
654 -- This procedure will update a row in fnd_oam_metval for the given
655 -- metric name.
656 --
657 -- Input Arguments
658 -- p_metric_name varchar2
659 -- p_value varchar2
660 -- p_status_code number : if < 0 then status_code is not updated.
661 --
662 -- Output Arguments
663 --
664 -- Input/Output Arguments
665 --
666 -- Notes:
667 -- This is an internal convenience method only for this package and should
668 -- not be exposed.
669 --
670 PROCEDURE update_metric_internal (
671 p_metric_name in varchar2,
672 p_value in varchar2,
673 p_status_code in number)
674 IS
675 v_userid number;
676 BEGIN
677 v_userid := get_user_id;
678 if p_status_code >= 0 then
679 update fnd_oam_metval
680 set metric_value = p_value,
681 status_code = p_status_code,
682 last_collected_date = sysdate,
683 last_updated_by = v_userid,
684 last_update_date = sysdate,
685 last_update_login = 0
686 where metric_short_name = p_metric_name;
687 else
688 update fnd_oam_metval
689 set metric_value = p_value,
690 last_collected_date = sysdate,
691 last_updated_by = v_userid,
692 last_update_date = sysdate,
693 last_update_login = 0
694 where metric_short_name = p_metric_name;
695 end if;
696 END update_metric_internal;
697
698 --
699 -- Name
700 -- refresh_status_for_service
701 -- Purpose
702 -- This procedure is for internal use of this package only!
703 -- For a given server type, and node name this procedure will insert
704 -- the status information for all the service instances for that
705 -- particular server type running on the given node into
706 -- fnd_oam_app_sys_status
707 --
708 -- Input Arguments
709 -- p_server_type varchar2 - 'C' - Concurrent Processing,
710 -- - 'F' - Forms
711 -- - 'W' - Web
712 -- p_node_name varchar2
713 --
714 --
715 -- Output Arguments
716 --
717 -- Input/Output Arguments
718 --
719 --
720 -- Notes:
721 -- This is an internal convenience proc only for this package and should
722 -- not be exposed.
723 --
724 PROCEDURE refresh_status_for_service(
725 p_server_type in varchar2,
726 p_node_name in varchar2)
727 IS
728 cursor svc_c(v_server_type varchar2, v_node_name varchar2) is
729 select
730 fcq.application_id application_id,
731 fcq.concurrent_queue_id concurrent_queue_id,
732 fcq.concurrent_queue_name concurrent_queue_name
733 from fnd_cp_services fcs, fnd_concurrent_queues fcq
734 where
735 fcs.service_id = to_number(fcq.manager_type)
736 and fcs.server_type in (v_server_type, 'E')
737 and upper(fcq.target_node) = upper(v_node_name)
738 and upper(fcs.enabled) = 'Y'
739 and upper(fcq.enabled_flag) = 'Y'
740 order by fcs.oam_display_order asc;
741
742 v_count number := 0;
743 BEGIN
744 for svc_inst in svc_c(p_server_type, p_node_name) loop
745 v_count := v_count + 1;
746 declare
747 v_target number := -1;
748 v_actual number := -1;
749 v_status_code number;
750 v_desc varchar2(1000);
751 v_err_code number;
752 v_err_msg varchar2(1000);
753 begin
754 -- check if collection is enabled before calling API to get status
755 if (is_collection_enabled(
756 svc_inst.application_id, svc_inst.concurrent_queue_name)) then
757 fnd_oam.get_svc_inst_status(svc_inst.application_id,
758 svc_inst.concurrent_queue_id, v_target, v_actual, v_status_code,
759 v_desc, v_err_code, v_err_msg);
760
761 if v_err_code > 0 then -- error
762 -- Log some information for now.
763 fnd_file.put_line(fnd_file.log, 'Error in refresh_status_for_service:');
764 fnd_file.put_line(fnd_file.log, 'SERVER_TYPE: ' || p_server_type);
765 fnd_file.put_line(fnd_file.log, 'NODE NAME: ' || p_node_name);
766 fnd_file.put_line(fnd_file.log, 'APP ID: ' ||
767 svc_inst.application_id);
768 fnd_file.put_line(fnd_file.log, 'CONCURRENT QUEUE ID: ' ||
769 svc_inst.concurrent_queue_id);
770 fnd_file.put_line(fnd_file.log, 'CONCURRENT QUEUE NAME: ' ||
771 svc_inst.concurrent_queue_name);
772 fnd_file.put_line(fnd_file.log, 'v_target: ' || v_target);
773 fnd_file.put_line(fnd_file.log, 'v_actual: ' || v_actual);
774 fnd_file.put_line(fnd_file.log, 'v_status_code: ' || v_status_code);
775 fnd_file.put_line(fnd_file.log, 'v_desc: ' || v_desc);
776 fnd_file.put_line(fnd_file.log, 'v_err_code: ' || v_err_code);
777 fnd_file.put_line(fnd_file.log, 'v_err_msg: ' || v_err_msg);
778 v_status_code := STATUS_UNKNOWN;
779 end if;
780 --dbms_output.put_line('STATUS CODE: ' || v_status_code);
781
782 else
783 -- upload status null since collection not enabled.
784 v_status_code := -1;
785 end if;
786
787 -- now insert into fnd_oam_mets:
788 insert_app_sys_status_internal(
789 p_server_type || '_' || to_char(v_count) ||
790 '_' || p_node_name,
791 svc_inst.application_id, svc_inst.concurrent_queue_name, null,
792 p_server_type,v_status_code, p_node_name);
793
794 end;
795 end loop;
796 EXCEPTION
797 when others then
798 raise;
799 END refresh_status_for_service;
800
801 --
802 -- Internal API to register status in a table in order to compute
803 -- rollup.
804 --
805 PROCEDURE register_status_in_table(
806 p_satus_code number,
807 p_info_table IN OUT NOCOPY st_table)
808 IS
809
810 BEGIN
811 if p_satus_code = STATUS_ERROR then
812 p_info_table(1) := 1;
813 elsif p_satus_code = STATUS_WARNING then
814 p_info_table(2) := 1;
815 elsif p_satus_code = STATUS_UNKNOWN then
816 p_info_table(3) := 1;
817 elsif p_satus_code = STATUS_NORMAL then
818 p_info_table(4) := 1;
819 elsif p_satus_code = STATUS_INACTIVE then
820 p_info_table(5) := 1;
821 end if;
822 END register_status_in_table;
823
824 --
825 -- Name
826 -- compute_rollup_status
827 -- Purpose
828 -- This function is for internal use of this package only!
829 -- Computes the the rollup status for a set of metrics given some
830 -- metadata information about the individual component metrics
831 -- that comprise the rollup.
832 --
833 -- Input Arguments
834 -- p_comp_info - st_table Table of numbers of with five entries as follows:
835 -- at index 1: if at least one component has STATUS_ERROR then 1
836 -- otherwise 0.
837 -- at index 2: if at least one component has STATUS_WARNING then 1
838 -- otherwise 0.
839 -- at index 3: if at least one component has STATUS_UNKNOWN then 1
840 -- otherwise 0.
841 -- at index 4: if at least one component has STATUS_NORMAL then 1
842 -- otherwise 0.
843 -- at index 5: if at least one component has STATUS_INACTIVE then
844 -- 1 otherwise 0.
845 --
846 -- Output Arguments
847 --
848 -- Input/Output Arguments
849 --
850 -- Returns
851 -- one of the following status codes:
852 -- STATUS_ERROR, STATUS_WARNING, STATUS_UNKNOWN, STATUS_NORMAL,
853 -- STATUS_INACTIVE
854 --
855 -- Notes:
856 -- This is an internal convenience method only for this package and should
857 -- not be exposed.
858 --
859 FUNCTION compute_rollup_status(
860 p_comp_info st_table) RETURN number
861 IS
862 v_status number := STATUS_NORMAL;
863 BEGIN
864 if p_comp_info.exists(1) and p_comp_info(1) = 1 then
865 v_status := STATUS_ERROR;
866 elsif p_comp_info.exists(2) and p_comp_info(2) = 1 then
867 v_status := STATUS_WARNING;
868 elsif p_comp_info.exists(3) and p_comp_info(3) = 1 then
869 v_status := STATUS_WARNING;
870 elsif p_comp_info.exists(4) and p_comp_info(4) = 1 then
871 v_status := STATUS_NORMAL;
872 elsif p_comp_info.exists(5) and p_comp_info(5) = 1 then
873 v_status := STATUS_INACTIVE;
874 end if;
875
876 return v_status;
877 END compute_rollup_status;
878
879 --
880 -- Name
881 -- compute_overall_server_status
882 -- Purpose
883 -- This procedure is for internal use of this package only!
884 -- Given the server name this procedure will compute and insert the status
885 -- for that server into fnd_oam_mets, based on the status of the server
886 -- on individual nodes.
887 --
888 -- Input Arguments
889 -- p_server varchar2 -- metric name for the server e.g. 'CP_SERVER'
890 -- p_server_type varchar2 -- server type eg. 'C','A','W','D' or 'F'
891 --
892 -- Output Arguments
893 --
894 -- Input/Output Arguments
895 --
896 --
897 -- Notes:
898 -- This is an internal convenience method only for this package and should
899 -- not be exposed.
900 --
901 PROCEDURE compute_overall_server_status(
902 p_server in varchar2,
903 p_server_type in varchar2)
904 IS
905
906 BEGIN
907 declare
908 cursor server_st is
909 select status_code from fnd_oam_app_sys_status
910 where metric_short_name like p_server || '%';
911 overall_st number := STATUS_NORMAL;
912 found_up boolean := false;
913 found_warning boolean := false;
914 server_count number := 0;
915 info_table st_table;
916 begin
917 --for server in server_st loop
918 -- if server.status_code = STATUS_NORMAL then
919 -- found_up := true;
920 -- elsif server.status_code = STATUS_WARNING then
921 -- found_warning := true;
922 -- overall_st := STATUS_WARNING;
923 -- else
924 -- overall_st := STATUS_WARNING;
925 -- end if;
926 -- server_count := server_count + 1;
927 --end loop;
928 --if server_count > 0 and found_up = false and found_warning = false then
929 -- overall_st := STATUS_ERROR;
930 --end if;
931
932 for server in server_st loop
933 register_status_in_table(server.status_code, info_table);
934 --if server.status_code = STATUS_ERROR then
935 -- info_table(1) := 1;
936 --elsif server.status_code = STATUS_WARNING then
937 -- info_table(2) := 1;
938 --elsif server.status_code = STATUS_UNKNOWN then
939 -- info_table(3) := 1;
940 --elsif server.status_code = STATUS_NORMAL then
941 -- info_table(4) := 1;
942 --elsif server.status_code = STATUS_INACTIVE then
943 -- info_table(5) := 1;
944 --end if;
945 end loop;
946
947 overall_st := compute_rollup_status(info_table);
948
949 -- now insert into fnd_oam_mets
950 insert_app_sys_status_internal(
951 p_server || '_OVERALL',
952 null, null, null, p_server_type, overall_st, null);
953
954 end;
955 END compute_overall_server_status;
956
957 --
958 -- Name
959 -- refresh_status_for_tier
960 -- Purpose
961 -- This procedure is for internal use of this package only!
962 -- For a given server type, and node name this procedure will insert
963 -- the status information for all the service instances for that
964 -- particular server type running on the given node into
965 -- fnd_oam_app_sys_status
966 --
967 -- Input Arguments
968 -- p_server_type varchar2 - 'C' - Concurrent Processing,
969 -- - 'F' - Forms
970 -- - 'W' - Web
971 -- - 'A' - Admin
972 -- p_node_name varchar2
973 --
974 --
975 -- Output Arguments
976 --
977 -- Input/Output Arguments
978 --
979 --
980 -- Notes:
981 -- This is an internal convenience proc only for this package and should
982 -- not be exposed.
983 --
984 PROCEDURE refresh_status_for_tier(
985 p_server_type in varchar2,
986 p_node_name in varchar2)
987 IS
988 v_server_type_prep varchar2(30);
989 BEGIN
990 -- determine the server type
991 if p_server_type = 'C' then
992 v_server_type_prep := 'CP_SERVER_';
993 elsif p_server_type = 'W' then
994 v_server_type_prep := 'WEB_SERVER_';
995 elsif p_server_type = 'F' then
996 v_server_type_prep := 'FORMS_SERVER_';
997 elsif p_server_type = 'A' then
998 v_server_type_prep := 'ADMIN_SERVER_';
999 else
1000 v_server_type_prep := 'UNKNOWN_SERVER_';
1001 end if;
1002
1003 refresh_status_for_service(p_server_type, p_node_name);
1004
1005 -- Now Compute Overall CP Server status on this node
1006 declare
1007 v_tier_overall_status number := STATUS_NORMAL; -- start off by up
1008 v_found_up_instance boolean := false;
1009 v_found_inactive_instance boolean := false;
1010 v_count number := 0;
1011
1012 cursor status_c is
1013 select status_code from fnd_oam_app_sys_status where
1014 upper(node_name) = upper(p_node_name) and (
1015 metric_short_name like p_server_type || '_%');
1016 info_table st_table;
1017 begin
1018 for st in status_c loop
1019 register_status_in_table(st.status_code, info_table);
1020 --if st.status_code = STATUS_ERROR then
1021 -- info_table(1) := 1;
1022 --elsif st.status_code = STATUS_WARNING then
1023 -- info_table(2) := 1;
1024 --elsif st.status_code = STATUS_UNKNOWN then
1025 -- info_table(3) := 1;
1026 --elsif st.status_code = STATUS_NORMAL then
1027 -- info_table(4) := 1;
1028 --elsif st.status_code = STATUS_INACTIVE then
1029 -- info_table(5) := 1;
1030 --end if;
1031 end loop;
1032
1033 -- also factor in the status of the current host while
1034 -- computing the status for this tier on this host.
1035 declare
1036 v_host_status number;
1037 begin
1038 select status_code into v_host_status
1039 from fnd_oam_app_sys_status
1040 where upper(node_name) = upper(p_node_name)
1041 and metric_short_name like 'HOST_%'
1042 and rownum = 1; -- we expect only one row per host
1043 register_status_in_table(v_host_status, info_table);
1044 exception
1045 when others then
1046 null;
1047 end;
1048
1049 -- compute the rollup for this tier on this node and update
1050 -- into the table.
1051 v_tier_overall_status := compute_rollup_status(info_table);
1052
1053 insert_app_sys_status_internal(
1054 v_server_type_prep || p_node_name,
1055 null, null, null, p_server_type, v_tier_overall_status, p_node_name);
1056 end;
1057 END refresh_status_for_tier;
1058
1059
1060 --
1061 -- Name
1062 -- refresh_app_sys_status
1063 --
1064 -- Purpose
1065 -- Derives the status of the following applications servers using URL
1066 -- pings of the corresponding processes that belong to the server. The status
1067 -- and host information for each of the processes as well as servers are
1068 -- updated in the FND_OAM_APP_SYS_STATUS table
1069 -- 1) Admin - Currently no processes are defined for this server
1070 -- 2) Web - Consists of Apache Web Listener, Apache Jserv
1071 -- 3) Forms - Consists of the forms launcher
1072 -- 4) CP - Consists of the Internal Concurrent Manager, Reports
1073 -- 5) Data - Consists of the database instances as defined in gv$instance.
1074 --
1075 -- Input Arguments
1076 --
1077 -- Output Arguments
1078 --
1079 -- Notes:
1080 --
1081 --
1082 PROCEDURE refresh_app_sys_status
1083 IS
1084 pragma AUTONOMOUS_TRANSACTION;
1085 cursor nodes_c is
1086 select upper(node_name) node_name, status, support_cp, support_forms,
1087 support_web, support_admin
1088 from FND_OAM_FNDNODES_VL
1089 where node_mode = 'O'
1090 and (nvl(support_cp, 'N') = 'Y' or
1091 nvl(support_forms, 'N') = 'Y' or
1092 nvl(support_web, 'N') = 'Y' or
1093 nvl(support_admin, 'N') = 'Y' or
1094 nvl(support_db, 'N') = 'Y');
1095 BEGIN
1096 -- delete existing app sys status information. We will change this later if we are
1097 -- going to move it to an archive table
1098 delete from fnd_oam_app_sys_status;
1099
1100 -- now update latest host information
1101 declare
1102 i number := 1;
1103 seq_counter number := 1;
1104 node_status number;
1105 begin
1106 for node in nodes_c loop
1107 select decode(nvl(node.status, 'U'),
1108 'Y',STATUS_NORMAL,
1109 'N',STATUS_ERROR,
1110 'U',STATUS_UNKNOWN, STATUS_UNKNOWN) into node_status
1111 from dual;
1112 insert_app_sys_status_internal(
1113 'HOST_'||to_char(i),
1114 null, null, null, null, node_status, node.node_name);
1115
1116 i := i + 1;
1117
1118
1119 -- now based on the various flags for the applications servers, update
1120 -- the status of individual processes as well as those of the servers
1121
1122 -- Concurrent Processing
1123 if node.support_cp = 'Y' then
1124 refresh_status_for_tier('C', node.node_name);
1125 end if; -- if node.support_cp = 'Y' then
1126
1127 -- For Forms
1128 if node.support_forms = 'Y' then
1129 refresh_status_for_tier('F', node.node_name);
1130 end if; -- if node.support_forms = 'Y' then
1131
1132 -- For ADMIN
1133 if node.support_admin = 'Y' then
1134 refresh_status_for_tier('A', node.node_name);
1135 end if; -- end if node.support_admin = 'Y' then
1136
1137 -- For WEB SERVER
1138 if node.support_web = 'Y' then
1139 refresh_status_for_tier('W', node.node_name);
1140 end if; -- if node.support_web = 'Y' then
1141
1142 end loop;
1143
1144 -- For DATA SERVER
1145 -- We will need to collect database statuses for all the
1146 -- individual instances list in gv$instance
1147 declare
1148 v_db_status number := STATUS_NORMAL;
1149 v_db_count number := 0;
1150 v_node_name varchar2(100);
1151 v_db_node_registered boolean := false;
1152 cursor dbst_c is
1153 select upper(host_name) host_name, instance_name, database_status
1154 from gv$instance;
1155
1156 -- added the where clause to this cursor as a fix for bug 3955412
1157 cursor nodex_c is
1158 --rjaiswal bug#4917109
1159 -- For virtual host we have the entry of main host in this column 'webhost'
1160 -- So this column can be used to compare the gv$instance host_name value
1161 -- instead of comparing it with node_name.Added webhost column
1162 select upper(node_name) node_name,upper(webhost) webhost from FND_OAM_FNDNODES_VL
1163 where node_mode = 'O'
1164 and (nvl(support_cp, 'N') = 'Y' or
1165 nvl(support_forms, 'N') = 'Y' or
1166 nvl(support_web, 'N') = 'Y' or
1167 nvl(support_admin, 'N') = 'Y' or
1168 nvl(support_db, 'N') = 'Y');
1169 --rjaiswal bug#4917109
1170 begin
1171 for db in dbst_c loop
1172 v_db_status := STATUS_NORMAL;
1173
1174 -- what are the possible values for database_status here that we
1175 -- need to check??
1176 if db.database_status <> 'ACTIVE' then
1177 v_db_status := STATUS_WARNING;
1178 end if;
1179
1180 -- fix for bug 2848014; if host_name has domain name as well
1181 -- only use the first part.
1182 v_node_name := db.host_name;
1183 for ndx in nodex_c loop
1184 declare
1185 v_gv_host varchar2(100);
1186 v_fn_node varchar2(100);
1187 --rjaiswal bug#4917109 starts
1188 --this variable is required to hold the value of web host:
1189 v_fn_webhost varchar2(100);
1190 --rjaiswal bug#4917109 ends
1191 begin
1192 select decode(instr(db.host_name, '.') - 1, -1,
1193 db.host_name,
1194 substr(db.host_name, 0,
1195 instr(db.host_name, '.') - 1))
1196 into v_gv_host from dual;
1197
1198 select decode(instr(ndx.node_name, '.') - 1, -1,
1199 ndx.node_name,
1200 substr(ndx.node_name, 0,
1201 instr(ndx.node_name, '.') - 1))
1202 into v_fn_node from dual;
1203 --rjaiswal bug#4917109 starts
1204 -- Storing the value of webhost inorder to compare it with v_gv_host
1205 select decode(instr(ndx.webhost, '.') - 1, -1,
1206 ndx.webhost,
1207 substr(ndx.webhost, 0,
1208 instr(ndx.webhost, '.') - 1))
1209 into v_fn_webhost from dual;
1210 -- ADDED "or v_gv_host = v_fn_webhost" in the "if" condition
1211 -- This column can be used to compare the gv$instance host_name value
1212 if ( v_gv_host = v_fn_node or v_gv_host = v_fn_webhost) then
1213 v_node_name := ndx.node_name;
1214 --rjaiswal bug#4917109 ends
1215 v_db_node_registered := true;
1216 exit; -- we found match so we are done with this loop
1217 end if;
1218 end;
1219 end loop;
1220
1221 if (v_db_node_registered = false) then
1222 -- no match found in FND_OAM_FNDNODES_VL, so we will create
1223 -- a new entry for this host (if one does not
1224 -- already exist) with status as unknown for now.
1225 -- This is temporary bug fix for 2952829.
1226 declare
1227 v_temp number;
1228 v_host_count number;
1229 begin
1230 select 1 into v_temp
1231 from fnd_oam_app_sys_status
1232 where metric_short_name like 'HOST_%'
1233 and node_name = db.host_name;
1234 exception
1235 when no_data_found then
1236 select count(*) into v_host_count
1237 from fnd_oam_app_sys_status
1238 where metric_short_name like 'HOST_%'
1239 and node_name is not null;
1240
1241 insert_app_sys_status_internal(
1242 'HOST_'||to_char(v_host_count+1),
1243 null, null, null, null,
1244 STATUS_UNKNOWN, db.host_name);
1245 end;
1246 v_node_name := db.host_name;
1247 end if;
1248
1249 -- now insert status Database instance into
1250 -- fnd_oam_app_sys_status
1251 -- we will insert only if an entry for the host on which the
1252 -- db instance lives has already been inserted. This way we
1253 -- will avoid errors during computing rollup in situations where
1254 -- a db instance was living on a node that is not being
1255 -- monitored.
1256 declare
1257 v_temp number;
1258 begin
1259 select 1 into v_temp
1260 from fnd_oam_app_sys_status
1261 where metric_short_name like 'HOST_%'
1262 and node_name = v_node_name;
1263
1264 select count(*) into v_db_count
1265 from fnd_oam_app_sys_status
1266 where metric_short_name like 'DATABASE_INS_%'
1267 and node_name = v_node_name;
1268
1269 insert_app_sys_status_internal(
1270 'DATABASE_INS_' || to_char(v_db_count+1) || '_' || v_node_name,
1271 null, null, db.instance_name, 'D', v_db_status, v_node_name);
1272 exception
1273 when no_data_found then
1274 null;
1275 end;
1276 end loop;
1277 end;
1278
1279 -- DATA SERVER
1280 -- Now compute the rollup for database server status on each node
1281 declare
1282 cursor all_monitored_nodes is
1283 select node_name from fnd_oam_app_sys_status
1284 where metric_short_name like 'HOST_%'
1285 and node_name is not null;
1286 cursor db_instance (p_node varchar2) is
1287 select metric_short_name, status_code
1288 from fnd_oam_app_sys_status
1289 where metric_short_name like 'DATABASE_INS_%'
1290 and node_name = p_node;
1291 begin
1292 for nd in all_monitored_nodes loop
1293 declare
1294 info_table st_table;
1295 v_db_status number;
1296 v_db_count number := 0;
1297 begin
1298 for dbi in db_instance(nd.node_name) loop
1299 if dbi.status_code = STATUS_ERROR then
1300 info_table(1) := 1;
1301 elsif dbi.status_code = STATUS_WARNING then
1302 info_table(2) := 1;
1303 elsif dbi.status_code = STATUS_UNKNOWN then
1304 info_table(3) := 1;
1305 elsif dbi.status_code = STATUS_NORMAL then
1306 info_table(4) := 1;
1307 elsif dbi.status_code = STATUS_INACTIVE then
1308 info_table(5) := 1;
1309 end if;
1310 v_db_count := v_db_count + 1;
1311 end loop;
1312
1313 if (v_db_count > 0) then
1314 v_db_status := compute_rollup_status(info_table);
1315 insert_app_sys_status_internal(
1316 'DATA_SERVER_' || nd.node_name,
1317 null, null, null, 'D', v_db_status, nd.node_name);
1318 end if;
1319 end;
1320 end loop;
1321 end;
1322
1323 -- Now finally, compute the overall status for CP, Forms, Admin, Web and
1324 -- Database. These are computed simply from the overall statuses across
1325 -- the different nodes.
1326 -- CP
1327 compute_overall_server_status('CP_SERVER', 'C');
1328
1329 -- FORM
1330 compute_overall_server_status('FORMS_SERVER', 'F');
1331
1332 -- DATA
1333 compute_overall_server_status('DATA_SERVER', 'D');
1334
1335 -- ADMIN
1336 compute_overall_server_status('ADMIN_SERVER', 'A');
1337
1338 -- WEB
1339 compute_overall_server_status('WEB_SERVER', 'W');
1340 end;
1341 commit;
1342 EXCEPTION
1343 when others then
1344 rollback;
1345 raise;
1346 END refresh_app_sys_status;
1347
1348 --
1349 -- Name
1350 -- refresh_activity
1351 --
1352 -- Purpose
1353 -- Computes the values for the following indicators and updates the
1354 -- fnd_oam_mets table using an autonomous transaction.
1355 -- 1) Number of Active Users
1356 -- 2) Number of Database sessions
1357 -- 3) Number of Running requests
1358 -- 4) Number of Service Processes
1359 -- 5) Number of Serivces Up
1360 -- 6) Number of Serivces Down
1361 -- 7) Number of invalid objects
1362 -- 8) % of Workflow mailer messages waiting to be sent
1363 --
1364 -- Input Arguments
1365 --
1366 -- Output Arguments
1367 --
1368 -- Notes:
1369 --
1370 --
1371 PROCEDURE refresh_activity
1372 IS
1373 pragma AUTONOMOUS_TRANSACTION;
1374 ct_active_users number;
1375 ct_db_sessions number;
1376 ct_running_req number;
1377 ct_service_processes number;
1378 ct_services_up number;
1379 ct_services_down number;
1380 ct_invalid_objects number;
1381 ct_waiting_msg number;
1382 ct_processed_msg number;
1383 BEGIN
1384 if (is_collection_enabled('ACTIVE_USERS')) then
1385 -- get the number of active users
1386 select count(distinct(F.login_id))
1387 into ct_active_users
1388 from fnd_login_resp_forms F,
1389 gv$session S
1390 where F.AUDSID = S.AUDSID;
1391
1392 -- update the number of active forms users
1393 update_metric_internal('ACTIVE_USERS', to_char(ct_active_users), -1);
1394 end if;
1395
1396 if (is_collection_enabled('DB_SESSIONS')) then
1397 -- get the number of db sessions
1398 select count(*) into ct_db_sessions from gv$session where audsid > 0;
1399
1400 -- update the number of db sessions
1401 update_metric_internal('DB_SESSIONS', to_char(ct_db_sessions), -1);
1402 end if;
1403
1404 if (is_collection_enabled('RUNNING_REQ')) then
1405 -- get the number of running requests
1406 select count(*)
1407 into ct_running_req
1408 from fnd_concurrent_requests
1409 where phase_code = 'R';
1410
1411 -- update the number of running requests
1412 update_metric_internal('RUNNING_REQ', to_char(ct_running_req), -1);
1413 end if;
1414
1415 if (is_collection_enabled('SERVICE_PROCS')) then
1416 -- get the number of service processes
1417 select count(*)
1418 into ct_service_processes
1419 from fnd_concurrent_processes
1420 where process_status_code in ('R','A','P');
1421
1422 -- update the number of service processes
1423 update_metric_internal('SERVICE_PROCS', to_char(ct_service_processes), -1);
1424 end if;
1425
1426 if (is_collection_enabled('SERVICES_UP')) then
1427 -- Now get the number of Services Up
1428 select count(concurrent_queue_id)
1429 into ct_services_up
1430 from fnd_concurrent_queues_vl
1431 where running_processes = max_processes and max_processes > 0;
1432
1433 -- Update Services Up
1434 update_metric_internal('SERVICES_UP', to_char(ct_services_up), 0);
1435 end if;
1436
1437 if (is_collection_enabled('SERVICES_DOWN')) then
1438 -- Get the number of services down
1439 select count(concurrent_queue_id)
1440 into ct_services_down
1441 from fnd_concurrent_queues_vl
1442 where running_processes = 0 and max_processes > 0;
1443
1444 -- Update Services down
1445 update_metric_internal('SERVICES_DOWN', to_char(ct_services_down), 2);
1446 end if;
1447
1448 if (is_collection_enabled('INVALID_OBJECTS')) then
1449 -- Get the count of invalid objects for 'APPS' schema only
1450 -- using user() function instead of hard coding 'APPS' - fix
1451 -- for bug 3876651
1452 SELECT COUNT(*)
1453 into ct_invalid_objects
1454 FROM DBA_OBJECTS DO
1455 WHERE DO.STATUS = 'INVALID' AND
1456 DO.OWNER = user and
1457 EXISTS (select 1
1458 from DBA_ERRORS DE
1459 where DE.NAME = DO.OBJECT_NAME AND
1460 DE.OWNER = DO.OWNER );
1461
1462 -- Update the invalid objects
1463 update_metric_internal('INVALID_OBJECTS', to_char(ct_invalid_objects), -1);
1464 end if;
1465
1466 -- added changes for this metric for performance optimization
1467 -- if a greater than threshold is specified for alerting, during
1468 -- FNDOAMCOL execution metric value will be counted only upto
1469 -- the threshold value
1470 if (is_collection_enabled('WFM_WAIT_MSG')) then
1471 declare
1472 v_alrt_enabled_flag fnd_oam_metval.alert_enabled_flag%TYPE;
1473 v_threshold_oper fnd_oam_metval.threshold_operator%TYPE;
1474 v_threshold_val fnd_oam_metval.threshold_value%TYPE;
1475 begin
1476 select nvl(alert_enabled_flag,'Y'),
1477 threshold_operator, threshold_value
1478 into v_alrt_enabled_flag, v_threshold_oper, v_threshold_val
1479 from fnd_oam_metval
1480 where metric_short_name = 'WFM_WAIT_MSG';
1481
1482 if (is_request() and
1483 v_alrt_enabled_flag = 'Y' and
1484 v_threshold_oper = OPER_G and
1485 v_threshold_val is not null) then
1486 -- Count only upto the specified threshold
1487 select count(*)
1488 into ct_waiting_msg
1489 from
1490 (
1491 select mail_status
1492 from wf_notifications
1493 where mail_status = 'MAIL' ) v
1494 where rownum <= to_number(v_threshold_val) + 1;
1495 else
1496 -- Get the full count of waiting workflow mailer messages
1497 select count(*)
1498 into ct_waiting_msg
1499 from wf_notifications
1500 where mail_status = 'MAIL';
1501 end if;
1502 end;
1503
1504 -- Update the unsent workflow email metric
1505 update_metric_internal('WFM_WAIT_MSG', to_char(ct_waiting_msg), -1);
1506 end if;
1507
1508 commit;
1509 EXCEPTION
1510 when others then
1511 rollback;
1512 raise;
1513 END refresh_activity;
1514
1515 --
1516 -- Name
1517 -- refresh_config_changes
1518 --
1519 -- Purpose
1520 -- Computes the values for the following indicators and updates the
1521 -- fnd_oam_mets table using an autonomous transaction.
1522 -- 1) Number of patches applied in the last 24 hours
1523 -- 2) Number of changes in profile options in last 24 hours
1524 --
1525 -- Input Arguments
1526 --
1527 -- Output Arguments
1528 --
1529 -- Notes:
1530 --
1531 --
1532 PROCEDURE refresh_config_changes
1533 IS
1534 pragma AUTONOMOUS_TRANSACTION;
1535 ct_patches number;
1536 ct_profile_options number;
1537 ct_context_files number;
1538 BEGIN
1539 if (is_collection_enabled('PATCHES')) then
1540 -- Get the number of patches applied within last 24 hours
1541
1542 -- Modified query for bug 3835667
1543 select count(*) into ct_patches
1544 from ad_patch_drivers d, ad_patch_runs r
1545 where r.end_date >= sysdate - 1
1546 and d.patch_driver_id = r.patch_driver_id;
1547
1548 --select count(distinct(PATCH_NAME))
1549 -- into ct_patches
1550 -- from ad_applied_patches where APPLIED_PATCH_ID in
1551 -- (select APPLIED_PATCH_ID from ad_patch_drivers where PATCH_DRIVER_ID in
1552 -- (select PATCH_DRIVER_ID from ad_patch_runs where sysdate-START_DATE <=1));
1553
1554 -- Update the number of patches applied within last 24 hours
1555 update_metric_internal('PATCHES', to_char(ct_patches), -1);
1556 end if;
1557
1558 if (is_collection_enabled('PROFILE_OPT')) then
1559 -- get the number of profile options changed in last 24 hours
1560 select count(*) into ct_profile_options
1561 from fnd_profile_options ovl,
1562 fnd_profile_option_values v
1563 where ovl.start_date_active <= SYSDATE
1564 and (nvl(ovl.end_date_active, SYSDATE) >= SYSDATE)
1565 and (v.level_id = 10001 and v.level_value = 0)
1566 and ovl.profile_option_id = v.profile_option_id
1567 and ovl.application_id = v.application_id
1568 and (sysdate - v.last_update_date <= 1);
1569
1570 -- Update the profile options
1571 update_metric_internal('PROFILE_OPT', to_char(ct_profile_options), -1);
1572 end if;
1573
1574 if (is_collection_enabled('CONTEXT_FILES_EDITED')) then
1575 -- query the number of context files changed in last 24 hours
1576 select count(*) into ct_context_files
1577 from (
1578 select focf.last_update_date lud
1579 from fnd_oam_context_files focf
1580 where (status <> 'H' or status is null)
1581 and upper(name) <> 'METADATA')
1582 where lud >= sysdate - 1;
1583
1584 -- update the number of context files changed
1585 update_metric_internal('CONTEXT_FILES_EDITED', to_char(ct_context_files), -1);
1586 end if;
1587
1588 commit;
1589 EXCEPTION
1590 when others then
1591 rollback;
1592 raise;
1593 END refresh_config_changes;
1594
1595 --
1596 -- Name
1597 -- refresh_throughput
1598 --
1599 -- Purpose
1600 -- Computes the values for the following indicators and updates the
1601 -- fnd_oam_mets table using an autonomous transaction.
1602 -- 1) % of Completed requests
1603 -- 2) % of Workflow mailer messages that have been processed
1604 --
1605 -- Input Arguments
1606 --
1607 -- Output Arguments
1608 --
1609 -- Notes:
1610 --
1611 --
1612 PROCEDURE refresh_throughput
1613 IS
1614 pragma AUTONOMOUS_TRANSACTION;
1615 ct_completed_req number;
1616 ct_total_req number;
1617 ct_waiting_msg number;
1618 ct_processed_msg number;
1619 BEGIN
1620 if (is_collection_enabled('COMPLETED_REQ')) then
1621 -- Compute the percentage of completed requests as the following:
1622 -- The numerator is the sum of the running requests and the requests that
1623 -- completed in the last 24 hours.
1624 -- The denominator is the sum of the running requests, the requests that
1625 -- completed in the last 24 hours, and the requests
1626 -- that are eligible to run at the current time.
1627 declare
1628 v_numerator number;
1629 v_denominator number;
1630 begin
1631 select count(*) into v_numerator
1632 from fnd_concurrent_requests
1633 where phase_code in ('R', 'C')
1634 and status_code <> 'D'
1635 and greatest(requested_start_date, request_date)
1636 between sysdate-1 and sysdate;
1637
1638 select count(*) into v_denominator
1639 from fnd_concurrent_requests
1640 where ( (phase_code in ('R', 'C')
1641 and status_code <> 'D')
1642 or ( status_code in ('I','Q')
1643 and hold_flag <> 'Y') )
1644 and greatest(requested_start_date, request_date)
1645 between sysdate-1 and sysdate;
1646
1647 select round((greatest(1,v_numerator)/greatest(1,v_denominator))* 100)
1648 into ct_completed_req
1649 from dual;
1650 update_metric_internal('COMPLETED_REQ', to_char(ct_completed_req), -1);
1651 end;
1652 end if;
1653
1654
1655 if (is_collection_enabled('WFM_PROC_MSG')) then
1656 -- Get the count of processed workflow mailer messages that began within
1657 -- last 24 hours
1658 select count(*)
1659 into ct_processed_msg
1660 from wf_notifications
1661 where mail_status = 'SENT'
1662 and status = 'OPEN'
1663 and (sysdate - begin_date <= 1);
1664
1665 update_metric_internal('WFM_PROC_MSG', to_char(ct_processed_msg), -1);
1666 end if;
1667
1668 commit;
1669 EXCEPTION
1670 when others then
1671 rollback;
1672 raise;
1673 END refresh_throughput;
1674
1675 --
1676 -- Name
1677 -- refresh_user_alerts_summary
1678 --
1679 -- Purpose
1680 -- Computes the values for the following indicators and updates the
1681 -- fnd_oam_mets table using an autonomous transaction.
1682 --
1683 -- 1) Number of New User Alerts
1684 -- 2) Number of New User Alert Occurrances
1685 -- 3) Number of Open User Alerts
1686 -- 4) Number of Open User Alert Occurrances
1687 --
1688 -- Input Arguments
1689 --
1690 -- Output Arguments
1691 --
1692 -- Notes:
1693 --
1694 --
1695 PROCEDURE refresh_user_alerts_summary
1696 IS
1697 pragma AUTONOMOUS_TRANSACTION;
1698 --ct_unpr number;
1699 --ct_pr number;
1700 --ct_total_unpr number;
1701 ct_new_al number;
1702 ct_new_occ number;
1703 ct_open_al number;
1704 ct_open_occ number;
1705 BEGIN
1706 if (is_collection_enabled('USER_ALERT_NEW')) then
1707 -- get the number of new alerts
1708 select count(*) into ct_new_al from fnd_log_unique_exceptions where
1709 status='N' and category='USER';
1710
1711 -- update new alerts
1712 update_metric_internal('USER_ALERT_NEW', to_char(ct_new_al), -1);
1713 end if;
1714
1715 if (is_collection_enabled('USER_ALERT_NEW_OCC')) then
1716 -- get the number of new occurrences
1717 select count(*) into ct_new_occ
1718 from fnd_log_exceptions fle, fnd_log_unique_exceptions flue
1719 where fle.unique_exception_id = flue.unique_exception_id
1720 and flue.status='N'
1721 and flue.category='USER';
1722
1723 -- update new occurrances
1724 update_metric_internal('USER_ALERT_NEW_OCC', to_char(ct_new_occ), -1);
1725 end if;
1726
1727
1728 if (is_collection_enabled('USER_ALERT_OPEN')) then
1729 -- get number of open alerts
1730 select count(*) into ct_open_al from fnd_log_unique_exceptions where
1731 status='O' and category='USER';
1732
1733 -- update open alerts
1734 update_metric_internal('USER_ALERT_OPEN', to_char(ct_open_al), -1);
1735 end if;
1736
1737 if (is_collection_enabled('USER_ALERT_OPEN_OCC')) then
1738 -- get the number of open occurrences
1739 select count(*) into ct_open_occ
1740 from fnd_log_exceptions fle, fnd_log_unique_exceptions flue
1741 where fle.unique_exception_id = flue.unique_exception_id
1742 and flue.status='O'
1743 and flue.category='USER';
1744
1745 -- update open occurrances
1746 update_metric_internal('USER_ALERT_OPEN_OCC', to_char(ct_open_occ), -1);
1747 end if;
1748
1749 commit;
1750 EXCEPTION
1751 when others then
1752 rollback;
1753 raise;
1754 END refresh_user_alerts_summary;
1755
1756 --
1757 -- Name
1758 -- refresh_exceptions_summary
1759 --
1760 -- Purpose
1761 -- Computes the values for the following indicators and updates the
1762 -- fnd_oam_mets table using an autonomous transaction.
1763 -- #1) Number of critical unprocessed exceptions in last 24 hours
1764 -- #2) Number of critical processed exceptions in last 24 hours
1765 -- #3) Number of total critical unprocessed exceptions
1766 --
1767 -- 1) Number of New System Alerts
1768 -- 2) Number of New Occurrances
1769 -- 3) Number of Open System Alerts
1770 -- 4) Number of Open Occurrances
1771 --
1772 -- Input Arguments
1773 --
1774 -- Output Arguments
1775 --
1776 -- Notes:
1777 --
1778 --
1779 PROCEDURE refresh_exceptions_summary
1780 IS
1781 pragma AUTONOMOUS_TRANSACTION;
1782 --ct_unpr number;
1783 --ct_pr number;
1784 --ct_total_unpr number;
1785 ct_new_al number;
1786 ct_new_occ number;
1787 ct_open_al number;
1788 ct_open_occ number;
1789 BEGIN
1790 if (is_collection_enabled('CRIT_UNPR_EXCEP')) then
1791 -- get the number of new alerts
1792 select count(*) into ct_new_al from fnd_log_unique_exceptions where
1793 status='N';
1794
1795 -- update new alerts
1796 update_metric_internal('CRIT_UNPR_EXCEP', to_char(ct_new_al), -1);
1797 end if;
1798
1799 if (is_collection_enabled('CRIT_PR_EXCEP')) then
1800 -- get the number of new occurrences
1801 select count(*) into ct_new_occ
1802 from fnd_log_exceptions fle, fnd_log_unique_exceptions flue
1803 where fle.unique_exception_id = flue.unique_exception_id
1804 and flue.status='N';
1805
1806 -- update new occurrances
1807 update_metric_internal('CRIT_PR_EXCEP', to_char(ct_new_occ), -1);
1808 end if;
1809
1810
1811 if (is_collection_enabled('CRIT_TOTAL_UNPR_EXCEP')) then
1812 -- get number of open alerts
1813 select count(*) into ct_open_al from fnd_log_unique_exceptions where
1814 status='O';
1815
1816 -- update open alerts
1817 update_metric_internal('CRIT_TOTAL_UNPR_EXCEP', to_char(ct_open_al), -1);
1818 end if;
1819
1820 if (is_collection_enabled('OPEN_OCC')) then
1821 -- get the number of open occurrences
1822 select count(*) into ct_open_occ
1823 from fnd_log_exceptions fle, fnd_log_unique_exceptions flue
1824 where fle.unique_exception_id = flue.unique_exception_id
1825 and flue.status='O';
1826
1827 -- update open occurrances
1828 update_metric_internal('OPEN_OCC', to_char(ct_open_occ), -1);
1829 end if;
1830
1831 commit;
1832 EXCEPTION
1833 when others then
1834 rollback;
1835 raise;
1836 END refresh_exceptions_summary;
1837
1838 --
1839 -- Name
1840 -- refresh_miscellaneous
1841 --
1842 -- Purpose
1843 -- Computes the values for the following indicators and
1844 -- updates the FND_OAM_METVAL using an autonomous transaction.
1845 -- Metrics: PL./SQL Agent, Servlet Agent, JSP Agent, JTF, Discoverer,
1846 -- Personal Home Page, TCF
1847 --
1848 -- Input Arguments
1849 --
1850 -- Output Arguments
1851 --
1852 -- Notes:
1853 -- THIS PROCEDURE IS DEPRECATED - PLEASE DO NOT CALL THIS ANYMORE
1854 -- Use the corresponding Java API instead.
1855 --
1856 PROCEDURE refresh_miscellaneous
1857 IS
1858 pragma AUTONOMOUS_TRANSACTION;
1859 v_status_code number;
1860 v_agent_short_name varchar2(30);
1861 BEGIN
1862 for agent in AGENT_MIN..AGENT_MAX loop
1863 v_status_code := get_agent_status(agent);
1864
1865 -- figure out the metric short name
1866 if agent = AOLJ_DB_POOL then
1867 v_agent_short_name := 'AOLJ_DB_POOL_GEN';
1868 elsif agent = PLSQL_AGNT then
1869 v_agent_short_name := 'PL_SQL_AGNT_GEN';
1870 elsif agent = SERVLET_AGNT then
1871 v_agent_short_name := 'SERVLET_AGNT_GEN';
1872 elsif agent = TCF then
1873 v_agent_short_name := 'TCF_GEN';
1874 elsif agent = JSP then
1875 v_agent_short_name := 'JSP_AGNT_GEN';
1876 elsif agent = JTF then
1877 v_agent_short_name := 'JTF_GEN';
1878 elsif agent = DISCOVERER then
1879 v_agent_short_name := 'DISCOVERER_GEN';
1880 elsif agent = PHP then
1881 v_agent_short_name := 'PHP_GEN';
1882 elsif agent = REPORT then
1883 v_agent_short_name := 'REPORT_GEN';
1884 elsif agent = FWK then
1885 v_agent_short_name := 'FWK_GEN';
1886 elsif agent = FORMS then
1887 v_agent_short_name := 'FORMS_GEN';
1888 end if;
1889
1890 update_metric_internal(v_agent_short_name, null, v_status_code);
1891 end loop;
1892
1893 commit;
1894 EXCEPTION
1895 when others then
1896 rollback;
1897 raise;
1898 END refresh_miscellaneous;
1899
1900 --
1901 -- Name
1902 -- raise_alerts
1903 --
1904 -- Purpose
1905 -- Checks values for all metrics and service instances that are currently
1906 -- being monitored and raises alert if the values or status codes match
1907 -- the thresholds specified by the user.
1908 --
1909 -- Input Arguments
1910 --
1911 -- Output Arguments
1912 --
1913 -- Notes:
1914 --
1915 --
1916 PROCEDURE raise_alerts
1917 IS
1918 cursor c_mets is
1919 select metric_short_name, metric_type, metric_value, status_code,
1920 threshold_operator, threshold_value
1921 from fnd_oam_metval
1922 where nvl(is_supported,'Y') = 'Y'
1923 and nvl(collection_enabled_flag,'Y') = 'Y'
1924 and nvl(alert_enabled_flag, 'N') = 'Y'
1925 and group_id <> 8 and group_id <> 0; -- Disabling Alerting for Web Components and Internal Metrics
1926 -- For OAM Rollup A
1927
1928 cursor c_svci is
1929 select foa.application_id application_id,
1930 foa.concurrent_queue_name concurrent_queue_name,
1931 fcq.concurrent_queue_id concurrent_queue_id,
1932 foa.status_code status_code
1933 from fnd_oam_app_sys_status foa,
1934 fnd_concurrent_queues fcq,
1935 fnd_oam_svci_info fsi
1936 where foa.application_id = fcq.application_id
1937 and foa.concurrent_queue_name = fcq.concurrent_queue_name
1938 and foa.application_id = fsi.application_id (+)
1939 and foa.concurrent_queue_name = fsi.concurrent_queue_name (+)
1940 and nvl(fsi.collection_enabled_flag, 'Y') = 'Y'
1941 and nvl(fsi.alert_enabled_flag, 'N') = 'Y';
1942
1943 v_metric_list varchar2(3500) := '';
1944 v_st_list varchar2(3500) := '';
1945 v_temp varchar2(300) := '';
1946
1947 v_x varchar2(2000);
1948 BEGIN
1949 for met in c_mets loop
1950 if (shall_raise_alert(met.metric_short_name)) then
1951 v_temp := met.metric_short_name;
1952 if (met.metric_type = 'S') then
1953 v_temp := v_temp || ':' || met.status_code || ',';
1954 if (length(v_st_list || v_temp) < 3500) then
1955 v_st_list := v_st_list || v_temp;
1956 end if;
1957 else
1958 v_temp := v_temp ||':'||met.threshold_operator||':'||met.threshold_value||',';
1959 if (length(v_metric_list || v_temp) < 3500) then
1960 v_metric_list := v_metric_list || v_temp;
1961 end if;
1962 end if;
1963 end if;
1964 end loop;
1965
1966 for svci in c_svci loop
1967 if (shall_raise_alert(svci.application_id,
1968 svci.concurrent_queue_name)) then
1969 v_temp := svci.application_id||':'||svci.concurrent_queue_id||':'||svci.status_code||',';
1970
1971 if (length(v_st_list || v_temp) < 3500) then
1972 v_st_list := v_st_list || v_temp;
1973 end if;
1974 end if;
1975 end loop;
1976
1977 if (length(v_metric_list) > 0) then
1978 if (fnd_log.level_unexpected >= fnd_log.g_current_runtime_level) then
1979 fnd_message.clear;
1980 fnd_message.set_name('FND','OAM_DASHBOARD_METRIC_ALERT');
1981 fnd_message.set_token_sql('METRICS_AND_VALUES',
1982 'select fnd_oam_dashboard_util.get_trans_name_values(''MET'','''||v_metric_list||''') from dual');
1983 --dbms_output.put_line('MET ALERT: ' || fnd_message.get);
1984 fnd_log.message(log_level=>fnd_log.level_unexpected,
1985 module=>MODULE||'.raise_alert',
1986 pop_message=>true);
1987 end if;
1988 end if;
1989
1990 if (length(v_st_list) > 0) then
1991 if (fnd_log.level_unexpected >= fnd_log.g_current_runtime_level) then
1992 fnd_message.clear;
1993 fnd_message.set_name('FND','OAM_DASHBOARD_STATUS_ALERT');
1994 fnd_message.set_token_sql('COMPONENTS_AND_STATUS',
1995 'select fnd_oam_dashboard_util.get_trans_name_values(''STATUS'','''||v_st_list||''') from dual');
1996 --dbms_output.put_line('STATUS ALERT: ' || fnd_message.get);
1997 fnd_log.message(log_level=>fnd_log.level_unexpected,
1998 module=>MODULE||'.raise_alert',
1999 pop_message=>true);
2000 end if;
2001 end if;
2002 END;
2003
2004
2005 --
2006 -- Name
2007 -- refresh_all
2008 --
2009 -- Purpose
2010 -- Computes the values for all the indicators and updates the
2011 -- fnd_oam_mets table.
2012 --
2013 -- Input Arguments
2014 --
2015 -- Output Arguments
2016 -- errbuf - for any error message
2017 -- retcode - 0 for success, 1 for success with warnings, 2 for error
2018 --
2019 -- Notes:
2020 --
2021 --
2022 PROCEDURE refresh_all (errbuf OUT NOCOPY VARCHAR2, retcode OUT NOCOPY VARCHAR2)
2023 IS
2024
2025 BEGIN
2026 fnd_file.put_line(fnd_file.log, 'Refreshing All ...');
2027
2028 fnd_file.put_line(fnd_file.log, 'Refreshing Applications System Status ...');
2029 refresh_app_sys_status;
2030 fnd_file.new_line(fnd_file.log, 1);
2031
2032 fnd_file.put_line(fnd_file.log, 'Refreshing Activity ...');
2033 refresh_activity;
2034 fnd_file.new_line(fnd_file.log, 1);
2035
2036 fnd_file.put_line(fnd_file.log, 'Refreshing Configuration Changes ...');
2037 refresh_config_changes;
2038 fnd_file.new_line(fnd_file.log, 1);
2039
2040 fnd_file.put_line(fnd_file.log, 'Refreshing Throughput ...');
2041 refresh_throughput;
2042 fnd_file.new_line(fnd_file.log, 1);
2043
2044 fnd_file.put_line(fnd_file.log, 'Refreshing Exceptions Summary ...');
2045 refresh_exceptions_summary;
2046 fnd_file.new_line(fnd_file.log, 1);
2047
2048 fnd_file.put_line(fnd_file.log, 'Refreshing Miscellaneous ...');
2049 refresh_miscellaneous;
2050 fnd_file.new_line(fnd_file.log, 1);
2051
2052 fnd_file.put_line(fnd_file.log, 'Done refreshing All ...');
2053
2054 -- Cancel any reduntant pending requests
2055 fnd_file.put_line(fnd_file.log, 'Cancelling any pending requests for FNDOAMCOL ...');
2056 declare
2057 cursor pending_req is
2058 select
2059 fcr.request_id request_id
2060 from fnd_concurrent_requests fcr, fnd_concurrent_programs fcp
2061 where
2062 fcr.program_application_id = fcp.application_id
2063 and fcr.concurrent_program_id = fcp.concurrent_program_id
2064 and fcp.concurrent_program_name = 'FNDOAMCOL'
2065 and fcr.phase_code = 'P';
2066 ret_code number;
2067 ret_msg varchar2(1000);
2068 begin
2069 for p_r in pending_req loop
2070 begin
2071 ret_code := -1;
2072 ret_msg := '';
2073 fnd_file.put_line(fnd_file.log, 'Found pending request: ' || p_r.request_id);
2074 ret_code := fnd_amp_private.cancel_request(p_r.request_id, ret_msg);
2075 if (ret_code <> 4 and ret_code <> 5) then
2076 fnd_file.put_line(fnd_file.log, 'Unable to cancel request ' || p_r.request_id);
2077 fnd_file.put_line(fnd_file.log, 'Message: ' || ret_msg);
2078 elsif (ret_code >= 0) then
2079 fnd_file.put_line(fnd_file.log, 'Cancelled request ' || p_r.request_id);
2080 else
2081 fnd_file.put_line(fnd_file.log, 'ret_code: ' || ret_code);
2082 fnd_file.put_line(fnd_file.log, 'Message: ' || ret_msg);
2083 end if;
2084 end;
2085 end loop;
2086
2087 exception
2088 -- some error occurred while cancelling pending requests
2089 -- Not failing the program since refresh was completed successfully.
2090 when others then
2091 null;
2092 end;
2093 fnd_file.new_line(fnd_file.log, 1);
2094 fnd_file.put_line(fnd_file.log, 'Done cancelling any pending requests for FNDOAMCOL ...');
2095
2096 retcode := '0';
2097 errbuf := 'Refresh Action OK';
2098 EXCEPTION
2099 when others then
2100 retcode := '2';
2101 errbuf := SQLERRM;
2102 END refresh_all;
2103
2104 --
2105 -- Name
2106 -- submit_col_req_conditional
2107 --
2108 -- Purpose
2109 -- Submits a request for program 'FNDOAMCOL' if and only if there are no
2110 -- other requests for this program in the pending or running phase.
2111 --
2112 -- Input Arguments
2113 --
2114 -- Output Arguments
2115 --
2116 --
2117 -- Notes:
2118 --
2119 --
2120 PROCEDURE submit_col_req_conditional
2121 IS
2122 retcode number;
2123 retval boolean;
2124 msg varchar2(1000);
2125 active_count number;
2126
2127 appl_id number;
2128 resp_id number;
2129 user_id number;
2130 user_name varchar2(80);
2131 resp_name varchar2(80);
2132 resp_key varchar2(50);
2133
2134 p_request_id number := null;
2135 p_phase varchar2(100);
2136 p_status varchar2(100);
2137 p_dev_phase varchar2(100);
2138 p_dev_status varchar2(100);
2139 p_message varchar2(500);
2140 outcome boolean;
2141 BEGIN
2142 -- First query to see if there is a request already submitted for this
2143 -- program.
2144 outcome :=
2145 fnd_concurrent.get_request_status(
2146 request_id=>p_request_id,
2147 appl_shortname=>'FND',
2148 program=>'FNDOAMCOL',
2149 phase=>p_phase,
2150 status=>p_status,
2151 dev_phase=>p_dev_phase,
2152 dev_status=>p_dev_status,
2153 message=>p_message);
2154
2155 --dbms_output.put_line('REQ ID ' || p_request_id);
2156 --dbms_output.put_line('PHASE ' || p_phase);
2157 --dbms_output.put_line('STATUS ' || p_status);
2158 --dbms_output.put_line('DEV_PHASE ' || p_dev_phase);
2159 --dbms_output.put_line('DEV_STATUS ' || p_dev_status);
2160 --dbms_output.put_line('MESSAGE ' || p_message);
2161 if p_dev_phase is null then
2162 p_dev_phase := 'X';
2163 end if;
2164 if ((outcome = false and p_request_id is null) or
2165 (outcome = true and p_request_id is not null and
2166 p_dev_phase <> 'PENDING' and
2167 p_dev_phase <> 'RUNNING')) and
2168 fnd_program.program_exists('FNDOAMCOL', 'FND') = true then
2169
2170 --dbms_output.put_line('Submmitting request');
2171 --select application_id, responsibility_id, responsibility_name
2172 -- into appl_id, resp_id, resp_name
2173 -- from fnd_responsibility_vl
2174 --where responsibility_name = 'System Administrator';
2175
2176 select application_id, responsibility_id, responsibility_key
2177 into appl_id, resp_id, resp_key
2178 from fnd_responsibility
2179 where responsibility_key = 'SYSTEM_ADMINISTRATOR';
2180
2181 select user_id, user_name
2182 into user_id, user_name
2183 from fnd_user
2184 where user_name = 'SYSADMIN';
2185
2186 -- Now initialize the environment for SYSADMIN
2187 fnd_global.apps_initialize(user_id, resp_id, appl_id);
2188
2189 -- Set the repeat options
2190 retval := fnd_request.set_repeat_options(repeat_interval => 10,
2191 repeat_unit => 'MINUTES',
2192 repeat_type => 'END');
2193
2194 -- Submit the request.
2195 retcode := fnd_request.submit_request(application=>'FND', program=>'FNDOAMCOL');
2196
2197 end if;
2198 commit;
2199 EXCEPTION
2200 when others then
2201 rollback;
2202 null;
2203 END submit_col_req_conditional;
2204
2205 --
2206 -- Name
2207 -- resubmit
2208 --
2209 -- Purpose
2210 -- Submits a request for program 'FNDOAMCOL' with the new repeat
2211 -- interval if the current interval is different from the new repeat
2212 -- interval.
2213 --
2214 -- It will cancel any pending or running requests before submitting
2215 -- a new request.
2216 --
2217 -- If more than one repeating requests are found, it will cancel them
2218 -- all and submit a new request with the given repeat interval.
2219 --
2220 --
2221 -- Input Arguments
2222 --
2223 -- p_repeat_interval - The new repeat interval
2224 -- p_repeat_interval_unit_code - The new repeat interval unit code
2225 --
2226 -- Output Arguments
2227 -- p_ret_code
2228 -- -1 - Was unable to cancel one or more in progress requests.
2229 -- Check p_ret_msg for any error message.
2230 -- -2 - There was no need to resubmit - since the currently
2231 -- repeating request has the same repeat interval.
2232 -- >0 - Successfully resubmitted. Request id of the new request.
2233 --
2234 -- p_ret_msg
2235 -- Any return error message.
2236 -- Notes:
2237 --
2238 --
2239 PROCEDURE resubmit(
2240 p_repeat_interval fnd_concurrent_requests.resubmit_interval%TYPE,
2241 p_repeat_interval_unit_code fnd_concurrent_requests.resubmit_interval_unit_code%TYPE,
2242 p_ret_code OUT NOCOPY number,
2243 p_ret_msg OUT NOCOPY varchar2)
2244 IS
2245 v_in_progress_count number := 0;
2246 v_continue_submit boolean := false;
2247 v_curr_interval fnd_concurrent_requests.resubmit_interval%TYPE;
2248 v_curr_unit_code fnd_concurrent_requests.resubmit_interval_unit_code%TYPE;
2249 ret_code number := -1;
2250 ret_msg varchar2(1000) := '';
2251 retval boolean;
2252 BEGIN
2253 select count(*) into v_in_progress_count
2254 from fnd_concurrent_requests fcr,
2255 fnd_concurrent_programs fcp
2256 where
2257 fcr.program_application_id = fcp.application_id
2258 and fcr.concurrent_program_id = fcp.concurrent_program_id
2259 and fcp.concurrent_program_name = 'FNDOAMCOL'
2260 and fcr.phase_code in ('R','P')
2261 and fcr.resubmit_interval is not null
2262 and fcr.resubmit_interval_unit_code is not null;
2263
2264 if (v_in_progress_count <> 1) then
2265 v_continue_submit := true;
2266 else
2267 -- compare repeat intervals to see if we need to resubmit
2268 select fcr.resubmit_interval, fcr.resubmit_interval_unit_code
2269 into v_curr_interval, v_curr_unit_code
2270 from fnd_concurrent_requests fcr,
2271 fnd_concurrent_programs fcp
2272 where
2273 fcr.program_application_id = fcp.application_id
2274 and fcr.concurrent_program_id = fcp.concurrent_program_id
2275 and fcp.concurrent_program_name = 'FNDOAMCOL'
2276 and fcr.phase_code in ('R','P')
2277 and fcr.resubmit_interval is not null
2278 and fcr.resubmit_interval_unit_code is not null;
2279
2280 if (v_curr_interval <> p_repeat_interval or
2281 v_curr_unit_code <> p_repeat_interval_unit_code) then
2282 v_continue_submit := true;
2283 else
2284 p_ret_code := -2; -- there was no need to resubmit
2285 p_ret_msg := '';
2286 end if;
2287 end if;
2288
2289 if (v_continue_submit = true) then
2290 -- cancel all pending running requests for FNDOAMCOL and submit new
2291 declare
2292 cursor repeating_req is
2293 select
2294 fcr.request_id request_id
2295 from fnd_concurrent_requests fcr, fnd_concurrent_programs fcp
2296 where
2297 fcr.program_application_id = fcp.application_id
2298 and fcr.concurrent_program_id = fcp.concurrent_program_id
2299 and fcp.concurrent_program_name = 'FNDOAMCOL'
2300 and fcr.phase_code in ('P','R');
2301
2302
2303 begin
2304 for p_r in repeating_req loop
2305 begin
2306 ret_code := fnd_amp_private.cancel_request(p_r.request_id, ret_msg);
2307 if (ret_code <> 4 and ret_code <> 5) then
2308 p_ret_code := -1;
2309 p_ret_msg := ret_msg;
2310 -- unable to cancel request
2311 return;
2312 end if;
2313
2314 -- log some debugging info
2315 if (fnd_log.level_event >= fnd_log.g_current_runtime_level) then
2316 fnd_log.string(log_level=>fnd_log.level_event,
2317 module=>MODULE||'.resubmit',
2318 message=>'Cancelled Request ' || p_r.request_id);
2319 end if;
2320 end;
2321 end loop;
2322
2323 -- Set the repeat options
2324 retval := fnd_request.set_repeat_options(
2325 repeat_interval => p_repeat_interval,
2326 repeat_unit => p_repeat_interval_unit_code,
2327 repeat_type => 'END');
2328 -- Submit the request.
2329 p_ret_code := fnd_request.submit_request(application=>'FND', program=>'FNDOAMCOL');
2330 p_ret_msg := ret_msg;
2331
2332 -- check for any errors in the request submission
2333 if (p_ret_code = 0) then
2334 p_ret_msg := fnd_message.get;
2335 end if;
2336 exception
2337 -- some error occurred
2338 when others then
2339 raise;
2340 end;
2341
2342 end if;
2343
2344 END resubmit;
2345
2346 --
2347 -- API to check if an already new or open alert exists for the given
2348 -- encoded messge
2349 --
2350 /*
2351 FUNCTION is_alert_open ( p_enc_msg fnd_log_unique_exceptions.encoded_message%TYPE) RETURN boolean
2352 IS
2353 v_exists boolean := FALSE;
2354 v_temp number := 0;
2355 BEGIN
2356 debug('p_enc_msg: ' || p_enc_msg);
2357 begin
2358 select 1 into v_temp
2359 from fnd_log_unique_exceptions
2360 where encoded_message = p_enc_msg
2361 and status in ('N','O');
2362 v_exists := TRUE;
2363 exception
2364 when no_data_found then
2365 v_exists := FALSE;
2366 end;
2367 debug('is_alert_open returning ' || v_temp);
2368 return v_exists;
2369 END is_alert_open;
2370 */
2371
2372 --
2373 -- Internal API for Alerting for Long Running Requests General
2374 --
2375 PROCEDURE ALERT_LRR_GEN
2376 IS
2377 v_lng_run_req_count fnd_oam_metval_vl.metric_value%TYPE;
2378 v_lng_run_req_alert_enable varchar2(1):='';
2379 v_lng_run_req_tolerance varchar2(10):='';
2380 v_lng_run_req_offset varchar2(10):='';
2381
2382 cursor req_id_list(p_tol varchar2,p_offset varchar2) is
2383 select fcr.request_id request_id,
2384 fcp.user_concurrent_program_name user_concurrent_program_name
2385 from
2386 fnd_concurrent_requests fcr,
2387 fnd_conc_prog_onsite_info fcpoi,
2388 fnd_concurrent_programs_vl fcp
2389 where
2390 fcr.program_application_id=fcpoi.program_application_id
2391 AND fcp.application_id = fcr.PROGRAM_APPLICATION_ID
2392 AND fcp.CONCURRENT_PROGRAM_ID=fcr.CONCURRENT_PROGRAM_ID
2393 and fcr.concurrent_program_id=fcpoi.concurrent_program_id
2394 and fcpoi.avg_run_time is not null
2395 and (sysdate -fcr.ACTUAL_START_DATE)*86400 >
2396 (fcpoi.avg_run_time*(1+.01*to_number(p_tol)))
2397 and ((sysdate -fcr.ACTUAL_START_DATE)*86400 >
2398 (to_number(p_offset)*60))
2399 and fcr.phase_code='R';
2400
2401 -- Types for record of tables
2402 TYPE NumTabType IS TABLE OF NUMBER
2403 INDEX BY BINARY_INTEGER;
2404 TYPE VarcharTabType IS TABLE OF
2405 fnd_concurrent_programs_vl.user_concurrent_program_name%TYPE
2406 INDEX BY BINARY_INTEGER;
2407
2408 TYPE RecTabType IS RECORD
2409 (request_id NumTabType,
2410 display_name VarcharTabType);
2411
2412 v_req_list_rec RecTabType;
2413 v_attch_id number;
2414
2415 BEGIN
2416 select threshold_value, alert_enabled_flag
2417 into v_lng_run_req_count, v_lng_run_req_alert_enable
2418 from fnd_oam_metval
2419 where metric_short_name ='LONG_RUNNING_REQ_COUNT';
2420
2421 select threshold_value into v_lng_run_req_tolerance
2422 from fnd_oam_metval
2423 where metric_short_name ='LONG_RUNNING_REQ_TOLERANCE';
2424
2425 select threshold_value into v_lng_run_req_offset
2426 from fnd_oam_metval
2427 where metric_short_name ='LONG_RUNNING_REQ_OFFSET';
2428
2429 if(v_lng_run_req_alert_enable ='Y') then
2430 open req_id_list(v_lng_run_req_tolerance,v_lng_run_req_offset);
2431 fetch req_id_list bulk collect
2432 into v_req_list_rec.request_id, v_req_list_rec.display_name;
2433 close req_id_list;
2434
2435 if ((v_req_list_rec.request_id is not null) and (v_req_list_rec.request_id.count >= TO_NUMBER(v_lng_run_req_count))) then
2436 -- raise alert with attachment
2437 if (fnd_log.level_unexpected >= fnd_log.g_current_runtime_level) then
2438 fnd_message.clear;
2439 fnd_message.set_name('FND','OAM_SYSAL_LONG_RUNNING_REQ_GEN');
2440 fnd_message.set_token('COUNT',v_lng_run_req_count);
2441 fnd_message.set_token('TOLERANCE',v_lng_run_req_tolerance);
2442 v_attch_id := fnd_log.message_with_attachment(
2443 log_level=>fnd_log.level_unexpected,
2444 module=>MODULE||'.Alert_Long_Running_Requests',
2445 pop_message=>false);
2446 fnd_log_attachment.writeln(
2447 pattachment_id => v_attch_id,
2448 pmessage => fnd_message.get);
2449 fnd_log_attachment.writeln(
2450 pattachment_id => v_attch_id,
2451 pmessage => ' ');
2452 for i in v_req_list_rec.request_id.FIRST..v_req_list_rec.request_id.LAST loop
2453 -- write info to attachment about each request.
2454 fnd_log_attachment.writeln(
2455 pattachment_id => v_attch_id,
2456 pmessage => v_req_list_rec.request_id(i) || ' - ' ||
2457 v_req_list_rec.display_name(i));
2458 end loop;
2459 fnd_log_attachment.close(
2460 pattachment_id => v_attch_id);
2461 end if;
2462 end if;
2463 end if; -- if(v_lng_run_req_alert_enable ='Y') then
2464
2465 END ALERT_LRR_GEN;
2466
2467 --
2468 -- Internal API for Alerting for Long Running Requests Specific
2469 --
2470 PROCEDURE ALERT_LRR_SPE
2471 IS
2472 v_spec_long_run_enabled varchar2(1):='';
2473
2474 cursor spec_req_id_list is
2475 select fcr.request_id request_id,
2476 fcp.user_concurrent_program_name user_concurrent_program_name,
2477 fcpoi.max_run_time max_run_time,
2478 fcpoi.avg_run_time avg_run_time,
2479 fcpoi.alert_long_running_threshold/60 threshold_minutes,
2480 fcpoi.alert_long_running_tolerance tolerance
2481 from
2482 fnd_concurrent_requests fcr,
2483 fnd_conc_prog_onsite_info fcpoi,
2484 fnd_concurrent_programs_vl fcp
2485 where
2486 fcr.program_application_id=fcpoi.program_application_id
2487 AND fcp.CONCURRENT_PROGRAM_ID=fcr.CONCURRENT_PROGRAM_ID
2488 AND fcp.application_id = fcr.PROGRAM_APPLICATION_ID
2489 and fcr.concurrent_program_id=fcpoi.concurrent_program_id
2490 and ((fcpoi.ALERT_LONG_RUNNING_THRESHOLD is not null)
2491 or (fcpoi.AVG_RUN_TIME is not null))
2492 and (sysdate -fcr.ACTUAL_START_DATE)*86400 >
2493 (to_number(nvl(fcpoi.ALERT_LONG_RUNNING_THRESHOLD,
2494 fcpoi.AVG_RUN_TIME))*(1+.01*to_number(nvl(
2495 fcpoi.ALERT_LONG_RUNNING_TOLERANCE,0))))
2496 and fcpoi.ALERT_LONG_RUNNING_ENABLED='Y'
2497 and fcr.phase_code='R';
2498
2499 -- Types for record of tables
2500 TYPE NumTabType IS TABLE OF NUMBER
2501 INDEX BY BINARY_INTEGER;
2502 TYPE VarcharTabType IS TABLE OF
2503 fnd_concurrent_programs_vl.user_concurrent_program_name%TYPE
2504 INDEX BY BINARY_INTEGER;
2505
2506 TYPE SpecRecTabType IS RECORD
2507 (request_id NumTabType,
2508 display_name VarcharTabType,
2509 max_run_time NumTabType,
2510 avg_run_time NumTabType,
2511 threshold NumTabType,
2512 tolerance NumTabType);
2513
2514 v_spec_req_list_rec SpecRecTabType;
2515
2516 v_spec_cnt number := 0;
2517 v_spec_tol number;
2518
2519 BEGIN
2520
2521 select threshold_value into v_spec_long_run_enabled
2522 from fnd_oam_metval
2523 where metric_short_name ='SPECIFIC_LONG_RUNNING_ENABLED';
2524
2525 if(v_spec_long_run_enabled ='Y') then
2526 --debug('v_spec_long_run_enabled is Y');
2527 select count(*) into v_spec_cnt
2528 from fnd_conc_prog_onsite_info
2529 where ALERT_LONG_RUNNING_ENABLED='Y' and rownum < 2;
2530 if (v_spec_cnt > 0) then
2531 open spec_req_id_list;
2532 fetch spec_req_id_list bulk collect
2533 into v_spec_req_list_rec.request_id,
2534 v_spec_req_list_rec.display_name,
2535 v_spec_req_list_rec.max_run_time,
2536 v_spec_req_list_rec.avg_run_time,
2537 v_spec_req_list_rec.threshold,
2538 v_spec_req_list_rec.tolerance;
2539 close spec_req_id_list;
2540
2541 if (v_spec_req_list_rec.request_id is not null and v_spec_req_list_rec.request_id.count > 0) then
2542 for i in v_spec_req_list_rec.request_id.FIRST..v_spec_req_list_rec.request_id.LAST loop
2543 --debug('Looping in cursor spec_req_id_list');
2544 if ((fnd_log.level_unexpected >= fnd_log.g_current_runtime_level)) then
2545 -- Compute tolerance for this program
2546 v_spec_tol := round(
2547 nvl(v_spec_req_list_rec.threshold(i),
2548 v_spec_req_list_rec.avg_run_time(i))*(
2549 1+.01*to_number(nvl(
2550 v_spec_req_list_rec.tolerance(i),0))));
2551
2552 -- Note: In the future if we provide users with more options, we
2553 -- may need to choose different messages based on those options
2554
2555 -- raise proxy alert for each request
2556 fnd_message.clear;
2557 fnd_message.set_name('FND','OAM_SYSAL_LONG_RUNNING_REQ_SPE');
2558 fnd_message.set_token('PROG', v_spec_req_list_rec.display_name(i));
2559 fnd_message.set_token('TOLERANCE', v_spec_tol);
2560 fnd_log.proxy_alert_for_conc_req(
2561 module => MODULE||'.Alert_Long_Running_Requests',
2562 pop_message => true,
2563 request_id => v_spec_req_list_rec.request_id(i));
2564 end if;
2565 end loop;
2566 end if;
2567 end if;
2568 end if;
2569
2570 END ALERT_LRR_SPE;
2571
2572 --
2573 -- Internal API for Alerting for Long Pending Requests General
2574 --
2575 PROCEDURE ALERT_LPR_GEN
2576 IS
2577 v_lng_pend_req_count fnd_oam_metval_vl.metric_value%TYPE;
2578 v_lng_pend_req_alert_enable varchar2(1):='';
2579 v_lng_pend_req_tolerance varchar2(10):='';
2580
2581 cursor req_id_list(p_tol varchar2) is
2582 select fcr.request_id request_id,
2583 fcp.user_concurrent_program_name user_concurrent_program_name
2584 from
2585 fnd_concurrent_requests fcr,
2586 fnd_conc_prog_onsite_info fcpoi,
2587 fnd_concurrent_programs_vl fcp
2588 where
2589 fcr.program_application_id=fcpoi.program_application_id
2590 AND fcp.application_id = fcr.PROGRAM_APPLICATION_ID
2591 AND fcp.CONCURRENT_PROGRAM_ID=fcr.CONCURRENT_PROGRAM_ID
2592 and fcr.concurrent_program_id=fcpoi.concurrent_program_id
2593 and ((sysdate -fcr.REQUESTED_START_DATE)*86400 >
2594 (to_number(nvl(p_tol,0))*60))
2595 and fcr.phase_code='P'
2596 and fcr.status_code in ('I', 'Q');
2597
2598 -- Types for record of tables
2599 TYPE NumTabType IS TABLE OF NUMBER
2600 INDEX BY BINARY_INTEGER;
2601 TYPE VarcharTabType IS TABLE OF
2602 fnd_concurrent_programs_vl.user_concurrent_program_name%TYPE
2603 INDEX BY BINARY_INTEGER;
2604
2605 TYPE RecTabType IS RECORD
2606 (request_id NumTabType,
2607 display_name VarcharTabType);
2608
2609 v_req_list_rec RecTabType;
2610 v_attch_id number;
2611
2612 BEGIN
2613 select threshold_value,alert_enabled_flag
2614 into v_lng_pend_req_count,v_lng_pend_req_alert_enable
2615 from fnd_oam_metval
2616 where metric_short_name ='LONG_PENDING_REQ_COUNT';
2617
2618 select threshold_value
2619 into v_lng_pend_req_tolerance
2620 from fnd_oam_metval
2621 where metric_short_name ='LONG_PENDING_REQ_TOLERANCE';
2622
2623 if(v_lng_pend_req_alert_enable ='Y') then
2624 open req_id_list(v_lng_pend_req_tolerance);
2625 fetch req_id_list bulk collect
2626 into v_req_list_rec.request_id, v_req_list_rec.display_name;
2627 close req_id_list;
2628
2629 if (v_req_list_rec.request_id is not null and v_req_list_rec.request_id.count >= TO_NUMBER(v_lng_pend_req_count)) then
2630 if (fnd_log.level_unexpected >= fnd_log.g_current_runtime_level) then
2631 fnd_message.clear;
2632 fnd_message.set_name('FND','OAM_SYSAL_LONG_PENDING_REQ_GEN');
2633 fnd_message.set_token('COUNT',v_lng_pend_req_count);
2634 fnd_message.set_token('TOLERANCE',v_lng_pend_req_tolerance);
2635 v_attch_id := fnd_log.message_with_attachment(
2636 log_level=>fnd_log.level_unexpected,
2637 module=>MODULE||'.Alert_Long_Pending_Requests',
2638 pop_message=>false);
2639 fnd_log_attachment.writeln(
2640 pattachment_id => v_attch_id,
2641 pmessage => fnd_message.get);
2642 fnd_log_attachment.writeln(
2643 pattachment_id => v_attch_id,
2644 pmessage => ' ');
2645 for i in v_req_list_rec.request_id.FIRST..v_req_list_rec.request_id.LAST loop
2646 -- write info to attachment about each request.
2647 fnd_log_attachment.writeln(
2648 pattachment_id => v_attch_id,
2649 pmessage => v_req_list_rec.request_id(i) || ' - ' ||
2650 v_req_list_rec.display_name(i));
2651 end loop;
2652 fnd_log_attachment.close(
2653 pattachment_id => v_attch_id);
2654 end if;
2655 end if;
2656 end if; -- if(v_lng_pend_req_alert_enable ='Y') then
2657
2658 END ALERT_LPR_GEN;
2659
2660 --
2661 -- Internal API for Alerting for Long Pending Requests Specific
2662 --
2663 PROCEDURE ALERT_LPR_SPE
2664 IS
2665 v_spec_long_pend_enabled varchar2(1):='';
2666
2667 cursor spec_req_id_list is
2668 select fcr.request_id request_id,
2669 fcp.user_concurrent_program_name user_concurrent_program_name,
2670 nvl(fcpoi.ALERT_LONG_PENDING_TOLERANCE,0)/60 tolerance_minutes
2671 from
2672 fnd_concurrent_requests fcr,
2673 fnd_conc_prog_onsite_info fcpoi,
2674 fnd_concurrent_programs_vl fcp
2675 where
2676 fcr.program_application_id=fcpoi.program_application_id
2677 AND fcp.application_id = fcr.PROGRAM_APPLICATION_ID
2678 AND fcp.CONCURRENT_PROGRAM_ID=fcr.CONCURRENT_PROGRAM_ID
2679 and fcr.concurrent_program_id=fcpoi.concurrent_program_id
2680 and (sysdate -fcr.REQUESTED_START_DATE)*86400 >
2681 (to_number(nvl(fcpoi.ALERT_LONG_PENDING_TOLERANCE,0)))
2682 and fcpoi.ALERT_LONG_PENDING_ENABLED='Y'
2683 and fcr.phase_code='P'
2684 and fcr.status_code in ('I', 'Q');
2685
2686 -- Types for record of tables
2687 TYPE NumTabType IS TABLE OF NUMBER
2688 INDEX BY BINARY_INTEGER;
2689 TYPE VarcharTabType IS TABLE OF
2690 fnd_concurrent_programs_vl.user_concurrent_program_name%TYPE
2691 INDEX BY BINARY_INTEGER;
2692
2693 TYPE SpecRecTabType IS RECORD
2694 (request_id NumTabType,
2695 display_name VarcharTabType,
2696 tolerance NumTabType);
2697
2698 v_spec_req_list_rec SpecRecTabType;
2699 v_spec_cnt number := 0;
2700 BEGIN
2701
2702 select threshold_value
2703 into v_spec_long_pend_enabled
2704 from fnd_oam_metval
2705 where metric_short_name ='SPECIFIC_LONG_PENDING_ENABLED';
2706
2707 if (v_spec_long_pend_enabled ='Y') then
2708 select count(*) into v_spec_cnt
2709 from fnd_conc_prog_onsite_info
2710 where ALERT_LONG_PENDING_ENABLED='Y' and rownum < 2;
2711
2712 if (v_spec_cnt > 0) then
2713 open spec_req_id_list;
2714 fetch spec_req_id_list bulk collect
2715 into
2716 v_spec_req_list_rec.request_id,
2717 v_spec_req_list_rec.display_name,
2718 v_spec_req_list_rec.tolerance;
2719 close spec_req_id_list;
2720
2721 if (v_spec_req_list_rec.request_id is not null and v_spec_req_list_rec.request_id.count > 0) then
2722 for i in v_spec_req_list_rec.request_id.FIRST..v_spec_req_list_rec.request_id.LAST loop
2723 if ((fnd_log.level_unexpected >= fnd_log.g_current_runtime_level)) then
2724 fnd_message.clear;
2725 fnd_message.set_name('FND','OAM_SYSAL_LONG_PENDING_REQ_SPE');
2726 fnd_message.set_token('PROG', v_spec_req_list_rec.display_name(i));
2727 fnd_message.set_token('TOLERANCE', v_spec_req_list_rec.tolerance(i));
2728 fnd_log.proxy_alert_for_conc_req(
2729 module => MODULE||'.Alert_Long_Pending_Requests',
2730 pop_message => true,
2731 request_id => v_spec_req_list_rec.request_id(i));
2732 end if;
2733 end loop;
2734 end if;
2735 end if;
2736 end if;
2737
2738 END ALERT_LPR_SPE;
2739
2740 --
2741 -- Name
2742 -- Alert_Long_Running_Requests
2743 --
2744 -- Purpose
2745 -- The procedure will raise a consolidated alert if more than
2746 -- a user specified threshold
2747 -- number of concurrent requests are running for more than a
2748 -- user specified threshold offset
2749 -- period of time and for more than a user specified threshold
2750 -- tolerance percentage of their
2751 -- respective average runtimes. It also raise an alert for specified
2752 -- concurrent programs if it
2753 -- runs for more than the user specified threshold tolerance percentage
2754 -- of its user specific threshold offset period of time.
2755 --
2756 -- Input Arguments
2757 --
2758 -- None
2759 --
2760 -- Output Arguments
2761 --
2762 -- None
2763 --
2764 -- Notes:
2765 --
2766 --
2767 PROCEDURE Alert_Long_Running_Requests
2768 IS
2769 BEGIN
2770 --
2771 -- Check logging enabled in the first place. There's nothing to do
2772 -- if not enabled.
2773 --
2774 if (fnd_log.level_unexpected < fnd_log.g_current_runtime_level) then
2775 fnd_file.put_line(fnd_file.log, 'Logging Not Enabled.');
2776 return;
2777 end if;
2778
2779 -- General Alert
2780 ALERT_LRR_GEN;
2781 -- Specific Alert
2782 ALERT_LRR_SPE;
2783
2784 END Alert_Long_Running_Requests;
2785
2786
2787 --
2788 -- Name
2789 -- Alert_Long_Pending_Requests
2790 --
2791 -- Purpose
2792 --
2793 -- The procedure raises a consolidated alert if more than a user specified
2794 -- threshold number of concurrent requests are pending for more than a user
2795 -- specified threshold period of time after their requested start time.
2796 -- It also raise an alert for specified concurrent programs if it is
2797 -- pending for more than a user specified threshold period of time.
2798 --
2799 -- Input Arguments
2800 --
2801 -- None
2802 --
2803 -- Output Arguments
2804 --
2805 -- None
2806 --
2807 -- Notes:
2808 --
2809 --
2810 PROCEDURE Alert_Long_Pending_Requests
2811 IS
2812
2813 BEGIN
2814 --
2815 -- Check logging enabled in the first place. There's nothing to do
2816 -- if not enabled.
2817 --
2818 if (fnd_log.level_unexpected < fnd_log.g_current_runtime_level) then
2819 fnd_file.put_line(fnd_file.log, 'Logging Not Enabled.');
2820 return;
2821 end if;
2822
2823 -- General Alert
2824 ALERT_LPR_GEN;
2825 -- Specific Alert
2826 ALERT_LPR_SPE;
2827
2828 END Alert_Long_Pending_Requests;
2829
2830 END fnd_oam_collection;