It has been some time since I could give my donators a new goodie , and this time it will be a library/tool to profile and monitor your B4J + B4A (7.01+) apps (not limited to ABMaterial WebApps!) because I needed something like this for some time for my own projects.
Using a very simple API, you can track how long the code execution time is, the times hit, average time, memory usage etc for nearly everything you want.
NOTE: Do not forget to set your DONATORKEY in the viewer params.txt + in the apps you are monitoring!
How it works:
ABMonitor uses the Jamon library, which has a extremely low overhead on your code. Just by disabling it (using the SetActive method), you can actually leave it in your production apps if you want (or use B4Js conditional compiling if you want to get rid of it in a production app).
ABMonitor consists of two parts:
1. The 'live' ABMonitor viewer
This viewer shows all the stuff you are monitoring with the API. It shows e.g. how many times some part of your code was hit, how long it took, what the average time was, when it was last accessed, memory consumption etc...
2. The ABMonitor library.
This API connects your own apps with the monitor. It basically consists of a Start and a Stop method.
First, we have to make the connection with the Viewer. Thanks to Erels new Resumable Subs, doing this is a breeze:
In main make some declarations:
Next add the following resumable sub (the ABMonitor part is the SetActive() method):
Finally, call the sub when your app starts (a good place is e.g. before StartMessageLoop):
Ready to do some monitoring!
There are two ways to do this:
a. Monitor some code:
If for example you want to monitor a query, or a whole sub, ... In general this is a complete block of code.
Good practice is using the class/module name as the Group parameter, and the method name as the Label, but you can put whatever you want. This will later be used in the Viewer to group stuff. (Group and Label are the first and second parameters in the calls).
Example:
Or tracking a query:
b. Monitor methods which are used in multiple places, and you want to know where it was called.
You have for example a page.Refresh method, which is called in multiple places. You can use the third parameter to set the 'caller'. In general there will only be one line of code between the start() and stop().
This caller will later be used in the Viewer to build a call tree (stack trace)
Example:
As you can see, you are totally free to monitor anything you want.
Note: This is DonationWare only!
Alain
Using a very simple API, you can track how long the code execution time is, the times hit, average time, memory usage etc for nearly everything you want.
NOTE: Do not forget to set your DONATORKEY in the viewer params.txt + in the apps you are monitoring!
How it works:
ABMonitor uses the Jamon library, which has a extremely low overhead on your code. Just by disabling it (using the SetActive method), you can actually leave it in your production apps if you want (or use B4Js conditional compiling if you want to get rid of it in a production app).
ABMonitor consists of two parts:
1. The 'live' ABMonitor viewer
This viewer shows all the stuff you are monitoring with the API. It shows e.g. how many times some part of your code was hit, how long it took, what the average time was, when it was last accessed, memory consumption etc...
2. The ABMonitor library.
This API connects your own apps with the monitor. It basically consists of a Start and a Stop method.
First, we have to make the connection with the Viewer. Thanks to Erels new Resumable Subs, doing this is a breeze:
In main make some declarations:
B4X:
Sub Process_Globals
Public Monitor As ABMonitor
Private port As Int = 10090
Private ip As String = "127.0.0.1" ' <-- Set your IP!
Private abmonitor As AsyncStreams
Private client As Socket
Public TRACKMONITOR As Boolean = True
End Sub
Next add the following resumable sub (the ABMonitor part is the SetActive() method):
B4X:
Sub ConnectMonitor()
Dim c As Socket
c.Initialize("client")
c.Connect(ip, port, 5000)
Wait For Client_Connected (Successful As Boolean)
If Successful Then
client = c
abmonitor.InitializePrefix(client.InputStream, False, client.OutputStream, "abmonitor")
Log("ABMonitor connected")
Monitor.SetActive("Template", True,abmonitor, 1)
Else
Log("ABMonitor disconnected")
End If
End Sub
Sub abmonitor_Error
Monitor.SetActive("Template", False,Null, 0)
Log("ABMonitor disconnected")
End Sub
Finally, call the sub when your app starts (a good place is e.g. before StartMessageLoop):
B4X:
...
Monitor.Initialize("YOURDONATORKEY")
ConnectMonitor
StartMessageLoop
Ready to do some monitoring!
There are two ways to do this:
a. Monitor some code:
If for example you want to monitor a query, or a whole sub, ... In general this is a complete block of code.
Good practice is using the class/module name as the Group parameter, and the method name as the Label, but you can put whatever you want. This will later be used in the Viewer to group stuff. (Group and Label are the first and second parameters in the calls).
Example:
B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
If Main.TRACKMONITOR Then Main.Monitor.Start("ABMPageTemplate", "WebSocket_Connected", "")
' ... the code you want to monitor
If Main.TRACKMONITOR Then Main.Monitor.Stop("ABMPageTemplate", "WebSocket_Connected", "")
End Sub
Or tracking a query:
B4X:
...
If Main.TRACKMONITOR Then Main.Monitor.Start("ABMPageTemplate", "MySlowQuery", "")
Dim SQL_str As String
SQL_str = "SELECT cases.CaseID, cases.CaseUserID, cases.CaseType, cases.CaseSummary FROM tCases WHERE cases.CaseStatus=1;"
Dim cases As List = DBM.SQLSelect(SQL, SQL_str, Null)
If Main.TRACKMONITOR Then Main.Monitor.Stop("ABMPageTemplate", "MySlowQuery", "")
...
b. Monitor methods which are used in multiple places, and you want to know where it was called.
You have for example a page.Refresh method, which is called in multiple places. You can use the third parameter to set the 'caller'. In general there will only be one line of code between the start() and stop().
This caller will later be used in the Viewer to build a call tree (stack trace)
Example:
B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
...
If Main.TRACKMONITOR Then Main.Monitor.Start("ABMPageTemplate", "page.Refresh", "WebSocket_Connected")
page.Refresh
If Main.TRACKMONITOR Then Main.Monitor.Stop("ABMPageTemplate", "page.Refresh", "WebSocket_Connected")
...
End Sub
public Sub ConnectPage()
...
' refresh the page
If Main.TRACKMONITOR Then Main.Monitor.Start("ABMPageTemplate", "page.Refresh", "ConnectPage")
page.Refresh
If Main.TRACKMONITOR Then Main.Monitor.Stop("ABMPageTemplate", "page.Refresh", "ConnectPage")
...
End Sub
As you can see, you are totally free to monitor anything you want.
Note: This is DonationWare only!
Alain
Last edited: