OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Author: Chris Moyer <cmoyer@newstex.com> |
| 3 # Description: CloudWatch Utility |
| 4 # For listing stats, creating alarms, and managing |
| 5 # other CloudWatch aspects |
| 6 |
| 7 import boto |
| 8 cw = boto.connect_cloudwatch() |
| 9 |
| 10 from datetime import datetime, timedelta |
| 11 |
| 12 def _parse_time(time_string): |
| 13 """Internal function to parse a time string""" |
| 14 |
| 15 def _parse_dict(d_string): |
| 16 result = {} |
| 17 if d_string: |
| 18 for d in d_string.split(","): |
| 19 d = d.split(":") |
| 20 result[d[0]] = d[1] |
| 21 return result |
| 22 |
| 23 def ls(namespace=None): |
| 24 """ |
| 25 List metrics, optionally filtering by a specific namespace |
| 26 namespace: Optional Namespace to filter on |
| 27 """ |
| 28 print "%-10s %-50s %s" % ("Namespace", "Metric Name", "Dimensions") |
| 29 print "-"*80 |
| 30 for m in cw.list_metrics(): |
| 31 if namespace is None or namespace.upper() in m.namespace: |
| 32 print "%-10s %-50s %s" % (m.namespace, m.name, m.dimensions) |
| 33 |
| 34 def stats(namespace, metric_name, dimensions=None, statistics="Average", start_t
ime=None, end_time=None, period=60, unit=None): |
| 35 """ |
| 36 Lists the statistics for a specific metric |
| 37 namespace: The namespace to use, usually "AWS/EC2", "AWS/SQS", etc. |
| 38 metric_name: The name of the metric to track, pulled from `ls` |
| 39 dimensions: The dimensions to use, formatted as Name:Value (such as Queu
eName:myQueue) |
| 40 statistics: The statistics to measure, defaults to "Average" |
| 41 'Minimum', 'Maximum', 'Sum', 'Average', 'SampleCount' |
| 42 start_time: Start time, default to now - 1 day |
| 43 end_time: End time, default to now |
| 44 period: Period/interval for counts, default to 60 minutes |
| 45 unit: Unit to track, default depends on what metric is being tracked |
| 46 """ |
| 47 |
| 48 # Parse the dimensions |
| 49 dimensions = _parse_dict(dimensions) |
| 50 |
| 51 # Parse the times |
| 52 if end_time: |
| 53 end_time = _parse_time(end_time) |
| 54 else: |
| 55 end_time = datetime.utcnow() |
| 56 if start_time: |
| 57 start_time = _parse_time(start_time) |
| 58 else: |
| 59 start_time = datetime.utcnow() - timedelta(days=1) |
| 60 |
| 61 print "%-30s %s" % ('Timestamp', statistics) |
| 62 print "-"*50 |
| 63 data = {} |
| 64 for m in cw.get_metric_statistics(int(period), start_time, end_time, metric_
name, namespace, statistics, dimensions, unit): |
| 65 data[m['Timestamp']] = m[statistics] |
| 66 keys = data.keys() |
| 67 keys.sort() |
| 68 for k in keys: |
| 69 print "%-30s %s" % (k, data[k]) |
| 70 |
| 71 def put(namespace, metric_name, dimensions=None, value=None, unit=None, statisti
cs=None, timestamp=None): |
| 72 """ |
| 73 Publish custom metrics |
| 74 namespace: The namespace to use; values starting with "AWS/" are reserve
d |
| 75 metric_name: The name of the metric to update |
| 76 dimensions: The dimensions to use, formatted as Name:Value (such as Queu
eName:myQueue) |
| 77 value: The value to store, mutually exclusive with `statistics` |
| 78 statistics: The statistics to store, mutually exclusive with `value` |
| 79 (must specify all of "Minimum", "Maximum", "Sum", "SampleCount") |
| 80 timestamp: The timestamp of this measurement, default is current server
time |
| 81 unit: Unit to track, default depends on what metric is being tracked |
| 82 """ |
| 83 |
| 84 def simplify(lst): |
| 85 return lst[0] if len(lst) == 1 else lst |
| 86 |
| 87 print cw.put_metric_data(namespace, simplify(metric_name.split(';')), |
| 88 dimensions = simplify(map(_parse_dict, dimensions.split(';'))) if dimens
ions else None, |
| 89 value = simplify(value.split(';')) if value else None, |
| 90 statistics = simplify(map(_parse_dict, statistics.split(';'))) if statis
tics else None, |
| 91 timestamp = simplify(timestamp.split(';')) if timestamp else None, |
| 92 unit = simplify(unit.split(';')) if unit else None) |
| 93 |
| 94 def help(fnc=None): |
| 95 """ |
| 96 Print help message, optionally about a specific function |
| 97 """ |
| 98 import inspect |
| 99 self = sys.modules['__main__'] |
| 100 if fnc: |
| 101 try: |
| 102 cmd = getattr(self, fnc) |
| 103 except: |
| 104 cmd = None |
| 105 if not inspect.isfunction(cmd): |
| 106 print "No function named: %s found" % fnc |
| 107 sys.exit(2) |
| 108 (args, varargs, varkw, defaults) = inspect.getargspec(cmd) |
| 109 print cmd.__doc__ |
| 110 print "Usage: %s %s" % (fnc, " ".join([ "[%s]" % a for a in args])) |
| 111 else: |
| 112 print "Usage: cwutil [command]" |
| 113 for cname in dir(self): |
| 114 if not cname.startswith("_") and not cname == "cmd": |
| 115 cmd = getattr(self, cname) |
| 116 if inspect.isfunction(cmd): |
| 117 doc = cmd.__doc__ |
| 118 print "\t%s - %s" % (cname, doc) |
| 119 sys.exit(1) |
| 120 |
| 121 |
| 122 if __name__ == "__main__": |
| 123 import sys |
| 124 self = sys.modules['__main__'] |
| 125 if len(sys.argv) >= 2: |
| 126 try: |
| 127 cmd = getattr(self, sys.argv[1]) |
| 128 except: |
| 129 cmd = None |
| 130 args = sys.argv[2:] |
| 131 else: |
| 132 cmd = help |
| 133 args = [] |
| 134 if not cmd: |
| 135 cmd = help |
| 136 try: |
| 137 cmd(*args) |
| 138 except TypeError, e: |
| 139 print e |
| 140 help(cmd.__name__) |
OLD | NEW |