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