I made a test project of Tracing to Debug (download at end) to send to SV to show how ugly Debug was with extra blank lines and short lines compared to the Text file that does not have the ugliness.
Below is a screen cap with Debug on the Left and Text file on the right to show the ugliness. It also provides a sample of what you get in the tracing output including PROP:Details and PROP:LogSQL
Below is the code that made the above. It does a variety of file access commands to see what comes out as Prop:Details and Prop:LogSQL. Project download at the end.
!Test PROP:Profile='DEBUG:' to send Profile to Debug View instead of a disk file
!Can also send to Disk file to compare the otuput to DEBUG and see how Debug is UGLY.
!Also tests various file ops with PROP:Profile to see what you get in the output
!
!IMO the DEBUG: output is Not formatted as nicely as the file logging. Its UGLY UGLY UGLY
! It has like breaks before the "Time Taken", and also inserts BLANK lines so is DOUBLE SPACED.
! I think PROP:LOG has some limitations if you try to do multiple calls to it without a file op???
!Help: https://clarion.help/doku.php?id=prop_profile.htm
!Help: https://clarion.help/doku.php?id=prop_profile_1.htm
!==========================================================================================
PROGRAM
MAP
TestProfile_AskMessage PROCEDURE() !Message to Ask if Log to Debug or File
TestProfile_FileCode PROCEDURE() !File Code to be Logged
END
!The use of {PROP:Profile}='DEBUG:' is not well documented appearing only in topic "Debugging your SQL application"
Profile:OutputDebugString EQUATE('DEBUG:') !Use with PROP:Profile to send to OutputDebugString()
Profile:LogFileName EQUATE('ProfileLog_SQL_ToFILE.TXT')
MyFile1 FILE,DRIVER('SQLite'),PRE(MyF1), BINDABLE,CREATE,THREAD,OWNER('MyFile1.SQL')
KeyByID KEY(MyF1:ID),PRIMARY
KeyByDate KEY(MyF1:Date),DUP,OPT
Record RECORD,PRE()
ID SHORT !MyF1:ID
Name STRING(20) !MyF1:Name
Date LONG !MyF1:Date
END
END
CODE
IF 0 THEN !1=Test Profile without UI, a way to test my DbFileAccessON() function
DbFileAccessON(MyFile1) !Easy Call to Debug File Access to MyFile1 using PROP:Profile='DEBUG:'
TestProfile_FileCode() !
DbFileTurnOFF(MyFile1)
ELSE
TestProfile_AskMessage() !Message to allow Profile to DEBUG or FILE
END
RETURN
!-------------------------------------------
TestProfile_AskMessage PROCEDURE()
Profile2 PSTRING(256)
CODE
CASE Message('Test PROP:Profile=DEBUG: ' & |
'||Profile with OutputDebugString or File?' & |
'||CLA Library ' & system{PROP:LibVersion,2} &'.'& system{PROP:LibVersion,3} & |
'||Do you have Debug View running?', |
'Profile 2 Debug - SQLite',ICON:Clarion, |
'Profile=DEBUG:|File: '& Profile:LogFileName & '|Do Not Log|Halt')
OF 1 ; Profile2 = Profile:OutputDebugString !Secret word 'DEBUG:'. Can be any case
OF 2 ; Profile2 = Profile:LogFileName !Disk File Logging
REMOVE(Profile2) ! Do not append
OF 3 ; Profile2 = '' !Do Not Log
OF 4 ; HALT
END
MyFile1{PROP:Profile} = Profile2 ! Filename to write profiling of all File I/O calls and errors returned by the file driver
MyFile1{PROP:Details} = 1 ! True = Driver to include Record Buffer contents **
MyFile1{PROP:LogSQL} = 1 ! True = Turns ON logging of calls to the backend for SQL drivers
TestProfile_FileCode()
RETURN
!-------------------------------------------
TestProfile_FileCode PROCEDURE()
CODE
!Message('PROP:Profile=' & MyFile1{PROP:Profile} &'|PROP:Details=' & MyFile1{PROP:Details},'Profile PROPs') !Debug Message
MyFile1{PROP:Log}='##### TestProfile_FileCode -- ' & |
FORMAT(TODAY(),@d3) &' '& FORMAT(CLOCK(),@t6) &' -- ' & |
'PROP:LibVersion: '& system{PROP:LibVersion,2} &'.'& system{PROP:LibVersion,3} &' #####'
REMOVE('MyFile1.SQL') !Simply get rid of this SQL DB Disk File so Create cannot have issue for Driver
!Perform some file actions to Log
CREATE(MyFile1)
IF ErrorCode() THEN Message('CREATE(MyFile1) failed '& ErrorCode()&' '&Error(),'Profile2Dbg').
OPEN(MyFile1)
IF ErrorCode() THEN Message('OPEN(MyFile1) failed '& ErrorCode()&' '&Error(),'Profile2Dbg').
!A Mix of File Access Commands to see the LOG
MyFile1{PROP:Log}='##### ADD 4 Records #####'
CLEAR(MyFile1)
LOOP 4 TIMES
MyF1:ID += 1
MyF1:Name = 'Test Add ' & MyF1:ID
MyF1:Date = TODAY() + CHOOSE(MyF1:ID % 2 = 0,-33,44) * MyF1:ID
ADD(MyFile1)
END
MyFile1{PROP:Log}='##### SET to ID=3 then NEXT to EOF #####'
CLEAR(MyF1:Record,-1)
MyF1:ID = 3 !See records 3 and 4
SET(MyF1:KeyByID,MyF1:KeyByID)
LOOP
NEXT(MyFile1) ; IF ERRORCODE() THEN BREAK.
END
MyFile1{PROP:Log}='##### SET to KeyByDate then PREVIOUS #####'
SET(MyF1:KeyByDate)
LOOP
PREVIOUS(MyFile1) ; IF ERRORCODE() THEN BREAK.
END
MyFile1{PROP:Log}='##### GET ID=4 then DELETE #####'
MyF1:ID = 4
GET(MyFile1,MyF1:KeyByID)
DELETE(MyFile1)
!Try to GET and DELETE 4 again which WILL FAIL, see what Debug shows
MyFile1{PROP:Log}='##### Repeat GET(,4) and DELETE ... that will FAIL #####'
CLEAR(MyFile1) ; GET(MyFile1,0)
MyF1:ID = 4
GET(MyFile1,MyF1:KeyByID)
DELETE(MyFile1)
CLOSE(MyFile1)
MyFile1{PROP:Log}='##### End of TestProfile_FileCode #####'
RETURN
These were the little functions I made to wrap the setting the PROP’s needed. You could reuse these in your own code.
!==============================================================================
! Functions to make it easy to turn On/Off Profile going to Debug
!==============================================================================
MAP
DbFileAccessON PROCEDURE(*FILE File2Debug, BOOL DetailsOfRecord=True, BOOL SqlBackendCalls=True, <STRING DiskFileLogName>) !Turn ON PROP:Profile File Logging
DbFileComment PROCEDURE(*FILE FileDebuging, STRING Comment2Log) !Write Debug Comment to File Profile LOG
DbFileTurnOFF PROCEDURE(*FILE File2NotDebug) !Turn OFF PROP:Profile File Logging
END
DbFileAccessON PROCEDURE(*FILE File2Debug, BOOL DetailsOfRecord=True, BOOL SqlBackendCalls=True, <STRING DiskFileLogName>) !Turn ON PROP:Profile File Logging
CODE
IF ~OMITTED(DiskFileLogName) AND DiskFileLogName THEN !Idea: Could pass AppendFlag=1 then If =0 Remove(LogFile)
File2Debug{PROP:Profile} = DiskFileLogName ! Filename to write profiling of all File I/O calls and errors returned by the file driver
ELSE
File2Debug{PROP:Profile} = 'DEBUG:' ! DebugView /Debugger gets Profiling
END
File2Debug{PROP:Details} = DetailsOfRecord ! True = Driver to include Record Buffer contents **
File2Debug{PROP:LogSQL} = SqlBackendCalls ! True = Turns ON logging of calls to the backend for SQL drivers
RETURN
DbFileComment PROCEDURE(*FILE FileDebuging, STRING Comment2Log) !Write Debug Comment to File Profile LOG
CODE
FileDebuging{PROP:LOG} = Comment2Log
RETURN
DbFileTurnOFF PROCEDURE(*FILE File2NotDebug) !Turn OFF PROP:Profile File Logging
CODE
File2NotDebug{PROP:Profile} = ''
RETURN
!==============================================================================
Test projects download for TPS and SQL which uses SQLite, so anyone can run it no server needed.
PROFILE_TestProject_UglyDebugOutput.ZIP (10.0 KB)