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