1 package body FND_CORE_LOG as
2 /* $Header: AFCORLGB.pls 120.9 2010/10/21 19:05:12 pdeluna ship $ */
3
4 UTL_DIR varchar2(255);
5 CORELOG_FILE utl_file.file_type;
6 CORELOG_FNAME varchar2(255) := NULL;
7 CORELOG_OPEN boolean;
8 CORELOG_ENABLED varchar2(1) := NULL;
9 CORELOG_PROFILE varchar2(80) := NULL;
10 CORELOG_IS_ENABLED boolean;
11
12 /*
13 ** FILENAME - returns the filename to be used by the core logging diagnostic
14 ** tool. The function uses the hostname and the instance name to
15 ** generate a unique filename.
16 */
17 function FILENAME return varchar2 is
18 lhost varchar2(255);
19 linstance varchar2(255);
20 fname varchar2(2000);
21 begin
22
23 select lower(host_name), lower(instance_name)
24 into lhost, linstance
25 from v$instance;
26
27 fname := 'afcorelog_'||lhost||'_'||linstance||'.txt';
28
29 return fname;
30 end FILENAME;
31
32 /*
33 ** ENABLED - returns 'Y' if AFCORE_LOGGING_ENABLED is 'Y'
34 ** returns 'N' if AFCORE_LOGGING_ENABLED is 'N'
35 ** returns 'P' if AFCORE_LOGGING_ENABLED is 'P'
36 */
37 function ENABLED return varchar2 is
38 begin
39 /* Determine if AFCORE_LOGGING_ENABLED is 'Y', 'N', or 'P'. A direct
40 ** select is done since Core Logging can be performed in FND_PROFILE APIs
41 ** and this could result in conflicts. AFCORE_LOGGING_ENABLED is
42 ** currently only settable only at the site level.
43 */
44 if CORELOG_ENABLED is NULL then
45 select FPOV.PROFILE_OPTION_VALUE
46 into CORELOG_ENABLED
47 from fnd_profile_option_values FPOV, fnd_profile_options FPO
48 where FPO.PROFILE_OPTION_NAME = 'AFCORE_LOGGING_ENABLED'
49 and FPO.PROFILE_OPTION_ID = FPOV.PROFILE_OPTION_ID
50 and FPOV.level_id = 10001
51 and FPO.APPLICATION_ID = FPOV.APPLICATION_ID; -- bug 4620968
52 end if;
53
54 /* If AFCORE_LOGGING_ENABLED is 'Y' or 'P', then check if CORELOG_FNAME
55 ** has been opened. If not, it needs to be opened.
56 */
57 if (CORELOG_ENABLED <> 'N') and (CORELOG_ENABLED is not null) then
58 if (CORELOG_OPEN = FALSE) or (CORELOG_OPEN is NULL) then
59 if (CORELOG_FNAME is NULL) then
60 CORELOG_FNAME := FILENAME;
61 end if;
62 PUT_NAMES(CORELOG_FNAME, UTL_DIR);
63 end if;
64
65 /* If AFCORE_LOGGING_ENABLED is 'N' or NULL, then check if CORELOG_FNAME
66 ** is open. If open, then it needs to be closed.
67 */
68 else
69 CORELOG_ENABLED := 'N'; -- default to 'N' for caching.
70 if (CORELOG_OPEN = TRUE) or (CORELOG_OPEN is NULL) then
71 CLOSE_FILE;
72 end if;
73 end if;
74
75 return CORELOG_ENABLED;
76
77 exception
78 when no_data_found then
79 CORELOG_ENABLED := 'N'; -- default to 'N' for caching.
80 if (CORELOG_OPEN = TRUE) or (CORELOG_OPEN is NULL) then
81 CLOSE_FILE;
82 end if;
83 return CORELOG_ENABLED;
84
85 end ENABLED;
86
87 /*
88 ** PROFILE_TO_LOG - returns PROFILE_OPTION_NAME to be logged
89 */
90 function PROFILE_TO_LOG return varchar2 is
91 begin
92 /* Determine if AFCORE_LOGGING_PROFILE_OPTION is not null. A direct
93 ** select is done since Core Logging can be performed in FND_PROFILE APIs
94 ** and this could result in conflicts. AFCORE_LOGGING_PROFILE_OPTION is
95 ** currently only enabled at the site level.
96 */
97 if CORELOG_PROFILE is NULL then
98 select FPOV.PROFILE_OPTION_VALUE
99 into CORELOG_PROFILE
100 from fnd_profile_option_values FPOV, fnd_profile_options FPO
101 where FPO.PROFILE_OPTION_NAME = 'AFCORE_LOGGING_PROFILE_OPTION'
102 and FPO.PROFILE_OPTION_ID = FPOV.PROFILE_OPTION_ID
103 and FPOV.level_id = 10001
104 and FPO.APPLICATION_ID = FPOV.APPLICATION_ID; -- bug 4620968
105 end if;
106
107 /* If CORELOG_PROFILE is not null, then check if CORELOG_PROFILE <= 80
108 ** characters. If > 80 chars, return null, else, return CORELOG_PROFILE.
109 */
110 if CORELOG_PROFILE is not null then
111 if (length(CORELOG_PROFILE) > 80) then
112 return null;
113 else
114 return CORELOG_PROFILE;
115 end if;
116
117 /* If CORELOG_PROFILE is NULL, then return NULL.
118 */
119 else
120 return null;
121 end if;
122
123 exception
124 when no_data_found then
125 CORELOG_PROFILE := null; -- default to NULL.
126 return null;
127 when others then
128 CORELOG_PROFILE := null; -- default to NULL.
129 return null;
130
131 end PROFILE_TO_LOG;
132
133 /*
134 ** WRITE - calls PUT to log text with a context
135 */
136 procedure WRITE(
137 CURRENT_API in varchar2,
138 LOG_USER_ID in number default NULL,
139 LOG_RESPONSIBILITY_ID in number default NULL,
140 LOG_APPLICATION_ID in number default NULL,
141 LOG_ORG_ID in number default NULL,
142 LOG_SERVER_ID in number default NULL,
143 LOG_TIME in varchar2 default NULL) is
144 begin
145 if (FND_CORE_LOG.IS_ENABLED) then
146
147 -- Write a line indicating the context for this session.
148 -- The format of this line is based loosely on the event_key format
149 -- used in WF.
150
151 -- Removed references to FND_GLOBAL to avoid a possible looping
152 -- scenario. PUT_LINE is called in FND_PROFILE and FND_PROFILE will
153 -- do the NVL substitution when it calls PUT_LINE.
154 PUT_LINE(
155 CURRENT_API||':'||
156 LOG_USER_ID||':'||
157 LOG_RESPONSIBILITY_ID||':'||
158 LOG_APPLICATION_ID||':'||
159 LOG_ORG_ID||':'||
160 LOG_SERVER_ID||':'||
161 userenv('sessionid')||':'||
162 LOG_TIME);
163
164 if CURRENT_API = 'FG.I' then
165 PUT_LINE(dbms_utility.format_call_stack);
166 end if;
167 end if;
168 end WRITE;
169
170 /*
171 ** WRITE_PROFILE - calls PUT and PUT_LINE to log text with a context
172 ** Will log only when FND_CORE_LOG.ENABLED = 'P'.
173 */
174 procedure WRITE_PROFILE(
175 LOG_PROFNAME in varchar2,
176 LOG_PROFVAL in varchar2 default null,
177 CURRENT_API in varchar2,
178 LOG_USER_ID in number,
179 LOG_RESPONSIBILITY_ID in number,
180 LOG_APPLICATION_ID in number,
181 LOG_ORG_ID in number,
182 LOG_SERVER_ID in number,
183 LOG_TIME in varchar2 default null)is
184
185 PROF_TO_LOG varchar2(80);
186 begin
187 if (FND_CORE_LOG.ENABLED = 'P') then
188
189 PROF_TO_LOG := FND_CORE_LOG.PROFILE_TO_LOG;
190
191 -- Write a line indicating the context for the FND_PROFILE session.
192 -- The format of this line is based loosely on the event_key format
193 -- used in WF.
194
195 -- If AFCORE_LOGGING_PROFILE_OPTION has a value, log only the lines
196 -- for that profile option.
197 -- Note: -99 means that no value was passed for context.
198 if (LOG_PROFNAME = PROF_TO_LOG) then
199 PUT_LINE(
200 LOG_PROFNAME,
201 nvl(LOG_PROFVAL,'NOVAL')||':'||
202 CURRENT_API||':'||
203 nvl(LOG_USER_ID,-99)||':'||
204 nvl(LOG_RESPONSIBILITY_ID,-99)||':'||
205 nvl(LOG_APPLICATION_ID,-99)||':'||
206 nvl(LOG_ORG_ID,-99)||':'||
207 nvl(LOG_SERVER_ID,-99)||':'||
208 userenv('sessionid')||':'||
209 LOG_TIME);
210
211 -- If CURRENT_API is a Generic FND_PROFILE.PUT call, include the
212 -- call stack.
213 if (CURRENT_API = 'Enter Generic FP.P') or
214 (CURRENT_API = 'VAL in GEN PUT, Exit FP.G') then
215 PUT_LINE(dbms_utility.format_call_stack);
216 end if;
217
218 -- If AFCORE_LOGGING_PROFILE_OPTION has a value and
219 -- CURRENT_API = 'FP.I' then log those lines also.
220 elsif (CURRENT_API = 'FP.I') then
221 PUT_LINE(
222 LOG_PROFNAME||':'||
223 nvl(LOG_PROFVAL,'NOVAL')||':'||
224 CURRENT_API||':'||
225 nvl(LOG_USER_ID, -99)||':'||
226 nvl(LOG_RESPONSIBILITY_ID,-99)||':'||
227 nvl(LOG_APPLICATION_ID,-99)||':'||
228 nvl(LOG_ORG_ID,-99)||':'||
229 nvl(LOG_SERVER_ID,-99)||':'||
230 userenv('sessionid')||':'||
231 LOG_TIME);
232
233 -- If AFCORE_LOGGING_PROFILE_OPTION is null, log everything.
234 elsif (PROF_TO_LOG is null) then
235 PUT_LINE(
236 LOG_PROFNAME||':'||
237 nvl(LOG_PROFVAL,'NOVAL')||':'||
238 CURRENT_API||':'||
239 nvl(LOG_USER_ID, -99)||':'||
240 nvl(LOG_RESPONSIBILITY_ID,-99)||':'||
241 nvl(LOG_APPLICATION_ID,-99)||':'||
242 nvl(LOG_ORG_ID,-99)||':'||
243 nvl(LOG_SERVER_ID,-99)||':'||
244 userenv('sessionid')||':'||
245 LOG_TIME);
246 end if;
247 end if;
248 end WRITE_PROFILE;
249
250 /*
251 ** WRITE_PROFILE_SAVE - write API specifically for FND_PROFILE.SAVE
252 ** Will log only when FND_CORE_LOG.ENABLED = 'P'.
253 */
254 procedure WRITE_PROFILE_SAVE(
255 X_NAME in varchar2,
256 /* Profile name */
257 X_VALUE in varchar2,
258 /* Profile value */
259 X_LEVEL_NAME in varchar2,
260 /* Level: 'SITE','APPL','RESP','USER', 'ORG', 'SERVER', 'SERVRESP' */
261 X_LEVEL_VALUE in varchar2 default NULL,
262 /* Level value, e.g. user id for 'USER' level.
263 X_LEVEL_VALUE is not used at site level. */
264 X_LEVEL_VALUE_APP_ID in varchar2 default NULL,
265 /* Used for 'RESP' and 'SERVRESP' level; Resp Application_Id. */
266 X_LEVEL_VALUE2 in varchar2 default NULL) is
267
268 PROF_TO_LOG varchar2(80);
269
270 begin
271 if (FND_CORE_LOG.ENABLED = 'P') then
272
273 PROF_TO_LOG := FND_CORE_LOG.PROFILE_TO_LOG;
274
275 -- Write a line indicating the context for the FND_PROFILE.SAVE call.
276 -- The format of this line is based loosely on the event_key format
277 -- used in WF.
278 -- If AFCORE_LOGGING_PROFILE_OPTION has a value, log only the lines
279 -- for that profile option.
280 if (X_NAME = PROF_TO_LOG) then
281 PUT_LINE(
282 X_NAME,
283 nvl(X_VALUE,'NULL')||':'||
284 'FP.S'||':'||
285 X_LEVEL_NAME||':'||
286 nvl(X_LEVEL_VALUE,'NULL')||':'||
287 nvl(X_LEVEL_VALUE_APP_ID,'NULL')||':'||
288 nvl(X_LEVEL_VALUE2,'NULL')||':'||
292 elsif (PROF_TO_LOG is null) then
289 userenv('sessionid'));
290
291 -- If AFCORE_LOGGING_PROFILE_OPTION is null, log everything.
293 PUT_LINE(
294 X_NAME,
295 nvl(X_VALUE,'NULL')||':'||
296 'FP.S'||':'||
297 X_LEVEL_NAME||':'||
298 nvl(X_LEVEL_VALUE,'NULL')||':'||
299 nvl(X_LEVEL_VALUE_APP_ID,'NULL')||':'||
300 nvl(X_LEVEL_VALUE2,'NULL')||':'||
301 userenv('sessionid'));
302 end if;
303 end if;
304 end WRITE_PROFILE_SAVE;
305
306 /*
307 ** PUT_NAMES - Set the logfile name and directory
308 **
309 ** IN
310 ** P_LOGFILE - logfile name
311 ** P_DIRECTORY - directory name
312 **
313 */
314 procedure PUT_NAMES(P_LOGFILE in varchar2, P_DIRECTORY in varchar2) is
315 TEMP_DIR varchar2(512);
316 begin
317
318 if (CORELOG_FNAME is null) and (P_LOGFILE is not null) then
319 CORELOG_FNAME := P_LOGFILE;
320 end if;
321
322 if UTL_DIR is null and P_DIRECTORY is null then
323 -- Then determine the utl_file_dir value.
324 select translate(ltrim(value),',',' ')
325 into TEMP_DIR
326 from v$parameter
327 where lower(name) = 'utl_file_dir';
328
329 if (instr(TEMP_DIR,' ') > 0 and TEMP_DIR is not null) then
330 select substrb(TEMP_DIR, 1, instr(TEMP_DIR,' ') - 1)
331 into UTL_DIR
332 from dual;
333 elsif (TEMP_DIR is not null) then
334 UTL_DIR := TEMP_DIR;
335 end if;
336
337 if (TEMP_DIR is null or UTL_DIR is null ) then
338 raise no_data_found;
339 end if;
340 elsif UTL_DIR is null and P_DIRECTORY is not null then
341 UTL_DIR := P_DIRECTORY;
342 end if;
343
344 if (CORELOG_OPEN = FALSE) or (CORELOG_OPEN is NULL) then
345 OPEN_FILE;
346 end if;
347
348 end PUT_NAMES;
349
350 /*
351 ** OPEN_FILE - open or create logfile
352 */
353 procedure OPEN_FILE is
354 MAX_LINESIZE binary_integer := 32767;
355 begin
356 if (CORELOG_OPEN = FALSE) or (CORELOG_OPEN is NULL) then
357 if (CORELOG_FNAME is NULL) then
358 CORELOG_FNAME := FILENAME;
359 end if;
360 CORELOG_FILE := utl_file.fopen(UTL_DIR, CORELOG_FNAME, 'a');
361 begin
362 utl_file.fclose(CORELOG_FILE);
363 exception
364 when others then
365 null;
366 end;
367 CORELOG_FILE := utl_file.fopen(UTL_DIR, CORELOG_FNAME, 'a',
368 MAX_LINESIZE);
369 CORELOG_OPEN := TRUE;
370 end if;
371 end OPEN_FILE;
372
373 /*
374 ** PUT - Put (write) text to file
375 **
376 ** IN
377 ** LOG_TEXT - Text to write
378 */
379 procedure PUT(LOG_TEXT in varchar2) is
380 begin
381 if (CORELOG_ENABLED <> 'N') and (CORELOG_ENABLED is not null) then
382 if (CORELOG_OPEN = FALSE) or (CORELOG_OPEN is NULL) then
383 OPEN_FILE;
384 end if;
385 utl_file.put(CORELOG_FILE, LOG_TEXT);
386 utl_file.fflush(CORELOG_FILE);
387 end if;
388 end PUT;
389
390 /*
391 ** PUT_LINE - Put (write) a line of text to file
392 **
393 ** IN
394 ** LOG_PROFNAME - Profile Option being monitored
395 ** LOG_TEXT - Text to write
396 */
397 procedure PUT_LINE(LOG_PROFNAME in varchar2, LOG_TEXT in varchar2) is
398 begin
399 if (LOG_PROFNAME = CORELOG_PROFILE) then
400 if (CORELOG_ENABLED <> 'N') and (CORELOG_ENABLED is not null) then
401 if (CORELOG_OPEN = FALSE) or (CORELOG_OPEN is NULL) then
402 OPEN_FILE;
403 end if;
404 utl_file.put_line(CORELOG_FILE, LOG_PROFNAME||':'||LOG_TEXT);
405 utl_file.fflush(CORELOG_FILE);
406 end if;
407 end if;
408 end PUT_LINE;
409
410 /*
411 ** PUT_LINE - Put (write) a line of text to file
412 ** Calls PUT and appends a NEW_LINE for better readability.
413 **
414 ** IN
415 ** LOG_TEXT - Text to write
416 */
417 procedure PUT_LINE(LOG_TEXT in varchar2) is
418 begin
419 PUT(LOG_TEXT);
420 NEW_LINE;
421 end PUT_LINE;
422
423 /*
424 ** NEW_LINE - Put (write) line terminators to file
425 **
426 ** IN
427 ** LINES - Number of line terminators to write
428 */
429 procedure NEW_LINE(LINES in natural := 1) is
430 begin
431 if (CORELOG_ENABLED <> 'N') and (CORELOG_ENABLED is not null) then
432 if (CORELOG_OPEN = FALSE) or (CORELOG_OPEN is NULL) then
433 OPEN_FILE;
434 end if;
435 utl_file.new_line(CORELOG_FILE, LINES);
436 utl_file.fflush(CORELOG_FILE);
437 end if;
438 end NEW_LINE;
439
440 /*
441 ** CLOSE_FILE - Close open files.
442 **
443 */
444 procedure CLOSE_FILE is
445 BEGIN
446 BEGIN
447 utl_file.fclose(CORELOG_FILE);
448 EXCEPTION
449 when others then
450 NULL;
451 END;
452 CORELOG_OPEN := FALSE;
453 end CLOSE_FILE;
454
455 /*
456 ** IS_ENABLED - returns TRUE if ENABLED <> 'N', i.e. 'Y' or 'P'
457 ** returns FALSE if ENABLED = 'N'
458 */
462 if ENABLED <> 'N' then
459 function IS_ENABLED return boolean is
460 begin
461 if CORELOG_IS_ENABLED is NULL then
463 CORELOG_IS_ENABLED := TRUE;
464 else
465 CORELOG_IS_ENABLED := FALSE;
466 end if;
467 end if;
468 return CORELOG_IS_ENABLED;
469 end IS_ENABLED;
470
471 end FND_CORE_LOG;