Wednesday, 15 April 2009

Some code about available disk space

My application runs across a server farm. I need to know when the disk capacity is running low. My first thought was to use SNMP traps that are built into HP servers and can monitor everything down to the temperature of the mother board. Unfortunately the servers do not have this configured and I am a little reluctant to start a project on Server monitoring especially since this is not my primary job. So I looked into what the SQL Server had to offer. I found the following quite usefull

EXEC xp_fixeddrives
Returns [drive] and [MB free]

EXEC xp_msver
Returns information about the current version of SQL server installed

exec master.dbo.xp_sqlagent_enum_jobs @is_sysadmin = 1, @job_owner = ''
Returns the jobs running under the SQL Agent

The first idea was to use the central SQL Server and use LinkedServers forwarding the user credentials. This this not work since the user has not sufficient access rights and that we did not want to hard code user name and password in the linked server connection

Since we don’t have IIS on these machines we decided for a Windows Service that hosts a WCP application. The Windows Service part of this looked like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace ServerMonitorWindowsService
{
static class Program
{
///
/// The main entry point for the application.
///

static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new ServerMonitorWindowsService()
};
ServiceBase.Run(ServicesToRun);
}
}
}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;

namespace ServerMonitorWindowsService
{
public partial class ServerMonitorWindowsService : ServiceBase
{
private Type serviceType;
private ServiceHost host;

public ServerMonitorWindowsService()
{
InitializeComponent();
serviceType = typeof(ServerMonitorService.ServerMonitorService);
}

protected override void OnStart(string[] args)
{
host = new ServiceHost(serviceType);
host.Open();
}

protected override void OnStop()
{
host.Close();
}
}
}

We used the tcp protocol and a WCP function that looked like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Management;

namespace ServerMonitorService
{
public class ServerMonitorService : IServerMonitorService
{

#region IServerMonitorService Members

public ulong GetFreeSpace()
{
return GetFreeDiskSpaceInBytes("d");
}

#endregion

private static ulong GetFreeDiskSpaceInBytes(string drive)
{
ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + drive + ":\"");
disk.Get();
return (ulong)disk["FreeSpace"];
}
}
}