monasca-agent/monagent/forwarder/api/mon.py

106 lines
3.9 KiB
Python

import logging
from monclient import exc as exc, client
from monagent.common.keystone import Keystone
from monagent.common.util import get_hostname
log = logging.getLogger(__name__)
class MonAPI(object):
"""Sends measurements to MonAPI
Any errors should raise an exception so the transaction calling
this is not committed
"""
def __init__(self, config):
"""
Initialize Mon api client connection.
"""
self.config = config
self.url = config['url']
self.api_version = '2_0'
self.default_dimensions = config['dimensions']
self.token_expiration = 1438
# Verify the hostname is set as a dimension
if not 'hostname' in self.default_dimensions:
self.default_dimensions['hostname'] = get_hostname()
log.debug("Getting token from Keystone")
self.keystone_url = config['keystone_url']
self.username = config['username']
self.password = config['password']
self.project_name = config['project_name']
self.keystone = Keystone(self.keystone_url,
self.username,
self.password,
self.project_name)
self.mon_client = None
def _post(self, measurements):
"""Does the actual http post
measurements is a list of Measurement
"""
data = [m.__dict__ for m in measurements]
kwargs = {
'jsonbody': data
}
try:
if not self.mon_client:
# construct the mon client
self.mon_client = self.get_client()
done = False
while not done:
response = self.mon_client.metrics.create(**kwargs)
if 200 <= response.status_code <= 299:
# Good status from web service
log.debug("Message sent successfully: {0}"
.format(str(data)))
elif 400 <= response.status_code <= 499:
# Good status from web service but some type of issue
# with the data
if response.status_code == 401:
# Get a new token/client and retry
self.mon_client = self.get_client()
continue
else:
error_msg = "Successful web service call but there" + \
" were issues (Status: {0}, Status Message: " + \
"{1}, Message Content: {1})"
log.error(error_msg.format(response.status_code,
response.reason, response.text))
response.raise_for_status()
else: # Not a good status
response.raise_for_status()
done = True
except exc.HTTPException as he:
log.error("Error sending message to mon-api: {0}"
.format(str(he.message)))
def post_metrics(self, measurements):
"""post_metrics
given [Measurement, ...], format the request and post to
the monitoring api
"""
# Add default dimensions
for measurement in measurements:
for dimension in self.default_dimensions.keys():
if not measurement.dimensions.has_key(dimension):
measurement.dimensions.update({dimension: self.default_dimensions[dimension]})
self._post(measurements)
def get_client(self):
"""get_client
get a new mon-client object
"""
token = self.keystone.refresh_token()
# Re-create the client. This is temporary until
# the client is updated to be able to reset the
# token.
kwargs = {
'token': token
}
return client.Client(self.api_version, self.url, **kwargs)