B4J Question Send Log() to Console from Standalone GUI App

B4XDev

Active Member
Licensed User
In the topic, Redirected console log - strange chars, code from Erel is mentioned but not linked(!).

Does anybody know the source topic to which he is referring?

I'm trying to get some debug output for a Standalone package. The app works from the IDE but not after creating a Standalone, so I need to output some debug stuff to figure out why.

Thank you!
 
Solution
This is the variant of the code above provided by @Cableguy which I use:

B4X:
Sub RedirectOutput (dir As String, FileName As String)
   #if RELEASE
    Dim out As OutputStream = File.OpenOutput(dir, FileName, True) 'Set to True to append the logs
    Dim ps As JavaObject
    ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
    Dim jo As JavaObject
    jo.InitializeStatic("java.lang.System")
    jo.RunMethod("setOut", Array(ps))
    jo.RunMethod("setErr", Array(ps))
   #end if
End Sub

then in my AppStart sub it is called by:

B4X:
            #If Test
            #Else
                RedirectOutput(PublicApplicationDataFolder, "PlayerBoardLog.txt")    ' Log file to record errors, etc.
            #End If...

Cableguy

Expert
Licensed User
Longtime User
The code is there, in the thread you linked! It creates a file with the name "filename" inside the folder "dir"

B4X:
   #if RELEASE
    Dim out As OutputStream = File.OpenOutput(Dir, filename, True) 'Set to True to append the logs
    Dim ps As JavaObject
    ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
    Dim jo As JavaObject
    jo.InitializeStatic("java.lang.System")
    jo.RunMethod("setOut", Array(ps))
    jo.RunMethod("setErr", Array(ps))
    Log("************************")
    Log("P R O G R A M  I N D U L")
    Log("************************")
   #end if

So, you could turn this into a sub when doing Logs in release mode, something like:

B4X:
    sub LogToFile(Txt as string)
    #if RELEASE
    Dim out As OutputStream = File.OpenOutput(Dir, filename, True) 'Set to True to append the logs
    Dim ps As JavaObject
    ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
    Dim jo As JavaObject
    jo.InitializeStatic("java.lang.System")
    jo.RunMethod("setOut", Array(ps))
    jo.RunMethod("setErr", Array(ps))
    Log(txt)
    #end if
End sub

Remember this is pseudo code, not tested, you will need to tweak it
 
Upvote 0

B4XDev

Active Member
Licensed User
The code is there, in the thread you linked! It creates a file with the name "filename" inside the folder "dir"

...

So, you could turn this into a sub when doing Logs in release mode, something like:

B4X:
    sub LogToFile(Txt as string)
    #if RELEASE
    Dim out As OutputStream = File.OpenOutput(Dir, filename, True) 'Set to True to append the logs
    Dim ps As JavaObject
    ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
    Dim jo As JavaObject
    jo.InitializeStatic("java.lang.System")
    jo.RunMethod("setOut", Array(ps))
    jo.RunMethod("setErr", Array(ps))
    Log(txt)
    #end if
End sub

Remember this is pseudo code, not tested, you will need to tweak it

Ah! OK, that helps. I didn't know where to put that code.

However, you're saying instead of it automatically logging to the file or console when my code calls Log(), I have to actually change all my Log() calls to LogToFile()?

Certainly there is a way to automatically redirect to the console (or a file). Right?
 
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
This is the variant of the code above provided by @Cableguy which I use:

B4X:
Sub RedirectOutput (dir As String, FileName As String)
   #if RELEASE
    Dim out As OutputStream = File.OpenOutput(dir, FileName, True) 'Set to True to append the logs
    Dim ps As JavaObject
    ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
    Dim jo As JavaObject
    jo.InitializeStatic("java.lang.System")
    jo.RunMethod("setOut", Array(ps))
    jo.RunMethod("setErr", Array(ps))
   #end if
End Sub

then in my AppStart sub it is called by:

B4X:
            #If Test
            #Else
                RedirectOutput(PublicApplicationDataFolder, "PlayerBoardLog.txt")    ' Log file to record errors, etc.
            #End If

So no need to change the Log() statements and in my case when testing by using the conditional Test, the output appears in the Log tab, but I remove that conditional when creating the standalone so the output goes to the specified file.

EDIT: Just to be clear, my code is not original but the code snippet provided by @Erel back in 2016: https://www.b4x.com/android/forum/threads/redirect-the-output-to-a-file.65165/
 
Last edited:
Upvote 0
Solution

B4XDev

Active Member
Licensed User
So no need to change the Log() statements

Excellent! It's working for me.

and in my case when testing by using the conditional Test, the output appears in the Log tab, but I remove that conditional when creating the standalone so the output goes to the specified file.

How do you specify the "conditional Test?" Does that go in the code, so you can comment it on/off when needed?

EDIT: Just to be clear, my code is not original but the code snippet provided by @Erel back in 2016: https://www.b4x.com/android/forum/threads/redirect-the-output-to-a-file.65165/

Ah, there it is! Thank you, again!
 
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
How do you specify the "conditional Test?" Does that go in the code, so you can comment it on/off when needed?

You can create different Build Configurations from the option under the Project menu (or use Ctrl B as a shortcut):

Configuration.png


In my case the app is created for several basketball clubs and so I have multiple Conditional Symbols, namely one for the club name and one for the Test configuration. As per the dialog box, you can combine multiple Conditional Symbols.

Then in the IDE you select which configuration you wish to run:

IDE.png


Here's another place in my code where I use the Conditional Symbols, as well as the log output one, which utilises the CustomBuildAction feature:

B4X:
    #If Ringwood
           #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\Ringwood\ ..\Files\ Default.png
           #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\Ringwood\ ..\Files\ config.plp
        #if Test
               #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\Ringwood\ temp\build\bin\ licence
        #Else
            #CustomBuildAction: After Packager, %WINDIR%\system32\robocopy.exe, ..\Ringwood\ temp\build\bin\ licence
        #End If
    #End If
    #if MtG
           #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\MtG\ ..\Files\ Default.png
           #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\MtG\ ..\Files\ config.plp
        #if Test
               #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\MtG\ temp\build\bin\ licence
        #Else
            #CustomBuildAction: After Packager, %WINDIR%\system32\robocopy.exe, ..\MtG\ temp\build\bin\ licence
        #End If
    #End If
    #if SWM
           #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\SWM\ ..\Files\ Default.png
           #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\SWM\ ..\Files\ config.plp
         #if Test
               #CustomBuildAction: 1, %WINDIR%\system32\robocopy.exe, ..\SWM\ temp\build\bin\ licence
        #Else
            #CustomBuildAction: After Packager, %WINDIR%\system32\robocopy.exe, ..\SWM\ temp\build\bin\ licence
        #End If
    #End If

I'm no expert in this area and learned by gathering information from this Forum together with using trial and error, but I've found it very useful.
 
Upvote 0
Top