Mackerelã§EC2ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®ä¾¡æ ¼å¤åãç£è¦ãã
ã¾ããã
Mackerel Advent Calendar 2015 12æ13æ¥ã®è¨äºã§ãã
æ¨æ¥ã¯ la_luna_azul ããã§ãããOre no homepageã¯ããåèã«ããã¦ããã£ã¦ã¾ãï¼
go-check-pluginsを勝手に解説 – Mackerelアドベントカレンダー12日目 | Ore no homepage
ä»æ¥ã®ã«ã¬ã³ãã¼ããã¾ãã¾ç©ºãã¦ããã®ã§ãããã¾ã§ç¶ããã®ãéåããã®ããªãããã£ãããªããªã¨æã£ã¦åå ãã¦ã¿ã¾ããã
ãã®è¨äºã§ã¯ãAWSã®APIããEC2ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®ä¾¡æ ¼ãåå¾ããMackerelã«ãµã¼ãã¹ã¡ããªãã¯ã¨ãã¦éä¿¡ããæ¹æ³ãç´¹ä»ãã¾ãã
使ç¨ããã©ã¤ãã©ãªã¼ã«ã¤ãã¦
Python3ã使ãã¾ãã®ã§ãAWS APIã¨ã®é£æºã«ã¯boto3ãMackerelã¨ã®é£æºã«ã¯mackerel.clientã使ç¨ãã¾ã
ç°å¢æ§ç¯ã«ã¤ãã¦ã詳ãã説æã¯å²æãã¾ãããboto3, mackerel.clientã¨ãã«pipã§ã¤ã³ã¹ãã¼ã«ã§ãã¾ãã
Rubyã§rbenvãRVMã使ç¨ããããã«ãPythonã§ã¯Virtualenvã使ç¨ããã®ãè¯ãã§ãããã
Virtualenvã使ãåæã«ã¯ãªãã¾ããã以ä¸ã®ã³ãã³ãã§ãã®è¨äºã§ä½¿ç¨ããã³ã¼ããåããç°å¢ãä½ããã¨æãã¾ãã
$ virtualenv -p python3 .venv $ source .venv/bin/activate $ pip install boto3 mackerel.client
ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®ä¾¡æ ¼ãåå¾ãã
ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®ä¾¡æ ¼ã¯EC2 APIã®DescribeSpotPriceHistoryã使ãã¨åå¾ã§ãã¾ãã
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSpotPriceHistory.html
boto3ã使ç¨ãã¦AWSæ±äº¬ãªã¼ã¸ã§ã³ã®ã¹ãããã¤ã³ã¹ã¿ã³ã¹ä¾¡æ ¼ãåå¾ããã«ã¯ã以ä¸ã®ãããªã³ã¼ãã«ãªãã¾ã
import boto3 access_key_id = 'AWSã®ã¢ã¯ã»ã¹ãã¼' secret_access_key = 'AWSã®ã·ã¼ã¯ã¬ãããã¼' region_name = 'ap-northeast-1' # AWSã®ãªã¼ã¸ã§ã³å boto3_session = boto3.session.Session(aws_access_key_id=access_key_id, aws_secret_access_key=secret_access_key, region_name=region_name) ec2_client = boto3_session.client('ec2') spot_price_history = ec2_client.describe_spot_price_history() for history in spot_price_history.get('SpotPriceHistory'): print(history)
ãã®ã³ã¼ããå®è¡ããã¨ä»¥ä¸ã®ãããªçµæã表示ããã¾ãã
$ python boto3_example.py {'SpotPrice': '0.087700', 'Timestamp': datetime.datetime(2015, 12, 13, 8, 21, 25, tzinfo=tzutc()), 'AvailabilityZone': 'ap-northeast-1b', 'InstanceType': 'm2.4xlarge', 'ProductDescription': 'Linux/UNIX'} {'SpotPrice': '0.126400', 'Timestamp': datetime.datetime(2015, 12, 13, 8, 21, 13, tzinfo=tzutc()), 'AvailabilityZone': 'ap-northeast-1c', 'InstanceType': 'c3.2xlarge', 'ProductDescription': 'Linux/UNIX'} {'SpotPrice': '0.419200', 'Timestamp': datetime.datetime(2015, 12, 13, 8, 21, 11, tzinfo=tzutc()), 'AvailabilityZone': 'ap-northeast-1c', 'InstanceType': 'c3.2xlarge', 'ProductDescription': 'Windows'} {'SpotPrice': '0.104200', 'Timestamp': datetime.datetime(2015, 12, 13, 8, 21, 8, tzinfo=tzutc()), 'AvailabilityZone': 'ap-northeast-1c', 'InstanceType': 'd2.xlarge', 'ProductDescription': 'Linux/UNIX'} {'SpotPrice': '0.091900', 'Timestamp': datetime.datetime(2015, 12, 13, 8, 21, 8, tzinfo=tzutc()), 'AvailabilityZone': 'ap-northeast-1b', 'InstanceType': 'd2.xlarge', 'ProductDescription': 'Linux/UNIX'} ...
ãã®ã¾ã¾ã§ã¯Availability Zoneãã¤ã³ã¹ã¿ã³ã¹ã¿ã¤ããªã©ã§ã®çµãè¾¼ã¿ãã§ãã¦ãã¾ãããããã®ãããªæ¡ä»¶ã§ãã£ã«ã¿ãªã³ã°ãããã¨ãã§ããã®ã§å¾è¿°ãã¾ãã
Mackerelã¨é£æºãã
ãªã¼ã¬ãã¼ã¼ã·ã§ã³ã«ãµã¼ãã¹ã追å ãã
ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®ä¾¡æ ¼ããµã¼ãã¹ã¡ããªãã¯ã¨ãã¦è¨é²ããããã«ããªã¼ã¬ãã¼ã¼ã·ã§ã³ã«ãµã¼ãã¹ã追å ãã¾ãã
ãµã¼ãã¹ã®ç»é²æ¹æ³ã«ã¤ãã¦ã¯11æ¥ç®ã®è¨äºãMackerelã使ã£ã¦Twitterãç£è¦ãã¦ã¿ããã§ãæé ãç´¹ä»ããã¦ãã¾ãã®ã§ããã®è¨äºã§ã¯å²æãã¾ãã
mackerel.clientã使ã
mackerel.clientã«ã¤ãã¦ãã11æ¥ç®ã®è¨äºã§ç´¹ä»ããã¦ããã®ã§ããããã£ãããªã®ã§mackerel.clientã®ãµã³ãã«ãç´¹ä»ãã¾ãã
以ä¸ã®ã³ã¼ãã¯ãmackerel.clientã使ç¨ãã¦ãå ¬å¼ãã«ãã®ãã¹ãã®ã«ã¹ã¿ã ã¡ããªãã¯ãæ稿ããã¨åãããã«6é¢ãã¤ã¹ã20é¢ãã¤ã¹ã®çµæããµã¼ãã¹ã¡ããªãã¯ã¨ãã¦éä¿¡ãã¾ãã
import random import time import mackerel.client api_key = 'Mackerelã®APIãã¼' service_name = 'Mackerelã®ãªã¼ã¬ãã¼ã¼ã·ã§ã³ã«è¿½å ãããµã¼ãã¹å' timestamp = int(time.time()) metrics = [ {'name': 'test.mackerel_client.dice6', 'value': random.randint(1, 6), 'time': timestamp}, {'name': 'test.mackerel_client.dice20', 'value': random.randint(1, 20), 'time': timestamp}, ] mackerel_client = mackerel.client.Client(mackerel_api_key=api_key) mackerel_client.post_service_metrics(service_name, metrics)
ä¸è¨ã®ã³ã¼ããå®æçã«å®è¡ããã¨ã以ä¸ã®ããã«Mackerelä¸ã§ãµã¼ãã¹ã¡ããªãã¯ã®ã°ã©ããè¦ããã¨ãã§ãã¾ãã
boto3ã¨mackerel.clientãçµã¿åããã
ãã¦ãboto3ã¨mackerel.clientã®ä½¿ãæ¹ãããã£ãã®ã§ãçµã¿åããã¦ã¿ã¾ãããã
import time from datetime import datetime, timedelta import boto3 import mackerel.client def metric_exists(instance_type, availability_zone, metrics): for metric in metrics: if metric.get('name') == 'ec2_spot_price_history.{0}.{1}'.format(availability_zone, instance_type): return True return False def build_metric_name(availability_zone, instance_type): return 'ec2_spot_price_history.{0}.{1}'.format(availability_zone, instance_type) def build_metric(instance_type, availability_zone, spot_price, timestamp): return { 'name': build_metric_name(availability_zone, instance_type), 'time': timestamp, 'value': spot_price, } aws_access_key_id = 'AWSã®ã¢ã¯ã»ã¹ãã¼' aws_secret_access_key = 'AWSã®ã·ã¼ã¯ã¬ãããã¼' region_name = 'ap-northeast-1' # AWSã®ãªã¼ã¸ã§ã³å aws_availability_zone = 'ap-northeast-1c' # AWSã®AZå mackerel_api_key = 'Mackerelã®APIãã¼' mackerel_service_name = 'Mackerelã®ãªã¼ã¬ãã¼ã¼ã·ã§ã³ã«è¿½å ãããµã¼ãã¹å' boto3_session = boto3.session.Session(aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=aws_region_name) boto3_client = boto3_session.client('ec2') ec2_instance_types = [ 'c4.large', 'c4.xlarge', 'c4.2xlarge', 'c4.4xlarge', ] # ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®ä¾¡æ ¼å±¥æ´ãAZ, ã¤ã³ã¹ã¿ã³ã¹ã¿ã¤ã, OSã¿ã¤ãã§çµãè¾¼ã filters = [ {'Name': 'availability-zone', 'Values': [aws_availability_zone]}, {'Name': 'instance-type', 'Values': ec2_instance_types}, {'Name': 'product-description', 'Values': ['Linux/UNIX']}, ] timestamp = int(time.time()) one_min_ago = datetime.now() - timedelta(minutes=1) # ã¹ãããã¤ã³ã¹ã¿ã³ã¹ã®å±¥æ´ãåå¾ # ç´è¿ã®å¤ãåå¾ãããããéå§æ¥æã1ååã®æ¥æã¨ãã spot_price_history = boto3_client \ .describe_spot_price_history(Filters=filters, StartTime=one_min_ago) \ .get('SpotPriceHistory') mackerel_client = mackerel.client.Client(mackerel_api_key=mackerel_api_key) metrics = [] for history in spot_price_history: # ä¾¡æ ¼å±¥æ´ããã¤ã³ã¹ã¿ã³ã¹ã¿ã¤ããªã©ã®æ å ±ãåå¾ # ãã¤ãã³ã¯Mackerelã®ã¡ããªã¯ã¹åã¨ãã¦ä½¿ç¨ã§ããªãã®ã§ãã¢ã³ãã¼ã¹ã³ã¢ã«ç½®æãã instance_type = history.get('InstanceType') aws_availability_zone = history.get('AvailabilityZone').replace('-', '_') spot_price = float(history.get('SpotPrice')) # ãã§ã«ã¡ããªãã¯ããªã¹ãã«åå¨ããå ´åã¯èªã¿é£ã°ã if metric_exists(instance_type, aws_availability_zone, metrics): continue # ã¡ããªãã¯ãæ§ç¯ãã¦ãªã¹ãã«è¿½å metric = build_metric(instance_type, aws_availability_zone, spot_price, timestamp) metrics.append(metric) # æå®ãããµã¼ãã¹åã®ã¡ããªãã¯ã¨ãã¦ä¾¡æ ¼å±¥æ´ãéä¿¡ mackerel_client.post_service_metrics(mackerel_service_name, metrics)
ä¸è¨ã®ã³ã¼ããå®æçã«å®è¡ããã¨ãMackerelä¸ã§ä»¥ä¸ã®æ§ãªã°ã©ããè¦ããã¨ãã§ãã¾ãã
ãµã¼ãã¹ã¡ããªãã¯ã¨ãã¦Mackerelã«éä¿¡ãã¦ãã¾ãã°ãä¾¡æ ¼ã®å¤æ´ãç£è¦ãããã¨ãç°¡åã«ã§ãã¾ãã
Slackãªã©ã®ãµã¼ãã¹ã¨é£æºãããã¨ãç°¡åãªã®ã§ã使ãæ £ãããã¼ã«ã§éç¥ãåãåããã¨ãã§ãã¦ä¾¿å©ããã§ããã
ã¾ã¨ã
æ°è»½ã«ã¡ããªã¯ã¹ãéãã¤ããã ãã§å¯è¦åãç£è¦ãã§ããã®ã§ãMackerel便å©ã§ããï¼
ææ¥ã¯pyama86ããã§ãã