diff options
author | rafael81 <jcm1981@gmail.com> | 2013-01-03 08:40:52 +0000 |
---|---|---|
committer | rafael81 <jcm1981@gmail.com> | 2013-01-03 08:40:52 +0000 |
commit | 8b5e195bf9dfdbc5260456e07261ca9e9637c35c (patch) | |
tree | 52efc873b27a063013e1b13dce39a5feaac54af1 | |
parent | 16960bf118cc4bd21a3bace837000cbc624ef9cf (diff) | |
download | logster-8b5e195bf9dfdbc5260456e07261ca9e9637c35c.zip logster-8b5e195bf9dfdbc5260456e07261ca9e9637c35c.tar.gz logster-8b5e195bf9dfdbc5260456e07261ca9e9637c35c.tar.bz2 |
add new feature for Amazon Web Service CloudWatch
-rwxr-xr-x | bin/logster | 36 | ||||
-rw-r--r-- | logster/logster_helper.py | 58 |
2 files changed, 87 insertions, 7 deletions
diff --git a/bin/logster b/bin/logster index bd77b43..5b1d819 100755 --- a/bin/logster +++ b/bin/logster @@ -50,20 +50,22 @@ import logging.handlers import fcntl import socket import traceback +import time -from time import time from math import floor # Local dependencies -from logster.logster_helper import LogsterParsingException, LockingError +from logster.logster_helper import LogsterParsingException, LockingError, CloudWatch # Globals gmetric = "/usr/bin/gmetric" logtail = "/usr/sbin/logtail2" log_dir = "/var/log/logster" state_dir = "/var/run" +aws_key = '' +aws_secret_key = '' -script_start_time = time() +script_start_time = time.time() # Command-line options and parsing. cmdline = optparse.OptionParser(usage="usage: %prog [options] parser logfile", @@ -88,8 +90,8 @@ cmdline.add_option('--graphite-host', action='store', cmdline.add_option('--state-dir', '-s', action='store', default=state_dir, help='Where to store the logtail state file. Default location %s' % state_dir) cmdline.add_option('--output', '-o', action='append', - choices=('graphite', 'ganglia', 'stdout'), - help="Where to send metrics (can specify multiple times). Choices are 'graphite', 'ganglia', or 'stdout'.") + choices=('graphite', 'ganglia', 'stdout', 'cloudwatch'), + help="Where to send metrics (can specify multiple times). Choices are 'graphite', 'ganglia', 'cloudwatch' or 'stdout'.") cmdline.add_option('--stdout-separator', action='store', default="_", dest="stdout_separator", help='Seperator between prefix/suffix and name for stdout. Default is \"%default\".') cmdline.add_option('--dry-run', '-d', action='store_true', default=False, @@ -151,6 +153,8 @@ def submit_stats(parser, duration, options): submit_graphite(metrics, options) if 'stdout' in options.output: submit_stdout(metrics, options) + if 'cloudwatch' in options.output: + submit_cloudwatch(metrics, options) def submit_stdout(metrics, options): for metric in metrics: @@ -205,6 +209,24 @@ def submit_graphite(metrics, options): if (not options.dry_run): s.close() +def submit_cloudwatch(metrics, options): + for metric in metrics: + + if (options.metric_prefix != ""): + metric.name = options.metric_prefix + "." + metric.name + if (options.metric_suffix is not None): + metric.name = metric.name + "." + options.metric_suffix + + metric.timestamp = time.strftime("%Y%m%dT%H:%M:00Z", time.gmtime(metric.timestamp)) + metric.units = "None" + metric_string = "%s %s %s" % (metric.name, metric.value, metric.timestamp) + logger.debug("Submitting CloudWatch metric: %s" % metric_string) + + if (not options.dry_run): + cw = CloudWatch(aws_key, aws_secret_key, metric) + cw.put_data() + else: + print metric_string def start_locking(lockfile_name): """ Acquire a lock via a provided lockfile filename. """ @@ -275,7 +297,7 @@ def main(): state_file_age = os.stat(logtail_state_file)[stat.ST_MTIME] # Calculate now() - state file age to determine check duration. - duration = floor(time()) - floor(state_file_age) + duration = floor(time.time()) - floor(state_file_age) logger.debug("Setting duration to %s seconds." % duration) except OSError, e: @@ -320,7 +342,7 @@ def main(): sys.exit(1) # Log the execution time - exec_time = round(time() - script_start_time, 1) + exec_time = round(time.time() - script_start_time, 1) logger.info("Total execution time: %s seconds." % exec_time) # Set mtime and atime for the state file to the startup time of the script diff --git a/logster/logster_helper.py b/logster/logster_helper.py index c8b3ca1..8846c8f 100644 --- a/logster/logster_helper.py +++ b/logster/logster_helper.py @@ -19,6 +19,13 @@ ### along with Logster. If not, see <http://www.gnu.org/licenses/>. ### +import os +import httplib +import base64 +import hashlib +import hmac + +from urllib import urlencode, quote_plus from time import time class MetricObject(object): @@ -51,3 +58,54 @@ class LockingError(Exception): """ Exception raised for errors creating or destroying lockfiles. """ pass +class CloudWatch: + """ Specify Amazon CloudWatch params """ + def __init__(self, key, secret_key, metric): + conn = httplib.HTTPConnection("169.254.169.254") + conn.request("GET", "/latest/meta-data/instance-id") + instance_id = conn.getresponse().read() + print "instance-id = %s" % instance_id + + self.base_url = "monitoring.ap-northeast-1.amazonaws.com" + self.key = os.getenv('AWS_ACCESS_KEY_ID', key) + self.secret_key = os.getenv('AWS_SECRET_ACCESS_KEY_ID', secret_key) + self.params = {'Namespace': 'logster', + 'MetricData.member.1.MetricName': metric.name, + 'MetricData.member.1.Value': metric.value, + 'MetricData.member.1.Unit': metric.units, + 'MetricData.member.1.Dimensions.member.1.Name': 'InstanceID', + 'MetricData.member.1.Dimensions.member.1.Value': instance_id} + + self.url_params = self.params + self.url_params['AWSAccessKeyId'] = self.key + self.url_params['Action'] = 'PutMetricData' + self.url_params['SignatureMethod'] = 'HmacSHA256' + self.url_params['SignatureVersion'] = '2' + self.url_params['Version'] = '2010-08-01' + self.url_params['Timestamp'] = metric.timestamp + + def get_signed_url(self): + """ build signed parameters following http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_PutMetricData.html """ + keys = self.url_params.keys() + keys.sort() + values = map(self.url_params.get, keys) + url_string = urlencode(zip(keys,values)) + + string_to_sign = "GET\n%s\n/\n%s" % (self.base_url, url_string) + signature = hmac.new( key=self.secret_key, msg=string_to_sign, digestmod=hashlib.sha256).digest() + signature = base64.encodestring(signature).strip() + urlencoded_signature = quote_plus(signature) + url_string += "&Signature=%s" % urlencoded_signature + + return "/?" + url_string + + def put_data(self): + signedURL = self.get_signed_url() + print signedURL + conn = httplib.HTTPConnection(self.base_url) + conn.request("GET", signedURL) + res = conn.getresponse() + print res.status, res.reason + print res.getheaders() + print res.read() + |