DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_CORE_LOG

Source


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;