This is yet another Ping Monitor utility written in VB.NET on .NET Framework 2.0. It fulfills the need of steadily monitoring through a "PING" the status (the aliveness) of some PCs and servers on a network, keeping a history of each state transition (ON to OFF and viceversa) and visually highlighting the last status of each machine.
This application is far from being a complete and sophisticated tool. I wrote it for a colleague who needed a starting point for a more advanced and customized tool implementation.
One service, one database, one IU
In order to continuously monitor some machine, we need to have a monitoring EXE continuously runnning. So, I decided to implement the "monitor engine" as a Windows Service application (taking advantage of unattended execution, automatic restart in case of power failure, and so on). This
PingMonitorService simply has to:
- read from some configuration storage (such as a database table) the list of machines to be monitored (along with the monitoring frequency);
- execute the actual monitoring sending a "PING" to each machine configured as to be monitored;
- log the outcome of each "PING" somewhere.
Other than a Windows Service for the monitoring and a database as a storage, we obviously need also a user interface (UI) to interact with the configuration and the log; that's why I created a simple Windows Form application (named
PingMonitor) to accomplish these tasks: showing the last PING status of the monitored machines and editing the
I decided to use a SQL Server 2000 (or 2005) database to host both the configuration (that is, a list of machines to be monitored) and the log.
The following are the two table schemas, expressed in T-SQL code, with some explanations.
The configuration table
CREATE TABLE HostList (
ID int IDENTITY(1,1) NOT NULL,
Host nvarchar(50) NULL,
IsHost char(1) NULL,
ShowInMonitor char(1) NULL,
DoPing char(1) NULL,
PingFreq int NULL,
IDparent int NULL,
CONSTRAINT PK_HostList PRIMARY KEY CLUSTERED (ID ASC)
WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON PRIMARY
) ON PRIMARY
HostList table will contain the list of the machines to be monitored. For each machine, it stores: the machine name with a unique ID (
ID fields), the frenquency of monitoring (
PingFreq field, expressed in seconds), a flag indicating if the monitoring is currently activated (
DoPing field) and a flag indicating if the specific machine has to be shown in the UI (
Being able to list a hierarchycal tree enables you to organize the machines to be monitored in groups and subgroups, the
HostList table supports the concept of parent-child node relationships (via the
IDparent field) and the concept of "folder" tree nodes, that are intermediate nodes not corresponding to an host but simply being the parent of other nodes (for them, the
IsHost flag is not set to "yes").
The user interface provided by the
PingMonitor application allows you to visually edit the tree while directly modifying the underlying
HostList table (please, notice that the deletion of nodes and the addition of children nodes is allowed through the context menu on the tree).
The log table
CREATE TABLE PingLog (
Host varchar(50) NOT NULL,
Status varchar(5) NOT NULL,
RecordingDate datetime NOT NULL,
CONSTRAINT [PK_PingLog] PRIMARY KEY CLUSTERED (Host ASC, Status ASC,
WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON PRIMARY
) ON PRIMARY
PingLog table will contain an entry for each detected state transition (ON to OFF or viceversa) for each monitored machine during a monitored period of time. The
Host field contains the name of the monitored machine, the
RecordingDate field contains a timestamp of the recorded entry and the
Status field simply contains the value "ON" or "OFF" (respectively indicating a successful and an unsuccessful "PING").
Some notes about the service
PingMonitorService has been implemented on the standard Windows Service application template of Visual Studio 2005. Being a standard .NET Windows Service, it has to be installed through the installutil.exe utility (see here for reference).
When started, the service reads its CONFIG file in order to retrieve:
- the connection string to the configuration database (see
- the configuration reloading frequency (see
ReloadConfigFrequency appSetting): it indicates the number of seconds before reloading all the configuration parameters (this enables the service to adapt its behavior based on new settings in the
HostList table eventually modified by the user through the PingMonitor UI).
To determine if it's time to "PING" a machine, the service simply looks at the total number of seconds passed after midnight and checks if this number is a multiple of the specific
PingFreq for that host (notice that only status transitions are stored, not each status detection).
If CurrentSecond Mod CInt(dr("PingFreq")) = 0 Then
Dim IsAlive As Boolean = HostIsAlive(dr("Host"))
Dim LastStatus As String = HostLastStatus(dr("Host"))
If LastStatus = "" OrElse _
(LastStatus = "ON" And Not IsAlive) OrElse _
(LastStatus = "OFF" And IsAlive) Then
Notice that the polling interval in the
MainTask() is currently set to 900ms, to be sure that at least one "tick" happens for every second (obviously, it could occur twice in some seconds). If the host list is very very big, the execution of the
TryPing() method could be long enough to make the service miss some "PING" to some hosts (so please carefully configure the hosts list and the specific
The "PING" itself is done, in a very simple way, through the
Private Function HostIsAlive(ByVal Host As String) As Boolean
Dim pingSender As New Ping
Dim reply As PingReply
reply = pingSender.Send(Host)
If reply.Status = IPStatus.Success Then
Catch ex As Exception
Some notes about the UI
The UI application is very simple; it consists of two forms: the monitoring form and the configuration form.
The application needs a CONFIG file where the connection string to the support database is specified (see
The monitoring form is just a
DataGridView populated by a query on the
PingLog table; the query is designed to show only the last entry for each host having
The refresh frequency for the
DataGridView can be specified in the
ReloadFrequency appSetting of the application configuration file. Entries with an "OFF" status are highlighted by simply implementing the
CellFormatting() event handler:
Private Sub dgMonitor_CellFormatting(...)
Dim v As Object = dgMonitor.Rows(e.RowIndex).Cells("Status").Value
If v IsNot Nothing AndAlso v.ToString() = "OFF" Then
For Each i As DataGridViewCell In dgMonitor.Rows(e.RowIndex).Cells
i.Style.BackColor = Color.Orange
The configuration form contains a treeview with a detail panel, shown when a host node is selected (see the first picture in the article).
No special remarks needed on this. Just notice that the update of the underlying
HostList table is done immediately after modifying values on the UI controls, through updates on the corresponding
DataTable suddenly written down by the
As stated in the Introduction, this application is to be considered as a starting point for a more advanced and customized tool implementation. Its basic idea and implementation are intentionally very simple, hoping it can be useful for you in building something more complex.
Content of the downloadable ZIP (now available also in a C# version) for this article:
DBTablesCreation.sql file - contains the T-SQL scripts for creating support database tables on Microsoft SQL Server 2000/2005;
PingMonitorService folder - contains the Visual Studio 2005 project for the service;
PingMonitor folder - contains the Visual Studio 2005 project for the UI WinForm application.