139 lines
4.3 KiB
Python
139 lines
4.3 KiB
Python
# Copyright 2016 Catalyst IT Ltd
|
|
#
|
|
# 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.
|
|
|
|
import datetime
|
|
|
|
from oslo_log import log as logging
|
|
|
|
from distil.transformer import BaseTransformer
|
|
from distil.common import constants
|
|
from distil.common import openstack
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class MaxTransformer(BaseTransformer):
|
|
"""Transformer for max-integration of a gauge value over time.
|
|
If the raw unit is 'gigabytes', then the transformed unit is
|
|
'gigabyte-hours'.
|
|
"""
|
|
|
|
def _get_max_vol(self, data):
|
|
if len(data):
|
|
max_vol = max([(v["volume"] if v["volume"] else 0) for v in data])
|
|
if max_vol:
|
|
return max_vol
|
|
return 0
|
|
|
|
def _transform_usage(self, meter_name, raw_data, start_at, end_at):
|
|
max_vol = self._get_max_vol(raw_data)
|
|
|
|
hours = (end_at - start_at).total_seconds() / 3600.0
|
|
|
|
return {meter_name: max_vol * hours}
|
|
|
|
|
|
class BlockStorageMaxTransformer(MaxTransformer):
|
|
"""
|
|
Variantion on the GaugeMax Transformer that checks for
|
|
volume_type and uses that as the service, or uses the
|
|
default service name.
|
|
"""
|
|
|
|
def _transform_usage(self, name, data, start, end):
|
|
if not data:
|
|
return None
|
|
|
|
max_vol = self._get_max_vol(data)
|
|
|
|
if "volume_type" in data[-1]['metadata']:
|
|
vtype = data[-1]['metadata']['volume_type']
|
|
service = openstack.get_volume_type_name(vtype)
|
|
if not service:
|
|
service = name
|
|
else:
|
|
service = name
|
|
|
|
hours = (end - start).total_seconds() / 3600.0
|
|
return {service: max_vol * hours}
|
|
|
|
|
|
class DatabaseVolumeMaxTransformer(BaseTransformer):
|
|
"""
|
|
Variantion on the GaugeMax Transformer that checks for
|
|
volume_type and uses that as the service, or uses the
|
|
default service name.
|
|
|
|
It also gets the actual volume size from metadata.
|
|
"""
|
|
|
|
def _transform_usage(self, name, data, start, end):
|
|
if not data:
|
|
return None
|
|
|
|
max_vol = max([int(v["metadata"]["volume.size"]) for v in data])
|
|
|
|
volume_type = openstack.get_volume_type_for_volume(
|
|
data[-1]['metadata']['volume_id'])
|
|
if not volume_type:
|
|
return None
|
|
|
|
hours = (end - start).total_seconds() / 3600.0
|
|
return {volume_type: max_vol * hours}
|
|
|
|
|
|
class ObjectStorageMaxTransformer(MaxTransformer):
|
|
"""
|
|
Variantion on the GaugeMax Transformer that checks for
|
|
object storage container policy and uses that as the service,
|
|
or uses the default service name.
|
|
"""
|
|
|
|
def _transform_usage(self, name, data, start, end):
|
|
if not data:
|
|
return None
|
|
|
|
container_name = data[-1]['resource_id'].split('/')[1]
|
|
project_id = data[-1]['project_id']
|
|
|
|
service = openstack.get_container_policy(project_id, container_name)
|
|
if not service:
|
|
service = name
|
|
|
|
max_vol = self._get_max_vol(data)
|
|
|
|
hours = (end - start).total_seconds() / 3600.0
|
|
return {service: max_vol * hours}
|
|
|
|
|
|
class SumTransformer(BaseTransformer):
|
|
"""Transformer for sum-integration of a gauge value for given period.
|
|
"""
|
|
|
|
def _transform_usage(self, meter_name, raw_data, start_at, end_at):
|
|
sum_vol = 0
|
|
for sample in raw_data:
|
|
try:
|
|
t = datetime.datetime.strptime(sample['timestamp'],
|
|
'%Y-%m-%dT%H:%M:%S.%f')
|
|
except ValueError:
|
|
# In case of u'timestamp': u'2016-08-04T11:35:00',
|
|
t = datetime.datetime.strptime(sample['timestamp'],
|
|
'%Y-%m-%dT%H:%M:%S')
|
|
|
|
if t >= start_at and t < end_at:
|
|
sum_vol += sample["volume"] or 0
|
|
|
|
return {meter_name: sum_vol}
|