· 9 years ago · Jan 09, 2017, 11:12 PM
1[cloudwatch]
2namespace: EC2: MY SERVER
3access_id: ADD-ACCESS-KEY-HERE ;;; leave blank if using an EC2 role
4secret_key: ADD-SECRET-KEY-HERE ;;; leave blank if using an EC2 role
5
6;;; Each disk value is a metric name and a directory
7[disk-metrics]
8disk-usage-root: /
9disk-usage-content1: /files
10disk-usage-content2: /files2
11
12[memory-metrics]
13swap-metric: memory-swap-usage
14ram-metric: memory-ram-usage
15
16#!/usr/bin/env python
17import sys
18import re
19import os
20import boto.ec2
21from boto.utils import get_instance_metadata
22import ConfigParser
23
24# Configuration file is required
25oConfig = ConfigParser.RawConfigParser()
26sConfigPath = os.path.dirname(os.path.realpath(sys.argv[0])) + '/config.ini'
27if os.path.isfile(sConfigPath) == False:
28 sys.exit('Missing configuration file: ' + sConfigPath)
29oConfig.read(sConfigPath)
30
31# Get the configuration elements
32AWS_ACCESS_ID = oConfig.get('cloudwatch', 'access_id')
33AWS_SECRET_KEY = oConfig.get('cloudwatch', 'secret_key')
34METRICS_NAMESPACE = oConfig.get('cloudwatch', 'namespace')
35MONITOR_DISKS = oConfig.items('disk-metrics')
36RAM_METRIC = oConfig.get('memory-metrics', 'ram-metric')
37SWAP_METRIC = oConfig.get('memory-metrics', 'swap-metric')
38
39
40def getDiskUsage(sPath):
41 """Return disk-usage percentage for a given directory"""
42 oStat = os.statvfs(sPath)
43 iTotal = (oStat.f_blocks * oStat.f_frsize)
44 iUsed = (oStat.f_blocks - oStat.f_bfree) * oStat.f_frsize
45 try:
46 fPercent = (float(iUsed) / iTotal) * 100
47 except ZeroDivisionError:
48 fPercent = 0
49 return round(fPercent, 1)
50
51
52def getAllDiskUsage(aDiskConfig):
53 """Get the disk usage for multiple directories"""
54 aUsage = []
55 for aDisk in aDiskConfig:
56 sName, sDir = aDisk
57 iUsage = getDiskUsage(sDir)
58 aUsage.append((sName, sDir, iUsage))
59 return aUsage
60
61
62def collectMemoryUsage():
63 """Return the memory usage for the current server"""
64 aMemInfo = {}
65 rePattern = re.compile('([w()]+):s*(d+)(:?s*(w+))?')
66 with open('/proc/meminfo') as fp:
67 for sLine in fp:
68 match = rePattern.match(sLine)
69 if match:
70 aMemInfo[match.group(1)] = float(match.group(2))
71 return aMemInfo
72
73
74def sendMetrics(oBoto, sInstanceId, aMetrics, sNameSpace, sUnit):
75 """Send metrics to CloudWatch - Metrics are sent in key-value pairs"""
76 aKeys = aMetrics.keys()
77 aValues = aMetrics.values()
78 print "Setting metric - namespace:%s server:%s name:%s value:%s unit:%s" %
79 (sNameSpace, sInstanceId, aKeys[0], aValues[0], sUnit)
80 oBoto.put_metric_data(sNameSpace, aKeys, aValues, unit=sUnit, dimensions={"InstanceId": sInstanceId})
81
82
83def getBoto (sAccessId, sSecretKey):
84 """"Get the Boto connection, using the default role if the ID and Key are not set"""
85 if re.search('w', sAccessId) and re.search('w', sSecretKey):
86 oBoto = boto.connect_cloudwatch(aws_access_key_id=sAccessId, aws_secret_access_key=sSecretKey)
87 else:
88 oBoto = boto.connect_cloudwatch()
89 return oBoto
90
91
92def getMemoryUsage(sRamMetric, sSwapMetric):
93 """Get the memory usage for the server"""
94
95 aMemInfo = collectMemoryUsage()
96
97 # Total free memory = free + buffers + cached
98 iMemFree = aMemInfo['MemFree'] + aMemInfo['Buffers'] + aMemInfo['Cached']
99 iMemUsed = aMemInfo['MemTotal'] - iMemFree
100
101 if aMemInfo['SwapTotal'] != 0 :
102 iSwapUsed = aMemInfo['SwapTotal'] - aMemInfo['SwapFree'] - aMemInfo['SwapCached']
103 fSwapPercent = iSwapUsed / aMemInfo['SwapTotal'] * 100
104 else:
105 fSwapPercent = 0.0
106
107 return [ ('memory-ram-usage', round (iMemUsed / aMemInfo['MemTotal'] * 100, 1)),
108 ('memory-swap-usage', round(fSwapPercent, 1)) ]
109
110
111def getInstanceId():
112 """Get the instance ID for the current server"""
113 aMetaData = get_instance_metadata()
114 return aMetaData['instance-id']
115
116
117# Primary execution
118if __name__ == '__main__':
119
120 sInstanceId = getInstanceId()
121 oBoto = getBoto(AWS_ACCESS_ID, AWS_SECRET_KEY)
122
123 for aUsage in getAllDiskUsage(MONITOR_DISKS):
124 sMetricName, sDir, fPercent = aUsage
125 print "Disk usage - %-25s percentage: %0.1f%% directory: %s" % (sMetricName, fPercent, sDir)
126 sendMetrics(oBoto, sInstanceId, { sMetricName: fPercent }, METRICS_NAMESPACE, 'Percent')
127
128 for aUsage in getMemoryUsage(RAM_METRIC, SWAP_METRIC):
129 sMetricName, fPercent = aUsage
130 print "Memory usage - %-25s percentage: %0.1f%%" % (sMetricName, fPercent)
131 sendMetrics(oBoto, sInstanceId, { sMetricName: fPercent }, METRICS_NAMESPACE, 'Percent')