How do I make b4jserver display the error and debug logs in an html page with b4j_ws.js instead of having to open the vps server every time to see the errors?
the idea is to make a panel to monitor the logs online
On the chat example. Erel shows how to store Websockets sessions in a map. Those being able to call them whenever an event happens.
The idea is simple.
Create a ThreadSafeMap
Add the session to this map
Every time an error occurs, call a function asynchronously triggering an updated on such websocket session
by Asynchronous i mean CallsubDelayed
The basic idea that I deploy with all of my B4J servers is to ...
- Direct all log information to a file. It's a simple command.
- On the webpage (each server has its' own admin.htm page for this and other things), setup a simple text area that'll show the log.
- In the B4J websocket class for that page, read the log file and put that string into the text area.
There's lots of customization that you can employ, such as just showing the last x number of lines and make that configurable. If you're interested, I can pull some code snippets out of one of the servers tomorrow and post them here.
A more detailed way of going about it, and one that really helps with monitoring multiple servers at once, is to direct all logging to a database and then display these lines in an html datatables table. But, the first one is just fine for basic log monitoring.
Your idea is good but you are actually creating a bottleneck (assuming you create the file in the same thread as the websocket/handler) this is because a file can't be written by 2 different threads so most likely the OS is qeueing the writes and therefore there is a delay or you may get a corrupt file form time to time.
To prevent this Jserver allows you to create a same thread handlers, specifically for IO and burdensome operations.
In Main.AppStart, just before initializing the jServer, I call:
B4X:
Sub RedirectOutputToFile (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
In the B4J wsAdmin websocket class, within the WebSocket_Connected sub, I'll call...
B4X:
Sub ShowServerLog
' Server Log
ServerLogNumberOfLines.SetVal(ShowServerLogLines)
If File.Exists(File.DirApp & "logs", "logs.txt") = True Then
Dim sb As StringBuilder : sb.initialize
Dim List1 As List = File.ReadList(File.DirApp & "logs", "logs.txt")
If List1.Size-1 > = ShowServerLogLines Then
Dim start As Int = List1.Size - 1 - ShowServerLogLines
Else
Dim start As Int = 0
End If
Dim finish As Int = List1.Size - 1
For i = start To finish
sb.Append(List1.Get(i) & CRLF)
Next
ServerLog.SetVal(sb.ToString)
End If
End Sub
In your code, you just use the same log() call that you use in normal debugging for the java system to automatically write to your log file. Errors, warnings, and crashes get sent there, too. You don't have to do anything special.
This is a very basic way of showing your log file on a webpage so that you might be able to see what's going on without having to logon to the (hardware) server.
Your idea is good but you are actually creating a bottleneck (assuming you create the file in the same thread as the websocket/handler) this is because a file can't be written by 2 different threads so most likely the OS is qeueing the writes and therefore there is a delay or you may get a corrupt file form time to time.
To prevent this Jserver allows you to create a same thread handlers, specifically for IO and burdensome operations.
This is the correct answer, in Jserver we use database pooling effectively making the whole transaction asynchronous
As you can see in my previous post, I'm letting the Java system do the logging automatically instead of what you were assuming I was doing: opening/writing a file from each websocket connection. Is there a delay anyway? Could be. Can't say that any of our admin staff (that monitors these) has ever complained about a delay. The customer-facing UI doesn't seem to be affected. I know that there's never been a corrupt file (5+ years, over 2 dozen B4J servers since the beginning, and thousands of daily constant users during that time), though.
In programming, there are very few absolute "correct answer"s. There are, however, a whole lot of "different answers", depending on the needs at the time. Is what I offered above a very flexible solution? No. Logging to a database is more flexible, yes. Especially if you're monitoring multiple servers from one location or running analysis on those logs, which is what our staff does now. But, that's no more "correct" than someone that simply wants to be able to see their logs on a webpage.