B4J Question B4J Windows Event Log - Inserting entries

rgarnett1955

Active Member
Licensed User
Longtime User
Hi All,

I have a number of headless server apps written in b4J running on Windows 10 and wish to use the Windows Even Log system to log starts/stops errors etc.

I know I can develop stand alone logs for each app using text files or sqLite, but I would like to use the Windows Event Logs so everything is in one place. I use these logs a lot to work out why Windows isn't working properly (this isn't an oxymoron).

Is there any way I can do this from b4J? I don't want to read the logs with b4j, just write to the Applications Event Log.

I have attached a screen shot so you can see what I'm getting at.

Best regards

Rob
 

Attachments

  • WindowsEventViewer.png
    WindowsEventViewer.png
    316 KB · Views: 229

MicroDrie

Well-Known Member
Licensed User
You can try the following program. It doesn't need a dll, but it has one drawback: you need to create only once an log event from a dos box.
B4X:
Sub Process_Globals
    Private fx As JFX
'    Private MainForm As Form
    Private WWL As WriteWindowsLog
End Sub

Sub AppStart (Form1 As Form, Args() As String)
'    MainForm = Form1
'    MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
'    MainForm.Show
    WWL.Initialize
    WWL.WriteWindowsEvent("Test")
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
This is the class code:
B4X:
Sub Class_Globals
'    --- Needs Javaobjects
    Private NativeMe As JavaObject
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    NativeMe = Me
End Sub

Public Sub WriteWindowsEvent(buffer As String)
    Dim s As String = NativeMe.RunMethod("WriteToWindowsEventLog", Array(buffer))
    Log(s)
End Sub

#IF JAVA

/* See also https://www.jasonsamuel.com/2010/01/08/creating-a-custom-event-log-under-event-viewer-to-log-server-events/
 * The first run time an error 1 is generated to solved this error status:
 *   Open a DOS box with the CMD command in Windows
 *   Paste the following command line (without the  *) 
 *   eventcreate /ID 5 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D \"My first log\"
 */
  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
 
public void WriteToWindowsEventLog(String argument) throws IOException, InterruptedException {
    String osName = System.getProperty("os.name").toUpperCase(Locale.ENGLISH);
    if (!osName.startsWith("WINDOWS")) {
        System.err.println("Not windows");
        return;
    }
    
//    System.out.println("Windows system found");
      
// https://www.jasonsamuel.com/2010/01/08/creating-a-custom-event-log-under-event-viewer-to-log-server-events/    
// eventcreate /ID 1 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D "My first log"
    Process process = Runtime.getRuntime().exec("eventcreate /ID 5 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D \"My first log\"");

    process.waitFor(10, TimeUnit.SECONDS);
    int exitValue = process.exitValue();
    System.out.printf("Process exited with value %d\n", exitValue);
    
    if (exitValue != 0) {
        InputStream errorStream = process.getErrorStream();
        String result = new BufferedReader(new InputStreamReader(errorStream))
            .lines()
            .collect(Collectors.joining("\n"));
        System.err.println(result);
    }
}
#End If
 
Upvote 0

rgarnett1955

Active Member
Licensed User
Longtime User
You can try the following program. It doesn't need a dll, but it has one drawback: you need to create only once an log event from a dos box.
B4X:
Sub Process_Globals
    Private fx As JFX
'    Private MainForm As Form
    Private WWL As WriteWindowsLog
End Sub

Sub AppStart (Form1 As Form, Args() As String)
'    MainForm = Form1
'    MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
'    MainForm.Show
    WWL.Initialize
    WWL.WriteWindowsEvent("Test")
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
This is the class code:
B4X:
Sub Class_Globals
'    --- Needs Javaobjects
    Private NativeMe As JavaObject
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    NativeMe = Me
End Sub

Public Sub WriteWindowsEvent(buffer As String)
    Dim s As String = NativeMe.RunMethod("WriteToWindowsEventLog", Array(buffer))
    Log(s)
End Sub

#IF JAVA

/* See also https://www.jasonsamuel.com/2010/01/08/creating-a-custom-event-log-under-event-viewer-to-log-server-events/
* The first run time an error 1 is generated to solved this error status:
*   Open a DOS box with the CMD command in Windows
*   Paste the following command line (without the  *)
*   eventcreate /ID 5 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D \"My first log\"
*/
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public void WriteToWindowsEventLog(String argument) throws IOException, InterruptedException {
    String osName = System.getProperty("os.name").toUpperCase(Locale.ENGLISH);
    if (!osName.startsWith("WINDOWS")) {
        System.err.println("Not windows");
        return;
    }
   
//    System.out.println("Windows system found");
     
// https://www.jasonsamuel.com/2010/01/08/creating-a-custom-event-log-under-event-viewer-to-log-server-events/   
// eventcreate /ID 1 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D "My first log"
    Process process = Runtime.getRuntime().exec("eventcreate /ID 5 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D \"My first log\"");

    process.waitFor(10, TimeUnit.SECONDS);
    int exitValue = process.exitValue();
    System.out.printf("Process exited with value %d\n", exitValue);
   
    if (exitValue != 0) {
        InputStream errorStream = process.getErrorStream();
        String result = new BufferedReader(new InputStreamReader(errorStream))
            .lines()
            .collect(Collectors.joining("\n"));
        System.err.println(result);
    }
}
#End If


Hi MicroDrie,

Thanks for that.

I will give it a try, but I am not sure what you mean by:

you need to create only once an log event from a dos box

Could you expand on this with an example?

Best regards

Rob
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
The given program example just works with that strange first log action. I suspect it has to do with the fact that you manually establish the association between the program and the Windows event process via the CMD box operation. As with everything, try it and if it works use it as long as it goes.
 

Attachments

  • WriteToWindowsLog.zip
    2.1 KB · Views: 213
Upvote 0

Derek Johnson

Active Member
Licensed User
Longtime User
Just tried that out and your code always writes "My first Log" as per the line below:

Process process = Runtime.getRuntime().exec("eventcreate /ID 5 /L APPLICATION /T INFORMATION /SO MYEVENTSOURCE /D \"My first log\"");

[/code]

To work with the passed parameter it needs to be:

Java:
Process process = Runtime.getRuntime().exec("eventcreate /ID 5 /L APPLICATION /T INFORMATION  /SO MYEVENTSOURCE /D \"" + argument +"\""    );

Thought this might help someone else if like me you first blindly copied the example!

Derek
 
Upvote 0
Top