B4J Library [B4X] Log Server

stevel05

Expert
Licensed User
This is one of the things I've been working on. It enables multi window logging so you can organise and more easily read the logs you create in your code.

1577789610048.png



You can :
  • create multiple dockable LogAreas (windows) the last area created will become the current default.
  • SwitchTo another existing area to make that the default.
  • Send a message to a specific log area
  • Log in Color
  • Write all messages simultaneously to a file for specified LogAreas
  • Filter or Find messages in each LogArea
  • Copy messages to the clipboard (select then ctrl-c)
  • Turn on and off logging of the messages to the IDE log (LogLocal)
  • Configure the output in the Server app (Edit/UserOptions) - Font size, Background color, Port number max message and a few more.
  • Run the server app on a separate computer.

LogServerClient is now a b4xlib which should work on all platforms. It has a different name to the previous libraries to avoid confusion.

The LogServer runs on a PC (untested on a MAC but please let me know) and is provided as a jar file which you should open before running the app containing the client module. Nothing bad will happen if you run the app without opening the server first, all messages will be sent to the IDE log window, you will get a "java.net.ConnectException: Connection refused: connect." message which you can ignore.

If you lose connection while an app is running for any reason, any subsequent messages will be sent to the IDE log.


The client module depends on:
jNetwork / Network
jRandomAccessFile / RandomAccessFile
jXUI / XUI (except NonUI B4j apps)
JavaObject

Limitations:

  • This is not a replacement for the IDE log, it cannot show application errors.
  • The Gui slows down once there are about 3000 items in a LogArea, which is why the limit is initially set to that in the User Options. If you experience a slow Gui, or are running it on an old slow computer you can try limiting this further.
The Server will now accept multiple connections.

Documentation: available as Html file on dropbox


Downloads:

Examples for B4a and B4j and single b4xlib file are attached.

The LogServer jar is too big to upload to the forum, you can get it from my Dropbox here : LogServer download


Update V2:
Supports multiple connections from any platform

The library is now a distributed as a B4xlib and should work on b4j, b4a and b4i as I have removed threading and java specific code.

The only downside is that if you send a lot of messages while the device is connecting, they are handled by a timer instead of a thread, which makes the updates a little slower. To negate this, there is a Stream_Ready callback that will fire when the stream is ready, if you wait for that as in the examples, then the slow down will not occur.

Update V2.10 Client library Updated to work with Non_UI apps in Java 9+

Update V2.2


  • Added ServertimeStamp
  • Added CircularProgressBar - Erel's Circular Progress Bar
  • Added TimePlot - Based on Klaus's xChart V4.2
  • Added LedMatrix
  • Added HexView
  • Improved tcp connection process
  • Added IsConnected method to LogServerClient

Don't forget to download the new version of LogServer.jar from the Dropbox link above and set the IP address of the server in b4a / b4i and also in b4j if you are running the server on a different computer.

If you test it on B4i, please let me know the results.


Please try it out and let me know how you get on with it.

Enjoy.
 

Attachments

Last edited:

stevel05

Expert
Licensed User
Found some instability in the method used to access the synchronised list when a very high volume of messages were being sent, this has been fixed, please download the example and or Library again.
 

stevel05

Expert
Licensed User
LogServer v0,2 Fixes a small bug in the display and selection of lists. Available at the above link.
 

stevel05

Expert
Licensed User
Thanks Peter, I use it on most of my projects, it makes tracking multiple data changes pretty simple.
 

stevel05

Expert
Licensed User
LogServer v2.0

Allows multiple connections from any platform to the server at the same time.
Removes threading and java specific calls so hopefully it will work with B4i.
 

IslandMedic

Member
Licensed User
when I try to implement the b4j client into my NON UI server application I get the following error:

B4J Version: 8.00
Java Version: 11
Parsing code. (0.01s)
Building folders structure. (0.00s)
Compiling code. (0.07s)
Compiling layouts code. (0.00s)
Organizing libraries. (0.00s)
Compiling generated Java code. Error
B4J line: 64
LS.DefaultColor = fx.Colors.Black
src\b4j\example\main.java:156: error: cannot access Paint
_ls._setdefaultcolor((Object)(_fx.Colors.Black));
^
class file for javafx.scene.paint.Paint not found

I have loaded all the libs that the client example has loaded. I am just wondering if this only works in a UI environment?

Brad
 

stevel05

Expert
Licensed User
Hi Brad,

The LogServerClient does not use the FX library, the error you are referring to is caused by the code in the example which will not run in a non UI app because of the lack of the FX library.

You can change any references to fx.Colors and simply enter the colours as Ints and it will work. So the
B4X:
LS.DefaultColor = fx.Colors.Black
Becomes
B4X:
LS.DefaultColor = 0xFF000000
And

B4X:
LS.DefaultColor = fx.Colors.Blue
Becomes

B4X:
LS.DefaultColor = 0xFF0000FF
etc.
 
Last edited:

stevel05

Expert
Licensed User
You can add these constants to your code if you want to, they will be in the next release of the logserver client:
B4X:
Public Const INTCOLOR_BLACK As Int = 0xFF000000
    Public Const INTCOLOR_BLUE As Int = 0xFF0000FF
    Public Const INTCOLOR_CYAN As Int = 0xFF00FFFF
    Public Const INTCOLOR_DARKGRAY As Int = 0xFF444444
    Public Const INTCOLOR_GRAY As Int = 0xFF808080
    Public Const INTCOLOR_GREEN As Int = 0xFF00FF00
    Public Const INTCOLOR_LIGHTGRAY As Int = 0xFFD3D3D3
    Public Const INTCOLOR_MAGENTA As Int = 0xFFFF00FF
    Public Const INTCOLOR_RED As Int = 0xFFFF0000
    Public Const INTCOLOR_TRANSPARENT As Int = 0x00000000
    Public Const INTCOLOR_WHITE As Int = 0xFFFFFFFF
    Public Const INTCOLOR_YELLOW As Int = 0xFFFFFF00
 
Last edited:

themr23

Member
Licensed User
Steve, a very useful utility. Thank you.
Please could you provide an IsConnected to the client, and assure it returns false after loss of server connection?
Alternatively you could provide an event.
Thanks.
 

stevel05

Expert
Licensed User
Please could you provide an IsConnected to the client
I thought this would be simple, but it seems that the amendments to make the server accept multiple connections have changed the way it works. I will let you know. The answer will be yes, but I want to make sure it's done correctly.
 

IslandMedic

Member
Licensed User
failed to remove existing native library file: C:\Users\I59100~1\AppData\Local\Temp\sqlite-unknown-sqlitejdbc.dll

I am guessing that there is a conflict between the sqllite driver I am using and the one you are? Here is what I am using

#Region Project Attributes
#CommandLineArgs:
#MergeLibraries: true
#AdditionalJar: sqlite-jdbc-3.7.2
#AdditionalJar: bcprov-jdk15on-159
'Version Dec 22 2019 1736

#End Region
 

IslandMedic

Member
Licensed User
ok the SQLlite error went away and I am not sure why but when I run my code in release mode I get the following. In the next message I will post the errors in debug mode.

B4X:
2019-12-23 09:33:06.824:INFO::main: Logging initialized @164ms to org.eclipse.jetty.util.log.StdErrLog
2019-12-23 09:33:06.976:INFO:eek:ejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2018-05-03T15:56:21.710Z; git: daa59876e6f384329b122929e70a80934569428c; jvm 11.0.1+13
2019-12-23 09:33:07.007:INFO:eek:ejs.session:main: DefaultSessionIdManager workerName=node0
2019-12-23 09:33:07.007:INFO:eek:ejs.session:main: No SessionScavenger set, using defaults
2019-12-23 09:33:07.008:INFO:eek:ejs.session:main: node0 Scavenging every 600000ms
2019-12-23 09:33:07.029:INFO:eek:ejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@3b0090a4{/,file:///D:/Android%20Programing/Ziggy%20Server%20b4j/Objects/www,AVAILABLE}
2019-12-23 09:33:07.032:INFO:eek:ejs.AbstractNCSARequestLog:main: Opened D:\Android Programing\Ziggy Server b4j\Objects\logs\b4j-2019_12_23.request.log
2019-12-23 09:33:07.124:INFO:eek:ejs.AbstractConnector:main: Started ServerConnector@6236eb5f{HTTP/1.1,[http/1.1]}{0.0.0.0:51042}
2019-12-23 09:33:07.124:INFO:eek:ejs.Server:main: Started @469ms
Messaging Server Ready
java.lang.NoClassDefFoundError: javafx/scene/Node
    at b4j.example.logserverclient._class_globals(logserverclient.java:180)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at b4j.example.logserverclient.innerInitialize(logserverclient.java:22)
    at b4j.example.logserverclient._initialize(logserverclient.java:500)
    at b4j.example.main$ResumableSub_AppStart.resume(main.java:130)
    at b4j.example.main._appstart(main.java:71)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
    at b4j.example.main.main(main.java:28)
Caused by: java.lang.ClassNotFoundException: javafx.scene.Node
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 17 more
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:111)
    at b4j.example.logserverclient.innerInitialize(logserverclient.java:22)
    at b4j.example.logserverclient._initialize(logserverclient.java:500)
    at b4j.example.main$ResumableSub_AppStart.resume(main.java:130)
    at b4j.example.main._appstart(main.java:71)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
    at b4j.example.main.main(main.java:28)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:496)
    at anywheresoftware.b4a.keywords.Common.CallSubNew3(Common.java:450)
    at anywheresoftware.b4a.BA.handleUncaughtException(BA.java:164)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:108)
    ... 11 more
Caused by: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:120)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:487)
    ... 14 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at b4j.example.logserverclient._messagecolorto(logserverclient.java:629)
    at b4j.example.logserverclient._messageto(logserverclient.java:646)
    at b4j.example.main._application_error(main.java:63)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    ... 15 more
main.main (java line: 28)
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:111)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
    at b4j.example.main.main(main.java:28)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:496)
    at anywheresoftware.b4a.keywords.Common.CallSubNew3(Common.java:450)
    at anywheresoftware.b4a.BA.handleUncaughtException(BA.java:164)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:108)
    ... 2 more
Caused by: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:120)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:487)
    ... 5 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at b4j.example.logserverclient._messagecolorto(logserverclient.java:629)
    at b4j.example.logserverclient._messageto(logserverclient.java:646)
    at b4j.example.main._application_error(main.java:63)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    ... 6 more
 
Last edited:

IslandMedic

Member
Licensed User
B4X:
Waiting for debugger to connect...
Program started.
2019-12-23 09:35:24.159:INFO::main: Logging initialized @794ms to org.eclipse.jetty.util.log.StdErrLog
2019-12-23 09:35:24.307:INFO:eek:ejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2018-05-03T15:56:21.710Z; git: daa59876e6f384329b122929e70a80934569428c; jvm 11.0.1+13
2019-12-23 09:35:24.334:INFO:eek:ejs.session:main: DefaultSessionIdManager workerName=node0
2019-12-23 09:35:24.335:INFO:eek:ejs.session:main: No SessionScavenger set, using defaults
2019-12-23 09:35:24.336:INFO:eek:ejs.session:main: node0 Scavenging every 600000ms
2019-12-23 09:35:24.355:INFO:eek:ejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@41fecb8b{/,file:///D:/Android%20Programing/Ziggy%20Server%20b4j/Objects/www,AVAILABLE}
2019-12-23 09:35:24.359:INFO:eek:ejs.AbstractNCSARequestLog:main: Opened D:\Android Programing\Ziggy Server b4j\Objects\logs\b4j-2019_12_23.request.log
2019-12-23 09:35:24.443:INFO:eek:ejs.AbstractConnector:main: Started ServerConnector@1b3ba5ea{HTTP/1.1,[http/1.1]}{0.0.0.0:51042}
2019-12-23 09:35:24.443:INFO:eek:ejs.Server:main: Started @1082ms
Emulated network latency: 200ms
Messaging Server Ready
Error occurred on line: 3 (LogServerClient)
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at b4j.example.logserverclient.innerInitialize(logserverclient.java:21)
    at b4j.example.logserverclient._initialize(logserverclient.java:85)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
    at b4j.example.main.main(main.java:29)
Caused by: java.lang.NoClassDefFoundError: javafx/scene/Node
    at b4j.example.logserverclient._class_globals(logserverclient.java:427)
    ... 21 more
Caused by: java.lang.ClassNotFoundException: javafx.scene.Node
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 22 more
Program terminated (StartMessageLoop was not called).
 
Last edited:

IslandMedic

Member
Licensed User
FYI I have successfully run your app in my UI client app. So I am guessing this is all about the UI vs NON-UI environment.
 

stevel05

Expert
Licensed User
I have successfully run it in a NonUI app on my PC, but I get the feeling you may have a different setup
 
Top