simplify gnocchi batch push setup

we run through samples and format samples and resources to what
gnocchi expects. this simplifies that process a little:
- don't needlessly sort and group by metric name
- build a full resource model iff resource needs to be created

Change-Id: I2ac25b3b0978eed664c500e645bae2d1b4ae6781
This commit is contained in:
gord chung 2017-11-25 18:01:03 -05:00 committed by gordon chung
parent 40317d7bae
commit 5b216fae74

@ -292,8 +292,7 @@ class GnocchiPublisher(publisher.ConfigPublisherBase):
def publish_samples(self, data): def publish_samples(self, data):
# NOTE(sileht): skip sample generated by gnocchi itself # NOTE(sileht): skip sample generated by gnocchi itself
data = [s for s in data if not self._is_gnocchi_activity(s)] data = [s for s in data if not self._is_gnocchi_activity(s)]
data.sort(key=operator.attrgetter('resource_id'))
data.sort(key=lambda s: (s.resource_id, s.name))
resource_grouped_samples = itertools.groupby( resource_grouped_samples = itertools.groupby(
data, key=operator.attrgetter('resource_id')) data, key=operator.attrgetter('resource_id'))
@ -303,13 +302,8 @@ class GnocchiPublisher(publisher.ConfigPublisherBase):
# NOTE(sileht): / is forbidden by Gnocchi # NOTE(sileht): / is forbidden by Gnocchi
resource_id = resource_id.replace('/', '_') resource_id = resource_id.replace('/', '_')
metric_grouped_samples = itertools.groupby( for sample in samples_of_resource:
list(samples_of_resource), metric_name = sample.name
key=operator.attrgetter('name'))
res_info = {}
for metric_name, samples in metric_grouped_samples:
samples = list(samples)
rd = self.metric_map.get(metric_name) rd = self.metric_map.get(metric_name)
if rd is None: if rd is None:
if metric_name not in self._already_logged_metric_names: if metric_name not in self._already_logged_metric_names:
@ -320,28 +314,22 @@ class GnocchiPublisher(publisher.ConfigPublisherBase):
if rd.cfg.get("ignore"): if rd.cfg.get("ignore"):
continue continue
res_info['resource_type'] = rd.cfg['resource_type'] if resource_id not in gnocchi_data:
res_info.setdefault("resource", {}).update({ gnocchi_data[resource_id] = {
"id": resource_id, 'resource_type': rd.cfg['resource_type'],
"user_id": samples[0].user_id, 'resource': {"id": resource_id,
"project_id": samples[0].project_id, "user_id": sample.user_id,
"metrics": rd.metrics, "project_id": sample.project_id,
}) "metrics": rd.metrics}}
for sample in samples: gnocchi_data[resource_id].setdefault(
res_info.setdefault("resource_extra", {}).update( "resource_extra", {}).update(rd.sample_attributes(sample))
rd.sample_attributes(sample)) measures.setdefault(resource_id, {}).setdefault(
m = measures.setdefault(resource_id, {}).setdefault( metric_name, []).append({'timestamp': sample.timestamp,
metric_name, []) 'value': sample.volume})
m.append({'timestamp': sample.timestamp, # TODO(gordc): unit should really be part of metric definition
'value': sample.volume}) gnocchi_data[resource_id]['resource']['metrics'][
unit = sample.unit metric_name]['unit'] = sample.unit
metric = sample.name
res_info['resource']['metrics'][metric]['unit'] = unit
res_info["resource"].update(res_info["resource_extra"])
if res_info:
gnocchi_data[resource_id] = res_info
try: try:
self.batch_measures(measures, gnocchi_data) self.batch_measures(measures, gnocchi_data)
@ -369,7 +357,8 @@ class GnocchiPublisher(publisher.ConfigPublisherBase):
resource_ids = set([r['original_resource_id'] resource_ids = set([r['original_resource_id']
for r in e.message['detail']]) for r in e.message['detail']])
return [(resource_infos[rid]['resource_type'], return [(resource_infos[rid]['resource_type'],
resource_infos[rid]['resource']) resource_infos[rid]['resource'],
resource_infos[rid]['resource_extra'])
for rid in resource_ids] for rid in resource_ids]
def batch_measures(self, measures, resource_infos): def batch_measures(self, measures, resource_infos):
@ -385,8 +374,9 @@ class GnocchiPublisher(publisher.ConfigPublisherBase):
raise raise
resources = self._extract_resources_from_error(e, resource_infos) resources = self._extract_resources_from_error(e, resource_infos)
for resource_type, resource in resources: for resource_type, resource, resource_extra in resources:
try: try:
resource.update(resource_extra)
self._if_not_cached("create", resource_type, resource, self._if_not_cached("create", resource_type, resource,
self._create_resource) self._create_resource)
except gnocchi_exc.ResourceAlreadyExists: except gnocchi_exc.ResourceAlreadyExists: