'Services Stuff
Imports System
Imports System.ServiceProcess
Imports System.Diagnostics
Imports System.Threading
' XML
Imports System.IO
Imports System.Xml
'Email
Imports System.Net.Mail
Public Class TKRuPerformWatchDog
'-------------------------------------------------------------------------
'Global Variables
'-------------------------------------------------------------------------
' The IDOL server to monitor and the local Windows Service to Start.
' (Manual changes in this section.)
'-------------------------------------------------------------------------
Dim strGetStatusPage As String = "http://ctnhupidold:9000/action=getstatus" '- -Test
Dim strServiceToControl As String = "Vignette Collaboration"
'Dim strGetStatusPage As String = "http://ctnhupidolp:9000/action=getstatus" '-- Production
'Dim strGetStatusPage As String = "http://ctnhhriis02/testxml.xml"
'Dim strServiceToControl As String = "Telnet"
'-------------------------------------------------------------------------
' Major Error Reporting (Manual changes in this section.)
'-------------------------------------------------------------------------
Dim strFromEmailAddress As String = "uperformadmn@somewhere.com"
Dim strGroupRecepientEmailAddress As String = "uperformadmn@somewhere.com"
Dim strCCEmailAddress As String = "hughesdo@somewhere.com"
Dim strBCCEmailAddress As String = "3308675309@vtext.com"
'-------------------------------------------------------------------------
Dim strPreviousStatus As String = "NOSTATUS"
Dim intJustStartingAttempts As Int64 = 0
Dim intNetworkHiccupCNT As Int64 = 0
'-------------------------------------------------------------------------
'Timers
Private oTimer1 As System.Threading.Timer ' JustStartingTimer
Private oTimer2 As System.Threading.Timer ' ContinuousMonitorTimer
'-------------------------------------------------------------------------
Protected Overrides Sub OnStart(ByVal args() As String)
'----------------------------------------------------------------------------------------
' Code to start the service as two separate timers.
'
' The Just Getting Started Timer is impatient and expects that the IDOL server will start
' without any problems. The Just Getting Started is run first when this computer is rebooted.
'
' The Continuous Monitor Timer knows that services had been running and therefore it only
' checks if everything is still running every 1/2 hour or so. It is very cautious not
' to think things have gone down and to really tests that things are bad before restarting
' local windows services.
'----------------------------------------------------------------------------------------
WriteToEventLog("Root of the application start. This occurs at restart and initial start of the service (reboot).", "tkruPerformWatchDog ", _
EventLogEntryType.Warning, "System")
Dim oCallback As New TimerCallback(AddressOf JustStartingTimerEvent)
oTimer1 = New System.Threading.Timer(oCallback, Nothing, 3000, 30000) ' Three second wait and every thirty seconds there after.
Dim oCallback2 As New TimerCallback(AddressOf ContinuousMonitorTimerEvent)
oTimer2 = New System.Threading.Timer(oCallback2, Nothing, Timeout.Infinite, Timeout.Infinite) ' Do NOT start this timer yet. Just Getting Started should start it.
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
WriteToEventLog("Stopped: " & DateTime.Now, "tkruPerformWatchDog ", _
EventLogEntryType.Information, "System")
oTimer1.Dispose()
oTimer2.Dispose()
End Sub
Private Sub JustStartingTimerEvent(ByVal state As Object)
'+-------------------------------------------------------------------------------
' Go check the status on the IDOL server
'+-------------------------------------------------------------------------------
Dim myPage As String = readHtmlPage(strGetStatusPage)
Dim strCurrentStatus = GetStatus(myPage)
If strCurrentStatus = "SUCCESS" Then
Dim sc As New ServiceController(strServiceToControl.ToString)
If sc.Status.Equals(ServiceControllerStatus.Stopped) Or sc.Status.Equals(ServiceControllerStatus.StopPending) Then
sc.Start()
sc.Refresh() ' Refresh and display the current service status.
'------------------------------------------------------
'Switch timers and change gears into ContinuousMonitor
'------------------------------------------------------
oTimer1.Change(Timeout.Infinite, Timeout.Infinite) ' Pause the "JustStartingTimer" indefinitely. It will be restarted!
oTimer2.Change(300000, 1800000) ' Start the ContinuousMonitorTimer
'oTimer1.Dispose() ' Get rid of this timer we completed our just starting.
WriteToEventLog("The tkruPerformWatchDog has saved the day and started services normally.", "tkruPerformWatchDog ", _
EventLogEntryType.SuccessAudit, "System")
Else
'Our local Services ARE started and the IDOL server responed with "SUCCESS" everything is good.
If sc.Status.Equals(ServiceControllerStatus.Running) Or sc.Status.Equals(ServiceControllerStatus.StartPending) Then
'------------------------------------------------------
'Switch timers and change gears into ContinuousMonitor
'------------------------------------------------------
oTimer1.Change(Timeout.Infinite, Timeout.Infinite) ' Pause the timer indefinitely. It will be restarted!
oTimer2.Change(300000, 1800000) ' Start the ContinuousMonitorTimer
'oTimer1.Dispose() ' Get rid of this timer we completed our just starting.
End If
End If
Else
'------------------------------------------------------------------------------------------------------
'The IDOL server is NOT responding with "SUCCESS" yet so continue this timer.
'
'Unless...
'This timer continues to wait. but after so many attempts it will send out a email/pager.
'
'Start counting our attempts.
'------------------------------------------------------------------------------------------------------
intJustStartingAttempts = intJustStartingAttempts + 1
'------------------------------------------------------------------------------------------------------
'This is called every 30 seconds so twice that multiplied by 60 = times called per hour.
' (30 * 2 * 60) = 3600 times in a hour and we just stated this portion time to email someone?
'------------------------------------------------------------------------------------------------------
If intJustStartingAttempts = 3600 Then
'Log it.
WriteToEventLog("Waiting for one hour but never found SUCCESS. ", "tkruPerformWatchDog ", _
EventLogEntryType.Error, "System")
'------------------------------------------------------------------------------------------------------------------
' Send a email Just one time.
' The counter will increment above the 3600 point and this email should never happen again.
' If intNetworkHiccupCNT > 0 then obviously I failed in the ContinuousMonitor too and fell into the JustStarting loop.
'------------------------------------------------------------------------------------------------------------------
If intNetworkHiccupCNT = 0 Then
'SendMailMessage("uperformadmn@timken.com", "3304171597@vtext.com", "", "", "uPerform is down", "uPerform has been down for one hour now. Please investiage. Details: The TKR uperform Watch Dog was just getting started and after at least one hour of waiting for a SUCCESS I sent this email.")
SendMailMessage(strFromEmailAddress.ToString(), strGroupRecepientEmailAddress.ToString(), strBCCEmailAddress.ToString(), strCCEmailAddress.ToString(), "uPerform is down", "uPerform has been down for one hour now. Please investiage. Details: The TKR uperform Watch Dog was just getting started and after at least one hour of waiting for a SUCCESS I sent this email.")
Else
'SendMailMessage("uperformadmn@timken.com", "3304171597@vtext.com", "", "", "uPerform is down", "uPerform has been down over one hour now. Please investiage. Details: The TKR uperform Watch Dog was in the Continuous Monitor where it monitors the status every 1/2 hour and it began to find: " & strPreviousStatus & ". After another hour of waiting for a SUCCESS I sent this email.")
SendMailMessage(strFromEmailAddress.ToString(), strGroupRecepientEmailAddress.ToString(), strBCCEmailAddress.ToString(), strCCEmailAddress.ToString(), "uPerform is down", "uPerform has been down over one hour now. Please investiage. Details: The TKR uperform Watch Dog was in the Continuous Monitor where it monitors the status every 1/2 hour and it began to find: " & strPreviousStatus & ". After another hour of waiting for a SUCCESS I sent this email.")
End If
End If
End If
End Sub
Private Sub ContinuousMonitorTimerEvent(ByVal state As Object)
'--------------------------------------------------------------------------------------------------
' Because we have already been SUCCESSfull and everything was A-Okay at one time we are now only going
' to look every 30 min. to see that everything remains A-Okay ("SUCCESS" status returned).
' The "Vignette Collaboration" service may be stopped and restarted in this section.
' Note that stopping the "Vignette Collaboration" service may be a fault within itself.
'--------------------------------------------------------------------------------------------------
' Web page to monitor
Dim myPage As String = readHtmlPage(strGetStatusPage)
Dim strCurrentStatus = GetStatus(myPage)
strPreviousStatus = strCurrentStatus ' Reported in the email where intNetworkHicups > 0.
'--------------------------------------------------------------------------------------------------
' If the web page reports SUCCESS then everything remains good. Do nothing for another 30 min.
'--------------------------------------------------------------------------------------------------
If strCurrentStatus = "SUCCESS" Then
Dim sc As New ServiceController(strServiceToControl.ToString) 'Global variable at the very top
If sc.Status.Equals(ServiceControllerStatus.Running) Or sc.Status.Equals(ServiceControllerStatus.StartPending) Then
'--------------------------------------------------------------------------------------------------
'Everything is good! no operation really. But if had a network hiccup I better disable it.
'--------------------------------------------------------------------------------------------------
' Continuous Monitor found :" & intNetworkHiccupCNT & " network hiccups
' "only report once" the location to have the system log written once.
'--------------------------------------------------------------------------------------------------
intNetworkHiccupCNT = 0
Else
'--------------------------------------------------------------------------------------------------
' Someone must have manually stopped our local services. I don't want to do anything here but log it!
'--------------------------------------------------------------------------------------------------
WriteToEventLog("Continuous Monitor found the local " & strServiceToControl.ToString & " service stopped. I assume that someone mannually stopped the service because it was previously known to be working.", "tkruPerformWatchDog ", _
EventLogEntryType.Error, "System")
End If
Else
'--------------------------------------------------------------------------------------------------
' Did the IDOL server really go down? I really have to be careful here and retest the status.
' This could be a network hiccup. I'll change this timer to every 30 seconds and within 5 minutes
' or by the 10th test I'll restart this service. let's not panic over a possible network hiccup (intNetworkHiccupCNT).
'--------------------------------------------------------------------------------------------------
If intNetworkHiccupCNT = 0 Then
'Start Counting.
intNetworkHiccupCNT = intNetworkHiccupCNT + 1
'Change this timer to every thirty seconds. Previously I only watch for status != "SUCCESS" every 1/2 hour.
oTimer2.Change(3000, 30000)
WriteToEventLog("Continuous Monitor did NOT find a SUCCESS. Questioning if this was a network Hicup before doing anything yet. ", "tkruPerformWatchDog ", _
EventLogEntryType.Warning, "System")
End If
'--------------------------------------------------------------------------------------------------
' The counter has been tripped we are monitoring this faster now.
'--------------------------------------------------------------------------------------------------
If intNetworkHiccupCNT <> 0 Then
' --------------------------------------------------------------------------------------
' The tenth time (intNetworkHiccupCNT) is it a for-sure IDOL is DOWN.
' The IDOL server must have rebooted and this server is still running.
' Likely cause is someone is rebooting the IDOL server.
' --------------------------------------------------------------------------------------
If intNetworkHiccupCNT = 11 Then ' do not count the first one because we started at 1.
WriteToEventLog("Continuous Monitor did NOT find a SUCCESS after 10 attempts (5 minutes). Restarting this service and waiting for IDOL to come back online.", "tkruPerformWatchDog ", _
EventLogEntryType.Error, "System")
'---------------------------
'Stop our local service
'---------------------------
Dim sc As New ServiceController(strServiceToControl.ToString)
sc.Stop()
sc.Refresh()
'---------------------------------------------------------------------------------------------------------
' Switch the timers and just wait for our IDOL server to start up again in the JustStartingTimer Event.
' Of course a reboot might occur for Patch Management that will restart this WatchDog all over again too.
'---------------------------------------------------------------------------------------------------------
oTimer2.Change(Timeout.Infinite, Timeout.Infinite) ' Pause THIS timer indefinitely. It will be restarted!
oTimer1.Change(3000, 30000) ' three second wait and every thirty seconds there after.
End If
' continue to count.
intNetworkHiccupCNT = intNetworkHiccupCNT + 1
'Debug Move this to: "only report once"
' Debug Only to report this only once
WriteToEventLog("Continuous Monitor found :" & intNetworkHiccupCNT & " network hiccups", "tkruPerformWatchDog ", _
EventLogEntryType.Warning, "System")
End If
End If
End Sub
Public Shared Sub SendMailMessage(ByVal from As String, ByVal recepient As String, ByVal bcc As String, ByVal cc As String, ByVal subject As String, ByVal body As String)
Try
' Instantiate a new instance of MailMessage
Dim mMailMessage As New MailMessage()
' Set the sender address of the mail message
mMailMessage.From = New MailAddress(from)
' Set the recepient address of the mail message
mMailMessage.To.Add(New MailAddress(recepient))
' Check if the bcc value is nothing or an empty string
If Not bcc Is Nothing And bcc <> String.Empty Then
' Set the Bcc address of the mail message
mMailMessage.Bcc.Add(New MailAddress(bcc))
End If
' Check if the cc value is nothing or an empty value
If Not cc Is Nothing And cc <> String.Empty Then
' Set the CC address of the mail message
mMailMessage.CC.Add(New MailAddress(cc))
End If
' Set the subject of the mail message
mMailMessage.Subject = subject
' Set the body of the mail message
mMailMessage.Body = body
' Set the format of the mail message body as HTML
mMailMessage.IsBodyHtml = True
' Set the priority of the mail message to normal
'mMailMessage.Priority = MailPriority.Normal
mMailMessage.Priority = MailPriority.High
' Instantiate a new instance of SmtpClient
Dim mSmtpClient As New SmtpClient("ctnhemailsw01.corp.timken.com")
'Timken Required settings. (hardcoded bad Don, bad!)
mSmtpClient.Host = "ctnhemailsw01.corp.timken.com"
mSmtpClient.Port = "25"
' Send the mail message
mSmtpClient.Send(mMailMessage)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Public Function WriteToEventLog(ByVal Entry As String, _
Optional ByVal AppName As String = "VB.NET Application", _
Optional ByVal EventType As _
EventLogEntryType = EventLogEntryType.Information, _
Optional ByVal LogName As String = "Application") As Boolean
'*************************************************************
'PURPOSE: Write Entry to Event Log using VB.NET
'PARAMETERS: Entry - Value to Write
' AppName - Name of Client Application. Needed
' because before writing to event log, you must
' have a named EventLog source.
' EventType - Entry Type, from EventLogEntryType
' Structure e.g., EventLogEntryType.Warning,
' EventLogEntryType.Error
' LogName: Name of Log (System, Application;
' Security is read-only) If you
' specify a non-existent log, the log will be
' created
'RETURNS: True if successful, false if not
'EXAMPLES:
'1. Simple Example, Accepting All Defaults
' WriteToEventLog "Hello Event Log"
'2. Specify EventSource, EventType, and LogName
' WriteToEventLog("Danger, Danger, Danger", "MyVbApp", _
' EventLogEntryType.Warning, "System")
'
'NOTE: EventSources are tightly tied to their log.
' So don't use the same source name for different
' logs, and vice versa
'******************************************************
Dim objEventLog As New EventLog()
Try
'Register the App as an Event Source
If Not EventLog.SourceExists(AppName) Then
EventLog.CreateEventSource(AppName, LogName)
End If
objEventLog.Source = AppName
'WriteEntry is overloaded; this is one
'of 10 ways to call it
objEventLog.WriteEntry(Entry, EventType)
Return True
Catch Ex As Exception
Return False
End Try
End Function
Public Function readHtmlPage(ByVal url As String) As String
Dim objResponse As Net.WebResponse
Dim objRequest As Net.WebRequest
Dim result As String
objRequest = System.Net.HttpWebRequest.Create(url)
Try
objResponse = objRequest.GetResponse()
Dim sr As New StreamReader(objResponse.GetResponseStream())
result = sr.ReadToEnd()
'clean up StreamReader
sr.Close()
Catch ex As Exception
'Network fail return nothing.
result = ""
End Try
Return result
End Function
Public Function GetStatus(ByVal uPerformStatusXML As String)
Dim Status As String = "Nothing Yet"
Try
Dim Doc As New XmlDocument
Doc.LoadXml(uPerformStatusXML)
Status = Doc.DocumentElement("response").InnerText
Doc = Nothing
Catch ex As Exception
Status = "Error"
Finally
End Try
Return Status
End Function
End Class