d62fbc9b49
This change isolate storage models used for alarm into a separate file. This a preparation work to have all alarms related storage API inside the alarm namespace and then be able to have a different database for alarming and metering. Partial implements blueprint dedicated-alarm-database Change-Id: Iab6b70c6a48301164016823bd0f8e9781ca21abd
245 lines
9.1 KiB
Python
245 lines
9.1 KiB
Python
#
|
|
# Copyright 2013 New Dream Network, LLC (DreamHost)
|
|
#
|
|
# Author: Doug Hellmann <doug.hellmann@dreamhost.com>
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
"""Model classes for use in the storage API.
|
|
"""
|
|
|
|
from ceilometer.openstack.common import timeutils
|
|
from ceilometer.storage import base
|
|
|
|
|
|
class Event(base.Model):
|
|
"""A raw event from the source system. Events have Traits.
|
|
|
|
Metrics will be derived from one or more Events.
|
|
"""
|
|
|
|
DUPLICATE = 1
|
|
UNKNOWN_PROBLEM = 2
|
|
|
|
def __init__(self, message_id, event_type, generated, traits):
|
|
"""Create a new event.
|
|
|
|
:param message_id: Unique ID for the message this event
|
|
stemmed from. This is different than
|
|
the Event ID, which comes from the
|
|
underlying storage system.
|
|
:param event_type: The type of the event.
|
|
:param generated: UTC time for when the event occurred.
|
|
:param traits: list of Traits on this Event.
|
|
"""
|
|
base.Model.__init__(self, message_id=message_id, event_type=event_type,
|
|
generated=generated, traits=traits)
|
|
|
|
def append_trait(self, trait_model):
|
|
self.traits.append(trait_model)
|
|
|
|
def __repr__(self):
|
|
trait_list = []
|
|
if self.traits:
|
|
trait_list = [str(trait) for trait in self.traits]
|
|
return "<Event: %s, %s, %s, %s>" % \
|
|
(self.message_id, self.event_type, self.generated,
|
|
" ".join(trait_list))
|
|
|
|
|
|
class Trait(base.Model):
|
|
"""A Trait is a key/value pair of data on an Event. The value is variant
|
|
record of basic data types (int, date, float, etc).
|
|
"""
|
|
|
|
NONE_TYPE = 0
|
|
TEXT_TYPE = 1
|
|
INT_TYPE = 2
|
|
FLOAT_TYPE = 3
|
|
DATETIME_TYPE = 4
|
|
|
|
type_names = {
|
|
NONE_TYPE: "none",
|
|
TEXT_TYPE: "string",
|
|
INT_TYPE: "integer",
|
|
FLOAT_TYPE: "float",
|
|
DATETIME_TYPE: "datetime"
|
|
}
|
|
|
|
def __init__(self, name, dtype, value):
|
|
if not dtype:
|
|
dtype = Trait.NONE_TYPE
|
|
base.Model.__init__(self, name=name, dtype=dtype, value=value)
|
|
|
|
def __repr__(self):
|
|
return "<Trait: %s %d %s>" % (self.name, self.dtype, self.value)
|
|
|
|
def get_type_name(self):
|
|
return self.get_name_by_type(self.dtype)
|
|
|
|
@classmethod
|
|
def get_type_by_name(cls, type_name):
|
|
return getattr(cls, '%s_TYPE' % type_name.upper(), None)
|
|
|
|
@classmethod
|
|
def get_type_names(cls):
|
|
return cls.type_names.values()
|
|
|
|
@classmethod
|
|
def get_name_by_type(cls, type_id):
|
|
return cls.type_names.get(type_id, "none")
|
|
|
|
@classmethod
|
|
def convert_value(cls, trait_type, value):
|
|
if trait_type is cls.INT_TYPE:
|
|
return int(value)
|
|
if trait_type is cls.FLOAT_TYPE:
|
|
return float(value)
|
|
if trait_type is cls.DATETIME_TYPE:
|
|
return timeutils.normalize_time(timeutils.parse_isotime(value))
|
|
return str(value)
|
|
|
|
|
|
class Resource(base.Model):
|
|
"""Something for which sample data has been collected.
|
|
"""
|
|
|
|
def __init__(self, resource_id, project_id,
|
|
first_sample_timestamp,
|
|
last_sample_timestamp,
|
|
source, user_id, metadata):
|
|
"""Create a new resource.
|
|
|
|
:param resource_id: UUID of the resource
|
|
:param project_id: UUID of project owning the resource
|
|
:param first_sample_timestamp: first sample timestamp captured
|
|
:param last_sample_timestamp: last sample timestamp captured
|
|
:param source: the identifier for the user/project id definition
|
|
:param user_id: UUID of user owning the resource
|
|
:param metadata: most current metadata for the resource (a dict)
|
|
"""
|
|
base.Model.__init__(self,
|
|
resource_id=resource_id,
|
|
first_sample_timestamp=first_sample_timestamp,
|
|
last_sample_timestamp=last_sample_timestamp,
|
|
project_id=project_id,
|
|
source=source,
|
|
user_id=user_id,
|
|
metadata=metadata,
|
|
)
|
|
|
|
|
|
class Meter(base.Model):
|
|
"""Definition of a meter for which sample data has been collected.
|
|
"""
|
|
|
|
def __init__(self, name, type, unit, resource_id, project_id, source,
|
|
user_id):
|
|
"""Create a new meter.
|
|
|
|
:param name: name of the meter
|
|
:param type: type of the meter (gauge, delta, cumulative)
|
|
:param unit: unit of the meter
|
|
:param resource_id: UUID of the resource
|
|
:param project_id: UUID of project owning the resource
|
|
:param source: the identifier for the user/project id definition
|
|
:param user_id: UUID of user owning the resource
|
|
"""
|
|
base.Model.__init__(self,
|
|
name=name,
|
|
type=type,
|
|
unit=unit,
|
|
resource_id=resource_id,
|
|
project_id=project_id,
|
|
source=source,
|
|
user_id=user_id,
|
|
)
|
|
|
|
|
|
class Sample(base.Model):
|
|
"""One collected data point.
|
|
"""
|
|
def __init__(self,
|
|
source,
|
|
counter_name, counter_type, counter_unit, counter_volume,
|
|
user_id, project_id, resource_id,
|
|
timestamp, resource_metadata,
|
|
message_id,
|
|
message_signature,
|
|
recorded_at,
|
|
):
|
|
"""Create a new sample.
|
|
|
|
:param source: the identifier for the user/project id definition
|
|
:param counter_name: the name of the measurement being taken
|
|
:param counter_type: the type of the measurement
|
|
:param counter_unit: the units for the measurement
|
|
:param counter_volume: the measured value
|
|
:param user_id: the user that triggered the measurement
|
|
:param project_id: the project that owns the resource
|
|
:param resource_id: the thing on which the measurement was taken
|
|
:param timestamp: the time of the measurement
|
|
:param resource_metadata: extra details about the resource
|
|
:param message_id: a message identifier
|
|
:param recorded_at: sample record timestamp
|
|
:param message_signature: a hash created from the rest of the
|
|
message data
|
|
"""
|
|
base.Model.__init__(self,
|
|
source=source,
|
|
counter_name=counter_name,
|
|
counter_type=counter_type,
|
|
counter_unit=counter_unit,
|
|
counter_volume=counter_volume,
|
|
user_id=user_id,
|
|
project_id=project_id,
|
|
resource_id=resource_id,
|
|
timestamp=timestamp,
|
|
resource_metadata=resource_metadata,
|
|
message_id=message_id,
|
|
message_signature=message_signature,
|
|
recorded_at=recorded_at)
|
|
|
|
|
|
class Statistics(base.Model):
|
|
"""Computed statistics based on a set of sample data.
|
|
"""
|
|
def __init__(self, unit,
|
|
period, period_start, period_end,
|
|
duration, duration_start, duration_end,
|
|
groupby, **data):
|
|
"""Create a new statistics object.
|
|
|
|
:param unit: The unit type of the data set
|
|
:param period: The length of the time range covered by these stats
|
|
:param period_start: The timestamp for the start of the period
|
|
:param period_end: The timestamp for the end of the period
|
|
:param duration: The total time for the matching samples
|
|
:param duration_start: The earliest time for the matching samples
|
|
:param duration_end: The latest time for the matching samples
|
|
:param groupby: The fields used to group the samples.
|
|
:param data: some or all of the following aggregates
|
|
min: The smallest volume found
|
|
max: The largest volume found
|
|
avg: The average of all volumes found
|
|
sum: The total of all volumes found
|
|
count: The number of samples found
|
|
aggregate: name-value pairs for selectable aggregates
|
|
"""
|
|
base.Model.__init__(self, unit=unit,
|
|
period=period, period_start=period_start,
|
|
period_end=period_end, duration=duration,
|
|
duration_start=duration_start,
|
|
duration_end=duration_end,
|
|
groupby=groupby,
|
|
**data)
|