Issue
I have monitored performance counters such as memory, free disk etc using CloudWatch custom metrics. Can I monitor the services using CloudWatch? I have checked the features which cloud watch monitors but found nothing related to monitoring services. I just need to monitor whether the service is running or not and send a notification when the state of the service changes.
Solution
Yes, but out-of-the-box solutions like the EC2Config Windows Integration you alluded to aren't as readily available for service-level custom metrics.
CloudWatch Custom Metrics allow you to extend CloudWatch with your own defined metrics and data, so you can reasonable implement them yourselves to monitor your own services. Your service can write metrics data to CloudWatch itself, or you can write another process that monitors your service and writes metrics based on responses from your service to CloudWatch.
Per your edits, to publish CloudWatch custom metrics for an arbitrary set of windows services will require some windows-specific powershell, because we can't assume that the service will have a web endpoint to ping.
You'll want to create a service monitor that evaluates your services via Get-Service
, and then publishes a data point to a CloudWatch custom metrics if they are running.
Here is an example implementation in PowerShell that will write custom metrics for services with a name matching *YOURSERVICENAMESHERE*
every 300 seconds. If you want to run this for every service on the EC2 instance, you can replace this with the wildcard *
, but this may be expensive at scale. It may also require some tweaking if too many services are on the box, because you can only send so many metrics at a time via Write-CwMetricData
. See code comments for details on that.
By only creating a data point on success, you establish a 'failure' condition (INSUFFICIENT_DATA for X seconds) that you can use to create CloudWatch Alarms that satisfy your notification constraint.
This script MUST be run on a Windows EC2 instance with AWS Tools for PowerShell installed and configured:
Param
(
[string]$Period = 300,
[string]$Namespace = 'service-monitor'
)
# Use the EC2 metadata service to get the host EC2 instance's ID
$instanceId = (New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
# Associate current EC2 instance with your custom cloudwatch metric
$instanceDimension = New-Object -TypeName Amazon.CloudWatch.Model.Dimension;
$instanceDimension.Name = "instanceid";
$instanceDimension.Value = $instanceId;
# "Job" loop; write to CloudWatch and then sleep for the interval defined by the period variable above, in seconds.
while($true)
{
$metrics = @();
$runningServices = Get-Service -Name *YOURSERVICENAMESHERE* | ? { $_.Status -eq 'Running' }
# For each running service, add a metric to metrics collection that adds a data point to a CloudWatch Metric named 'Status' with dimensions: instanceid, servicename
$runningServices | % {
$dimensions = @();
$serviceDimension = New-Object -TypeName Amazon.CloudWatch.Model.Dimension;
$serviceDimension.Name = "service"
$serviceDimension.Value = $_.Name;
$dimensions += $instanceDimension;
$dimensions += $serviceDimension;
$metric = New-Object -TypeName Amazon.CloudWatch.Model.MetricDatum;
$metric.Timestamp = [DateTime]::UtcNow;
$metric.MetricName = 'Status';
$metric.Value = 1;
$metric.Dimensions = $dimensions;
$metrics += $metric;
Write-Host "Checking status for: $($_.Name)"
}
# Write all of the metrics for this run of the job at once, to save on costs for calling the CloudWatch API.
# This will fail if there are too many services in metrics collection; if this happens, just reduce the amount of
# services monitored, or edit this line into the above foreach loop and write each metric directly.
Write-CWMetricData -Namespace $Namespace -MetricData $metrics
Write-Host "Sleeping for $Period seconds."
Start-Sleep -s $Period
}
Save this to a file and you can run it from the command line to begin writing metrics. Once you're comfortable with it, feel free to ditch the "while true" loop for a scheduled task or powershell job.
Additional Resources:
- AWS Documentation - Scenario: Publish Metrics to CloudWatch - A tutorial/walkthrough for publishing custom metrics for a hypothetical application. This would be a good place to get started learning how to publish your own custom metrics.
- AWS Documentation - Publish Custom Metrics
- MSDN - Get-Service Cmdlet Reference
- AWS Tools For PowerShell Documentation - Write-CWMetricData
Answered By - Anthony Neace Answer Checked By - Dawn Plyler (WPSolving Volunteer)