IIS log housekeeper service
A simple IIS log rotation Windows service with automatic/manual log location discovery and subfolder traversal for IIS 6 (Windows Server 2003), IIS 7.x (Windows Server 2008) and IIS 8.x (Windows Server 2012). The complete VB.Net source code is included in the download package.Download IisLogHousekeeper for IIS 6.x
Download IisLogHousekeeper for IIS 7.x / 8.x
Installation instructions:
- Download the zip file matching the server's IIS version and extract it to the server's "Program files (x86)" or "Program files" folder.
- Open IisLogHousekeeper.exe.config in a text editor and adjust the schedule, the log retention period and optionally the manual log locations (see configuration reference further down this page).
- Install and start the service by running ServiceInstall.vbs. The service can be uninstalled using ServiceUninstall.vbs.
- Check the service status in the Windows Application Event log. Events will be marked with the name "IisLogHousekeeper".
The standard disclaimer: The program is provided 'as is' without warranty of any kind. I have done my best to incorporate graceful exception handling and to test the code in different scenarios, so it shouldn't be able to do anything bad or unintended. But I guarantee nothing.
This IIS log housekeeper service is a further development of my old VBScript automatic log housekeeping scripts. But they differ in functionality. If you also need archiving/compression of log files, they should be used instead.
IisLogHousekeeper.exe.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SimulationMode" value="False"/>
<add key="RunAt" value="03:00"/>
<add key="LogRetentionDays" value="30"/>
<add key="UseManualLogLocations" value="False"/>
<add key="ManualLogLocations" value="C:\inetpub\logs\LogFiles|C:\WINDOWS\system32\LogFiles"/>
</appSettings>
</configuration>
<configuration>
<appSettings>
<add key="SimulationMode" value="False"/>
<add key="RunAt" value="03:00"/>
<add key="LogRetentionDays" value="30"/>
<add key="UseManualLogLocations" value="False"/>
<add key="ManualLogLocations" value="C:\inetpub\logs\LogFiles|C:\WINDOWS\system32\LogFiles"/>
</appSettings>
</configuration>
IisLogHousekeeper.vb (for IIS 6.x):
Imports System
Imports System.DirectoryServices
Imports System.Text
Imports System.IO
Imports System.Configuration
Imports System.Threading
Imports System.ServiceProcess
Imports System.Diagnostics
Imports System.Reflection
<Assembly: AssemblyTitle("IisLogHousekeeper 1.1 IIS6x edition")>
<Assembly: AssemblyDescription("IIS log housekeeping service")>
<Assembly: AssemblyCompany("www.700c.dk")>
<Assembly: AssemblyProduct("IisLogHousekeeper")>
<Assembly: AssemblyCopyright("Creative Commons Attribution (CC BY 3.0) https://creativecommons.org/licenses/by/3.0/ Reference source https://www.700c.dk/?code-iis-log-housekeeper-service")>
<Assembly: AssemblyVersion("1.1.0.0")>
<Assembly: CLSCompliant(True)>
Public Class IisLogHousekeeper
Private Shared ServiceThread As Thread
Private Shared KeepRunning As Boolean = True
Protected Overrides Sub OnStart(ByVal args() As String)
WriteToEventLog("IisLogHousekeeper starting", 1110)
ServiceThread = New Thread(AddressOf RunWorkerThread)
ServiceThread.Start()
End Sub
Protected Overrides Sub OnStop()
KeepRunning = False
WriteToEventLog( _
"IisLogHousekeeper stopping. Please note: the worker process " & _
"will live on for up to 60 seconds before it terminates.", 1110)
End Sub
Public Sub RunWorkerThread()
Dim aFolders() As String = {}
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "true" Then
aFolders = Split(ConfigurationManager.AppSettings("ManualLogLocations"), "|")
End If
Dim sRunResult As String = ""
Do While KeepRunning
If ConfigurationManager.AppSettings("RunAt") = Date.Now.ToString("HH:mm") Then
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "false" Then
Try
aFolders = GetIisLogFoldersThroughADSI()
Catch e As Exception
WriteToEventLog("Could not get IIS log locations through ADSI. Error message: " & e.Message, 1112)
End Try
End If
Try
For i As Integer = 0 to UBound(aFolders)
sRunResult = sRunResult & _
DeleteLogFilesRecursive(aFolders(i), CInt(ConfigurationManager.AppSettings("LogRetentionDays")))
Next
If sRunResult <> "" Then
WriteToEventLog(sRunResult, 1111)
sRunResult = ""
End If
Catch e As Exception
WriteToEventLog("An error occurred while cleaning up logs: " & e.Message, 1112)
End Try
End If
Thread.Sleep(60000)
Loop
End Sub
Public Function WriteToEventLog(ByVal Entry As String, _
Optional ByVal EventID As Integer = 0, _
Optional ByVal AppName As String = "IisLogHousekeeper", _
Optional ByVal EventType As _
EventLogEntryType = EventLogEntryType.Information, _
Optional ByVal LogName As String = "Application") As Boolean
Dim objEventLog As New EventLog()
Try
If Not Diagnostics.EventLog.SourceExists(AppName) Then
Diagnostics.EventLog.CreateEventSource(AppName, LogName)
End If
objEventLog.Source = AppName
objEventLog.WriteEntry(Entry, EventType, EventID)
Return True
Catch Ex As Exception
Return False
End Try
objEventLog.Dispose()
End Function
Public Function GetIisLogFoldersThroughADSI() As String()
Dim sFolderList As String = ""
Dim deIisRootObject As New DirectoryEntry("IIS://localhost")
Dim deIisSubItems As DirectoryEntry
Dim deIisNodeObj As DirectoryEntry
For Each deIisSubItems in deIisRootObject.Children
If LCase(deIisSubItems.SchemaClassName) = "iiswebservice" Then
Dim deIisService As New DirectoryEntry("IIS://localhost/W3SVC")
For Each deIisNodeObj in deIisService.Children
If LCase(deIisNodeObj.SchemaClassName) = "iiswebserver" Then
sFolderList = sFolderList & _
deIisNodeObj.Properties("LogFileDirectory").Value.ToString() & _
"\W3SVC" & deIisNodeObj.Name & "|"
End If
Next
ElseIf LCase(deIisSubItems.SchemaClassName) = "iissmtpservice" Then
Dim deIisService As New DirectoryEntry("IIS://localhost/SMTPSVC")
For Each deIisNodeObj in deIisService.Children
If LCase(deIisNodeObj.SchemaClassName) = "iissmtpserver" Then
sFolderList = sFolderList & _
deIisNodeObj.Properties("LogFileDirectory").Value.ToString() & _
"\SMTPSVC" & deIisNodeObj.Name & "|"
End If
Next
ElseIf LCase(deIisSubItems.SchemaClassName) = "iisftpservice" Then
Dim deIisService As New DirectoryEntry("IIS://localhost/MSFTPSVC")
For Each deIisNodeObj in deIisService.Children
If LCase(deIisNodeObj.SchemaClassName) = "iisftpserver" Then
sFolderList = sFolderList & _
deIisNodeObj.Properties("LogFileDirectory").Value.ToString() & _
"\MSFTPSVC" & deIisNodeObj.Name & "|"
End If
Next
End If
Next
If Right(sFolderList, 1) = "|" Then
sFolderList = Left(sFolderList, Len(sFolderList) - 1)
End If
Return Split(sFolderList, "|")
End Function
Public Function DeleteLogFilesRecursive(ByVal sLogPath As String, ByVal iDelAge As Integer) As String
Dim sReturn As String = ""
If Directory.Exists(sLogPath)
Dim dInfo As New DirectoryInfo(sLogPath)
Dim fInfo as FileSystemInfo
Dim sTempString As String = ""
For Each fInfo In dInfo.GetFileSystemInfos()
If fInfo.Attributes = FileAttributes.Directory Then
sReturn = sReturn & DeleteLogFilesRecursive(fInfo.FullName, iDelAge)
Else
If (InStr(fInfo.FullName, "ex") > 0) And (Right(fInfo.FullName, 4) = ".log") Then
If DateDiff("d", fInfo.LastWriteTime, Now) > iDelAge Then
Try
sTempString = fInfo.FullName & " deleted." & VbCrLf
If LCase(ConfigurationManager.AppSettings("SimulationMode")) = "false" Then
File.Delete(fInfo.FullName)
sReturn = sReturn & sTempString
Else
sReturn = sReturn & "[Simulation mode enabled] " & sTempString
End If
Catch e As Exception
sReturn = sReturn & fInfo.FullName & " could not be deleted. Error message: " & e.Message & VbCrLf
End Try
End If
End If
End If
Next
End If
Return sReturn
End Function
End Class
<System.ComponentModel.RunInstaller(True)> _
Public Class ProjectInstaller
Inherits System.Configuration.Install.Installer
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Private components As System.ComponentModel.IContainer
Private Sub InitializeComponent()
Me.ServiceProcessInstaller1 = New ServiceProcessInstaller
Me.ServiceInstaller1 = New ServiceInstaller
Me.ServiceProcessInstaller1.Account = ServiceAccount.LocalSystem
Me.ServiceProcessInstaller1.Password = Nothing
Me.ServiceProcessInstaller1.Username = Nothing
Me.ServiceInstaller1.ServiceName = "IisLogHousekeeper"
Me.ServiceInstaller1.StartType = ServiceStartMode.Automatic
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
End Sub
Friend WithEvents ServiceProcessInstaller1 As ServiceProcessInstaller
Friend WithEvents ServiceInstaller1 As ServiceInstaller
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class IisLogHousekeeper
Inherits System.ServiceProcess.ServiceBase
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New IisLogHousekeeper}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.ServiceName = "IisLogHousekeeper"
End Sub
End Class
Imports System.DirectoryServices
Imports System.Text
Imports System.IO
Imports System.Configuration
Imports System.Threading
Imports System.ServiceProcess
Imports System.Diagnostics
Imports System.Reflection
<Assembly: AssemblyTitle("IisLogHousekeeper 1.1 IIS6x edition")>
<Assembly: AssemblyDescription("IIS log housekeeping service")>
<Assembly: AssemblyCompany("www.700c.dk")>
<Assembly: AssemblyProduct("IisLogHousekeeper")>
<Assembly: AssemblyCopyright("Creative Commons Attribution (CC BY 3.0) https://creativecommons.org/licenses/by/3.0/ Reference source https://www.700c.dk/?code-iis-log-housekeeper-service")>
<Assembly: AssemblyVersion("1.1.0.0")>
<Assembly: CLSCompliant(True)>
Public Class IisLogHousekeeper
Private Shared ServiceThread As Thread
Private Shared KeepRunning As Boolean = True
Protected Overrides Sub OnStart(ByVal args() As String)
WriteToEventLog("IisLogHousekeeper starting", 1110)
ServiceThread = New Thread(AddressOf RunWorkerThread)
ServiceThread.Start()
End Sub
Protected Overrides Sub OnStop()
KeepRunning = False
WriteToEventLog( _
"IisLogHousekeeper stopping. Please note: the worker process " & _
"will live on for up to 60 seconds before it terminates.", 1110)
End Sub
Public Sub RunWorkerThread()
Dim aFolders() As String = {}
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "true" Then
aFolders = Split(ConfigurationManager.AppSettings("ManualLogLocations"), "|")
End If
Dim sRunResult As String = ""
Do While KeepRunning
If ConfigurationManager.AppSettings("RunAt") = Date.Now.ToString("HH:mm") Then
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "false" Then
Try
aFolders = GetIisLogFoldersThroughADSI()
Catch e As Exception
WriteToEventLog("Could not get IIS log locations through ADSI. Error message: " & e.Message, 1112)
End Try
End If
Try
For i As Integer = 0 to UBound(aFolders)
sRunResult = sRunResult & _
DeleteLogFilesRecursive(aFolders(i), CInt(ConfigurationManager.AppSettings("LogRetentionDays")))
Next
If sRunResult <> "" Then
WriteToEventLog(sRunResult, 1111)
sRunResult = ""
End If
Catch e As Exception
WriteToEventLog("An error occurred while cleaning up logs: " & e.Message, 1112)
End Try
End If
Thread.Sleep(60000)
Loop
End Sub
Public Function WriteToEventLog(ByVal Entry As String, _
Optional ByVal EventID As Integer = 0, _
Optional ByVal AppName As String = "IisLogHousekeeper", _
Optional ByVal EventType As _
EventLogEntryType = EventLogEntryType.Information, _
Optional ByVal LogName As String = "Application") As Boolean
Dim objEventLog As New EventLog()
Try
If Not Diagnostics.EventLog.SourceExists(AppName) Then
Diagnostics.EventLog.CreateEventSource(AppName, LogName)
End If
objEventLog.Source = AppName
objEventLog.WriteEntry(Entry, EventType, EventID)
Return True
Catch Ex As Exception
Return False
End Try
objEventLog.Dispose()
End Function
Public Function GetIisLogFoldersThroughADSI() As String()
Dim sFolderList As String = ""
Dim deIisRootObject As New DirectoryEntry("IIS://localhost")
Dim deIisSubItems As DirectoryEntry
Dim deIisNodeObj As DirectoryEntry
For Each deIisSubItems in deIisRootObject.Children
If LCase(deIisSubItems.SchemaClassName) = "iiswebservice" Then
Dim deIisService As New DirectoryEntry("IIS://localhost/W3SVC")
For Each deIisNodeObj in deIisService.Children
If LCase(deIisNodeObj.SchemaClassName) = "iiswebserver" Then
sFolderList = sFolderList & _
deIisNodeObj.Properties("LogFileDirectory").Value.ToString() & _
"\W3SVC" & deIisNodeObj.Name & "|"
End If
Next
ElseIf LCase(deIisSubItems.SchemaClassName) = "iissmtpservice" Then
Dim deIisService As New DirectoryEntry("IIS://localhost/SMTPSVC")
For Each deIisNodeObj in deIisService.Children
If LCase(deIisNodeObj.SchemaClassName) = "iissmtpserver" Then
sFolderList = sFolderList & _
deIisNodeObj.Properties("LogFileDirectory").Value.ToString() & _
"\SMTPSVC" & deIisNodeObj.Name & "|"
End If
Next
ElseIf LCase(deIisSubItems.SchemaClassName) = "iisftpservice" Then
Dim deIisService As New DirectoryEntry("IIS://localhost/MSFTPSVC")
For Each deIisNodeObj in deIisService.Children
If LCase(deIisNodeObj.SchemaClassName) = "iisftpserver" Then
sFolderList = sFolderList & _
deIisNodeObj.Properties("LogFileDirectory").Value.ToString() & _
"\MSFTPSVC" & deIisNodeObj.Name & "|"
End If
Next
End If
Next
If Right(sFolderList, 1) = "|" Then
sFolderList = Left(sFolderList, Len(sFolderList) - 1)
End If
Return Split(sFolderList, "|")
End Function
Public Function DeleteLogFilesRecursive(ByVal sLogPath As String, ByVal iDelAge As Integer) As String
Dim sReturn As String = ""
If Directory.Exists(sLogPath)
Dim dInfo As New DirectoryInfo(sLogPath)
Dim fInfo as FileSystemInfo
Dim sTempString As String = ""
For Each fInfo In dInfo.GetFileSystemInfos()
If fInfo.Attributes = FileAttributes.Directory Then
sReturn = sReturn & DeleteLogFilesRecursive(fInfo.FullName, iDelAge)
Else
If (InStr(fInfo.FullName, "ex") > 0) And (Right(fInfo.FullName, 4) = ".log") Then
If DateDiff("d", fInfo.LastWriteTime, Now) > iDelAge Then
Try
sTempString = fInfo.FullName & " deleted." & VbCrLf
If LCase(ConfigurationManager.AppSettings("SimulationMode")) = "false" Then
File.Delete(fInfo.FullName)
sReturn = sReturn & sTempString
Else
sReturn = sReturn & "[Simulation mode enabled] " & sTempString
End If
Catch e As Exception
sReturn = sReturn & fInfo.FullName & " could not be deleted. Error message: " & e.Message & VbCrLf
End Try
End If
End If
End If
Next
End If
Return sReturn
End Function
End Class
<System.ComponentModel.RunInstaller(True)> _
Public Class ProjectInstaller
Inherits System.Configuration.Install.Installer
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Private components As System.ComponentModel.IContainer
Private Sub InitializeComponent()
Me.ServiceProcessInstaller1 = New ServiceProcessInstaller
Me.ServiceInstaller1 = New ServiceInstaller
Me.ServiceProcessInstaller1.Account = ServiceAccount.LocalSystem
Me.ServiceProcessInstaller1.Password = Nothing
Me.ServiceProcessInstaller1.Username = Nothing
Me.ServiceInstaller1.ServiceName = "IisLogHousekeeper"
Me.ServiceInstaller1.StartType = ServiceStartMode.Automatic
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
End Sub
Friend WithEvents ServiceProcessInstaller1 As ServiceProcessInstaller
Friend WithEvents ServiceInstaller1 As ServiceInstaller
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class IisLogHousekeeper
Inherits System.ServiceProcess.ServiceBase
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New IisLogHousekeeper}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.ServiceName = "IisLogHousekeeper"
End Sub
End Class
IisLogHousekeeper.vb (for IIS 7.x and 8.x):
Imports System
Imports System.DirectoryServices
Imports System.Text
Imports System.IO
Imports System.Configuration
Imports System.Threading
Imports System.ServiceProcess
Imports System.Diagnostics
Imports System.Reflection
Imports Microsoft.Web.Administration
<Assembly: AssemblyTitle("IisLogHousekeeper 1.1 for IIS 7.x / 8.x")>
<Assembly: AssemblyDescription("IIS log housekeeping service (IIS 7/8 edition)")>
<Assembly: AssemblyCompany("www.700c.dk")>
<Assembly: AssemblyProduct("IisLogHousekeeper")>
<Assembly: AssemblyCopyright("Creative Commons Attribution (CC BY 3.0) https://creativecommons.org/licenses/by/3.0/ Reference source https://www.700c.dk/?code-iis-log-housekeeper-service")>
<Assembly: AssemblyVersion("1.1.0.0")>
<Assembly: CLSCompliant(True)>
Public Class IisLogHousekeeper
Private Shared ServiceThread As Thread
Private Shared KeepRunning As Boolean = True
Protected Overrides Sub OnStart(ByVal args() As String)
WriteToEventLog("IisLogHousekeeper starting", 1110)
ServiceThread = New Thread(AddressOf RunWorkerThread)
ServiceThread.Start()
End Sub
Protected Overrides Sub OnStop()
KeepRunning = False
WriteToEventLog( _
"IisLogHousekeeper stopping. Please note: the worker process " & _
"will live on for up to 60 seconds before it terminates.", 1110)
End Sub
Public Sub RunWorkerThread()
Dim aFolders() As String = {}
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "true" Then
aFolders = Split(ConfigurationManager.AppSettings("ManualLogLocations"), "|")
End If
Dim sRunResult As String = ""
Do While KeepRunning
If ConfigurationManager.AppSettings("RunAt") = Date.Now.ToString("HH:mm") Then
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "false" Then
Try
aFolders = GetIisLogFolders()
Catch e As Exception
WriteToEventLog("Could not get IIS log locations through the IIS API. Error message: " & e.Message, 1112)
End Try
End If
Try
For i As Integer = 0 to UBound(aFolders)
sRunResult = sRunResult & _
DeleteLogFilesRecursive(aFolders(i), CInt(ConfigurationManager.AppSettings("LogRetentionDays")))
Next
If sRunResult <> "" Then
WriteToEventLog(sRunResult, 1111)
sRunResult = ""
End If
Catch e As Exception
WriteToEventLog("An error occurred while cleaning up logs: " & e.Message, 1112)
End Try
End If
Thread.Sleep(60000)
Loop
End Sub
Public Function WriteToEventLog(ByVal Entry As String, _
Optional ByVal EventID As Integer = 0, _
Optional ByVal AppName As String = "IisLogHousekeeper", _
Optional ByVal EventType As _
EventLogEntryType = EventLogEntryType.Information, _
Optional ByVal LogName As String = "Application") As Boolean
Dim objEventLog As New EventLog()
Try
If Not Diagnostics.EventLog.SourceExists(AppName) Then
Diagnostics.EventLog.CreateEventSource(AppName, LogName)
End If
objEventLog.Source = AppName
objEventLog.WriteEntry(Entry, EventType, EventID)
Return True
Catch Ex As Exception
Return False
End Try
objEventLog.Dispose()
End Function
Public Function GetIisLogFolders() As String()
Dim sFolderList As String = ""
Dim mgr As New ServerManager()
For Each oWebsite As Site In mgr.Sites
sFolderList = sFolderList & oWebsite.LogFile.Directory & "\W3SVC" & oWebsite.Id.ToString() & "|"
Next
If Right(sFolderList, 1) = "|" Then
sFolderList = Left(sFolderList, Len(sFolderList) - 1)
End If
' Yes, the following replacement is an ugly hack. The later file handling functions don't like the environment variable format the IIS API returns:
sFolderList = Replace(sFolderList, "%SystemDrive%", "C:")
Return Split(sFolderList, "|")
End Function
Public Function DeleteLogFilesRecursive(ByVal sLogPath As String, ByVal iDelAge As Integer) As String
Dim sReturn As String = ""
If Directory.Exists(sLogPath)
Dim dInfo As New DirectoryInfo(sLogPath)
Dim fInfo as FileSystemInfo
Dim sTempString As String = ""
For Each fInfo In dInfo.GetFileSystemInfos()
If fInfo.Attributes = FileAttributes.Directory Then
sReturn = sReturn & DeleteLogFilesRecursive(fInfo.FullName, iDelAge)
Else
If (InStr(fInfo.FullName, "ex") > 0) And (Right(fInfo.FullName, 4) = ".log") Then
If DateDiff("d", fInfo.LastWriteTime, Now) > iDelAge Then
Try
sTempString = fInfo.FullName & " deleted." & VbCrLf
If LCase(ConfigurationManager.AppSettings("SimulationMode")) = "false" Then
File.Delete(fInfo.FullName)
sReturn = sReturn & sTempString
Else
sReturn = sReturn & "[Simulation mode enabled] " & sTempString
End If
Catch e As Exception
sReturn = sReturn & fInfo.FullName & " could not be deleted. Error message: " & e.Message & VbCrLf
End Try
End If
End If
End If
Next
End If
Return sReturn
End Function
End Class
<System.ComponentModel.RunInstaller(True)> _
Public Class ProjectInstaller
Inherits System.Configuration.Install.Installer
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Private components As System.ComponentModel.IContainer
Private Sub InitializeComponent()
Me.ServiceProcessInstaller1 = New ServiceProcessInstaller
Me.ServiceInstaller1 = New ServiceInstaller
Me.ServiceProcessInstaller1.Account = ServiceAccount.LocalSystem
Me.ServiceProcessInstaller1.Password = Nothing
Me.ServiceProcessInstaller1.Username = Nothing
Me.ServiceInstaller1.ServiceName = "IisLogHousekeeper"
Me.ServiceInstaller1.StartType = ServiceStartMode.Automatic
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
End Sub
Friend WithEvents ServiceProcessInstaller1 As ServiceProcessInstaller
Friend WithEvents ServiceInstaller1 As ServiceInstaller
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class IisLogHousekeeper
Inherits System.ServiceProcess.ServiceBase
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New IisLogHousekeeper}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.ServiceName = "IisLogHousekeeper"
End Sub
End Class
Imports System.DirectoryServices
Imports System.Text
Imports System.IO
Imports System.Configuration
Imports System.Threading
Imports System.ServiceProcess
Imports System.Diagnostics
Imports System.Reflection
Imports Microsoft.Web.Administration
<Assembly: AssemblyTitle("IisLogHousekeeper 1.1 for IIS 7.x / 8.x")>
<Assembly: AssemblyDescription("IIS log housekeeping service (IIS 7/8 edition)")>
<Assembly: AssemblyCompany("www.700c.dk")>
<Assembly: AssemblyProduct("IisLogHousekeeper")>
<Assembly: AssemblyCopyright("Creative Commons Attribution (CC BY 3.0) https://creativecommons.org/licenses/by/3.0/ Reference source https://www.700c.dk/?code-iis-log-housekeeper-service")>
<Assembly: AssemblyVersion("1.1.0.0")>
<Assembly: CLSCompliant(True)>
Public Class IisLogHousekeeper
Private Shared ServiceThread As Thread
Private Shared KeepRunning As Boolean = True
Protected Overrides Sub OnStart(ByVal args() As String)
WriteToEventLog("IisLogHousekeeper starting", 1110)
ServiceThread = New Thread(AddressOf RunWorkerThread)
ServiceThread.Start()
End Sub
Protected Overrides Sub OnStop()
KeepRunning = False
WriteToEventLog( _
"IisLogHousekeeper stopping. Please note: the worker process " & _
"will live on for up to 60 seconds before it terminates.", 1110)
End Sub
Public Sub RunWorkerThread()
Dim aFolders() As String = {}
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "true" Then
aFolders = Split(ConfigurationManager.AppSettings("ManualLogLocations"), "|")
End If
Dim sRunResult As String = ""
Do While KeepRunning
If ConfigurationManager.AppSettings("RunAt") = Date.Now.ToString("HH:mm") Then
If LCase(ConfigurationManager.AppSettings("UseManualLogLocations")) = "false" Then
Try
aFolders = GetIisLogFolders()
Catch e As Exception
WriteToEventLog("Could not get IIS log locations through the IIS API. Error message: " & e.Message, 1112)
End Try
End If
Try
For i As Integer = 0 to UBound(aFolders)
sRunResult = sRunResult & _
DeleteLogFilesRecursive(aFolders(i), CInt(ConfigurationManager.AppSettings("LogRetentionDays")))
Next
If sRunResult <> "" Then
WriteToEventLog(sRunResult, 1111)
sRunResult = ""
End If
Catch e As Exception
WriteToEventLog("An error occurred while cleaning up logs: " & e.Message, 1112)
End Try
End If
Thread.Sleep(60000)
Loop
End Sub
Public Function WriteToEventLog(ByVal Entry As String, _
Optional ByVal EventID As Integer = 0, _
Optional ByVal AppName As String = "IisLogHousekeeper", _
Optional ByVal EventType As _
EventLogEntryType = EventLogEntryType.Information, _
Optional ByVal LogName As String = "Application") As Boolean
Dim objEventLog As New EventLog()
Try
If Not Diagnostics.EventLog.SourceExists(AppName) Then
Diagnostics.EventLog.CreateEventSource(AppName, LogName)
End If
objEventLog.Source = AppName
objEventLog.WriteEntry(Entry, EventType, EventID)
Return True
Catch Ex As Exception
Return False
End Try
objEventLog.Dispose()
End Function
Public Function GetIisLogFolders() As String()
Dim sFolderList As String = ""
Dim mgr As New ServerManager()
For Each oWebsite As Site In mgr.Sites
sFolderList = sFolderList & oWebsite.LogFile.Directory & "\W3SVC" & oWebsite.Id.ToString() & "|"
Next
If Right(sFolderList, 1) = "|" Then
sFolderList = Left(sFolderList, Len(sFolderList) - 1)
End If
' Yes, the following replacement is an ugly hack. The later file handling functions don't like the environment variable format the IIS API returns:
sFolderList = Replace(sFolderList, "%SystemDrive%", "C:")
Return Split(sFolderList, "|")
End Function
Public Function DeleteLogFilesRecursive(ByVal sLogPath As String, ByVal iDelAge As Integer) As String
Dim sReturn As String = ""
If Directory.Exists(sLogPath)
Dim dInfo As New DirectoryInfo(sLogPath)
Dim fInfo as FileSystemInfo
Dim sTempString As String = ""
For Each fInfo In dInfo.GetFileSystemInfos()
If fInfo.Attributes = FileAttributes.Directory Then
sReturn = sReturn & DeleteLogFilesRecursive(fInfo.FullName, iDelAge)
Else
If (InStr(fInfo.FullName, "ex") > 0) And (Right(fInfo.FullName, 4) = ".log") Then
If DateDiff("d", fInfo.LastWriteTime, Now) > iDelAge Then
Try
sTempString = fInfo.FullName & " deleted." & VbCrLf
If LCase(ConfigurationManager.AppSettings("SimulationMode")) = "false" Then
File.Delete(fInfo.FullName)
sReturn = sReturn & sTempString
Else
sReturn = sReturn & "[Simulation mode enabled] " & sTempString
End If
Catch e As Exception
sReturn = sReturn & fInfo.FullName & " could not be deleted. Error message: " & e.Message & VbCrLf
End Try
End If
End If
End If
Next
End If
Return sReturn
End Function
End Class
<System.ComponentModel.RunInstaller(True)> _
Public Class ProjectInstaller
Inherits System.Configuration.Install.Installer
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Private components As System.ComponentModel.IContainer
Private Sub InitializeComponent()
Me.ServiceProcessInstaller1 = New ServiceProcessInstaller
Me.ServiceInstaller1 = New ServiceInstaller
Me.ServiceProcessInstaller1.Account = ServiceAccount.LocalSystem
Me.ServiceProcessInstaller1.Password = Nothing
Me.ServiceProcessInstaller1.Username = Nothing
Me.ServiceInstaller1.ServiceName = "IisLogHousekeeper"
Me.ServiceInstaller1.StartType = ServiceStartMode.Automatic
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
End Sub
Friend WithEvents ServiceProcessInstaller1 As ServiceProcessInstaller
Friend WithEvents ServiceInstaller1 As ServiceInstaller
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class IisLogHousekeeper
Inherits System.ServiceProcess.ServiceBase
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New IisLogHousekeeper}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.ServiceName = "IisLogHousekeeper"
End Sub
End Class
Tags: software
Page last updated 2013-04-12 21:18. Some rights reserved (CC by 3.0)