Trace File Best Practices

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
jyoung
Posts: 635
Joined: Thu Jan 21, 2016 6:43 am
Location: Oklahoma City, OK USA

Trace File Best Practices

Post by jyoung » Thu Jul 11, 2019 3:58 am

When using a trace handler that implements #PRIM_APP.iTraceHandler the example the docs show uses an incrementing file counter.

Something like this

Code: Select all

Mthroutine Name(GetNextFile) Access(*Private)
Define_Map For(*Result) Class(#Prim_alph) Name(#Result)
Define_Com Class(#prim_nmbr) Name(#Extension)
Begin_Loop Using(#Extension)
#Result := *Sys_dir + "UserTrace" + "." + #Extension.asstring.rightAdjust( 3 "0" )
Leave If(*Not #Com_owner.FileExists( #Result ))
End_Loop
Endroutine
I've modified that code to go into a temp file change the name as such

Code: Select all

mthroutine name(GetNextFile) access(*PRIVATE)
 define_map for(*RESULT) class(#PRIM_ALPH) name(#Result)
 define_com class(#PRIM_NMBR) name(#Extension)

 begin_loop using(#Extension)
  #Result := *TEMP_DIR + "API-Trace." + *YYYYMMDD.AsString + "." + #Extension.asstring.RightAdjust( 3 "0" ) + ".txt"
  leave if(*Not #Com_owner.FileExists( #Result ))
 end_loop
endroutine
This creates a WHOLE lot of incremented files with very little content in each file.
Capture.PNG
Capture.PNG (66.73 KiB) Viewed 46 times
My question is about condensing those files into a single file by date.
For example, I can do this

Code: Select all

mthroutine name(GetNextFile) access(*PRIVATE)
    define_map for(*RESULT) class(#PRIM_ALPH) name(#Result)

    #Result := *TEMP_DIR + "API-Trace" + "." + *YYYYMMDD.AsString + ".txt"
endroutine
And I can easily view all the logs for a specific date.

The question is should I do this?

Is there any benefit from having a file increment?

Its much easier to have a single file to look thru then having to go to each file; however are there unseen drawbacks to this approach?

Thanks,
Joe

Edit

For completeness, here is the entire trace handler. In this case I can turn on/off tracing via a System Variable (*APITRACE)

Code: Select all

* =================================================================================================================
*
* API SERVER SIDE TRACE HANDLER
*
* Enables trace output on server side objects.
* Tracing is toggled via the LANSACFG/TRACE data area
* Trace files are written to *TEMP_DIR, typically
*     IBM i - /lansa_devpgmlib/x_lansa/tmp
*     Windows - C:\Windows\Temp
* Trace files are named API-Trace.YYYYMMDD.99.text

* -----------------------------------------------------------------------------------------------------------------
* TO USE:
*
* Define this component in your object with application scope
* define_com class(#APITraceHandler) scope(*APPLICATION)
*
* Enable tracing by setting the TRACE/LANSACFG data area to 'YES'

function options(*DIRECT)
begin_com role(*EXTENDS #PRIM_OBJT *implements #PRIM_APP.iTraceHandler)

define field(#FileHandle) type(*DEC) length(3) decimals(0)
define_com class(#PRIM_ALPH) name(#Tab)

evtroutine handling(#COM_OWNER.CreateInstance)
#Tab := (09).asChar
#COM_OWNER.InstallTracing
endroutine

mthroutine name(InstallTracing) help('Plug in the trace handler to the Application') access(*PRIVATE)
if (*APITRACE = "YES")
#SYS_APPLN.TraceHandler <= #COM_OWNER
endif

endroutine

mthroutine name(Initialize) options(*REDEFINE) access(*PRIVATE)
#COM_OWNER.OpenTraceFile
endroutine

mthroutine name(Terminate) options(*REDEFINE) access(*PRIVATE)
#COM_OWNER.CloseTraceFile
endroutine

mthroutine name(TraceMessage) help('Executed whenever #SYS_APPLN.TraceMessageData or #SYS_APPLN.TraceMessageText is used') options(*REDEFINE) access(*PRIVATE)
#COM_OWNER.WriteToFile( #ComponentName #Description #LineNumber #MessageText )
endroutine

mthroutine name(OpenTraceFile) help('Create a new trace outputfile') access(*PRIVATE)
use builtin(STM_FILE_OPEN) with_args(#COM_OWNER.GetNextFile "APPEND" "N" "Y") to_get(#FileHandle #IO$STS)
endroutine

mthroutine name(WriteToFile) help('Write an entry in the trace output file') access(*PRIVATE)
define_map for(*INPUT) class(#PRIM_ALPH) name(#ComponentName)
define_map for(*INPUT) class(#PRIM_ALPH) name(#Description)
define_map for(*INPUT) class(#PRIM_NMBR) name(#LineNumber)
define_map for(*INPUT) class(#PRIM_ALPH) name(#MessageText)

define_com class(#PRIM_DAT) name(#Now)

#MessageText := #Now.now.AsLocalizedDateTime.AsString + #Tab + #ComponentName + #Tab + #LineNumber.asstring + #Tab + #MessageText

use builtin(STM_FILE_WRITE) with_args(#FileHandle #MessageText) to_get(#IO$STS)
endroutine

mthroutine name(CloseTraceFile) access(*PRIVATE)
use builtin(STM_FILE_CLOSE) with_args(#FileHandle) to_get(#IO$STS)
endroutine

mthroutine name(TracingState) options(*REDEFINE)
#MessageTracingActive := True
endroutine

mthroutine name(GetNextFile) access(*PRIVATE)
define_map for(*RESULT) class(#PRIM_ALPH) name(#Result)

#Result := *TEMP_DIR + "API-Trace" + "." + *YYYYMMDD.AsString + ".txt"
endroutine

* mthroutine name(GetNextFile) access(*PRIVATE)
* define_map for(*RESULT) class(#PRIM_ALPH) name(#Result)
* define_com class(#PRIM_NMBR) name(#Extension)
*
* begin_loop using(#Extension)
* #Result := *TEMP_DIR + "API-Trace." + *YYYYMMDD.AsString + "." + #Extension.asstring.RightAdjust( 3 "0" ) + ".txt"
* leave if(*Not #Com_owner.FileExists( #Result ))
* end_loop
* endroutine

mthroutine name(FileExists) access(*PRIVATE)
define_map for(*INPUT) class(#PRIM_ALPH) name(#Path)
define_map for(*RESULT) class(#PRIM_BOLN) name(#Result)

use builtin(OV_FILE_SERVICE) with_args("CHECK_FILE" #Path) to_get(#io$sts)
#Result := (#io$sts = "OK")
endroutine
end_com


Post Reply