uptime function in gauge given a parameter of billable states (will be renamed to tracked later). Also some code clean up and formatting done.

This commit is contained in:
adriant 2014-01-15 15:05:53 +13:00
parent 8751f45163
commit 5cb1ba97f3
2 changed files with 48 additions and 24 deletions

View File

@ -604,21 +604,23 @@ class Gauge(Artifact):
# print totals
return sum(totals)
def uptime(self):
def uptime(self, billable):
"""Calculates uptime accurately for the given 'billable' states.
Will ignore all other states.
- Relies heavily on the existence of a state meter."""
- Will ignore all other states.
- Relies heavily on the existence of a state meter, and
should only ever be called on the state meter.
# this NEEDS to be moved to a config file
billable = [1, 2, 3, 6, 7]
Returns: uptime in seconds"""
usage = sorted(self.usage, key=lambda x: x["timestamp"])
last = usage[0]
try:
last["timestamp"] = datetime.datetime.strptime(last["timestamp"], date_format)
last["timestamp"] = datetime.datetime.strptime(last["timestamp"],
date_format)
except ValueError:
last["timestamp"] = datetime.datetime.strptime(last["timestamp"], other_date_format)
last["timestamp"] = datetime.datetime.strptime(last["timestamp"],
other_date_format)
except TypeError:
pass
@ -626,14 +628,27 @@ class Gauge(Artifact):
for val in usage[1:]:
try:
val["timestamp"] = datetime.datetime.strptime(val["timestamp"], date_format)
val["timestamp"] = datetime.datetime.strptime(val["timestamp"],
date_format)
except ValueError:
val["timestamp"] = datetime.datetime.strptime(val["timestamp"], other_date_format)
val["timestamp"] = datetime.datetime.strptime(val["timestamp"],
other_date_format)
except TypeError:
pass
if val["counter_volume"] in billable:
difference = val["timestamp"] - last["timestamp"]
# TODO:
# possibly might need to account for sudden jumps
# caused due to ceilometer down time:
if difference > datetime.timedelta(hours=1):
# the timedelta should be the ceilometer interval.
# do nothing if different greater than twice interval?
# or just add interval length to uptime.
pass
else:
# otherwise just add difference.
uptime = uptime + difference.seconds
last = val

View File

@ -5,6 +5,7 @@ from sqlalchemy.orm import relationship, backref
from decimal import *
import math
class Resource(Base):
__tablename__ = "resources"
@ -33,8 +34,8 @@ class BaseModelConstruct(object):
def get(self, name):
# Returns a given name value thing?
# Based on patterning, this is expected to be a dict of usage information
# based on a meter, I guess?
# Based on patterning, this is expected to be a dict of usage
# information based on a meter, I guess?
return getattr(self, name)
def _fetch_meter_name(self, name):
@ -68,7 +69,8 @@ class VM(BaseModelConstruct):
# The only relevant meters of interest are the type of the interest
# and the amount of network we care about.
# Oh, and floating IPs.
relevant_meters = ["state", "instance", "cpu", "instance:<type>", "network.incoming.bytes", "network.outgoing.bytes"]
relevant_meters = ["state", "instance", "cpu", "instance:<type>",
"network.incoming.bytes", "network.outgoing.bytes"]
def _fetch_meter_name(self, name):
if name == "instance:<type>":
@ -81,7 +83,12 @@ class VM(BaseModelConstruct):
@property
def amount(self):
seconds = self.usage()['state'].uptime()
# this NEEDS to be moved to a config file or
# possibly be queried from Clerk?
billable = [1, 2, 3, 6, 7]
seconds = self.usage()['state'].uptime(billable)
# in hours, rounded up:
uptime = math.ceil((seconds / 60.0) / 60.0)
@ -100,8 +107,8 @@ class VM(BaseModelConstruct):
@property
def type(self):
# TODO FIgure out what the hell is going on with ceilometer here,
# and why flavor.name isn't always there, and why sometimes instance_type
# is needed instead....
# and why flavor.name isn't always there, and why
# sometimes instance_type is needed instead....
try:
# print "\"flavor.name\" was used"
return self._raw["metadata"]["flavor.name"]
@ -139,6 +146,7 @@ class VM(BaseModelConstruct):
def name(self):
return self._raw["metadata"]["display_name"]
class Object(BaseModelConstruct):
relevant_meters = ["storage.objects.size"]
@ -148,12 +156,12 @@ class Object(BaseModelConstruct):
@property
def size(self):
# How much use this had.
return self._raw.meter("storage.objects.size", self.start, self.end).volume()
return self._raw.meter("storage.objects.size",
self.start, self.end).volume()
# Size is a gauge measured every 10 minutes.
# So that needs to be compressed to 60-minute intervals
class Volume(BaseModelConstruct):
relevant_meters = ["volume.size"]
@ -167,5 +175,6 @@ class Volume(BaseModelConstruct):
# Size of the thing over time.
return self._raw.meter("volume.size", self.start, self.end).volume()
class Network(BaseModelConstruct):
relevant_meters = ["ip.floating"]