Trace File Best Practices
Posted: 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
I've modified that code to go into a temp file change the name as such
This creates a WHOLE lot of incremented files with very little content in each file.
My question is about condensing those files into a single file by date.
For example, I can do this
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)
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
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
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
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