Rename EventFilter to SampleFilter.

With the new Event tables entering ceilometer, having this EventFilter
class is going to cause confusion. Renaming this to SampleFilter.

Change-Id: I537ddaa79f1d28b4608518a2048be7c33c1b5acf
This commit is contained in:
Sandy Walsh 2013-04-29 17:41:58 -03:00
parent 15b0e108f5
commit 92905c9331
14 changed files with 128 additions and 125 deletions

View File

@ -57,7 +57,7 @@ class _Base(wtypes.Base):
class Query(_Base):
"""Query filter.
"""Sample query filter.
"""
_op = None # provide a default
@ -378,9 +378,9 @@ class MeterController(rest.RestController):
:param q: Filter rules for the data to be returned.
"""
kwargs = _query_to_kwargs(q, storage.EventFilter.__init__)
kwargs = _query_to_kwargs(q, storage.SampleFilter.__init__)
kwargs['meter'] = self._id
f = storage.EventFilter(**kwargs)
f = storage.SampleFilter(**kwargs)
return [Sample.from_db_model(e)
for e in pecan.request.storage_conn.get_samples(f)
]
@ -394,9 +394,9 @@ class MeterController(rest.RestController):
period long of that number of seconds.
"""
kwargs = _query_to_kwargs(q, storage.EventFilter.__init__)
kwargs = _query_to_kwargs(q, storage.SampleFilter.__init__)
kwargs['meter'] = self._id
f = storage.EventFilter(**kwargs)
f = storage.SampleFilter(**kwargs)
computed = pecan.request.storage_conn.get_meter_statistics(f, period)
LOG.debug('computed value coming from %r', pecan.request.storage_conn)
# Find the original timestamp in the query to use for clamping

View File

@ -395,7 +395,7 @@ def _list_samples(meter,
to maintain API compatibilty.
"""
q_ts = _get_query_timestamps(flask.request.args)
f = storage.EventFilter(
f = storage.SampleFilter(
user=user,
project=project,
source=source,
@ -405,8 +405,9 @@ def _list_samples(meter,
end=q_ts['end_timestamp'],
metaquery=_get_metaquery(flask.request.args),
)
events = flask.request.storage_conn.get_samples(f)
jsonified = flask.jsonify(events=[e.as_dict() for e in events])
samples = flask.request.storage_conn.get_samples(f)
jsonified = flask.jsonify(events=[s.as_dict() for s in samples])
if request_wants_html():
return flask.templating.render_template('list_event.html',
user=user,
@ -552,7 +553,7 @@ def compute_duration_by_resource(resource, meter):
# Query the database for the interval of timestamps
# within the desired range.
f = storage.EventFilter(
f = storage.SampleFilter(
meter=meter,
project=acl.get_limited_to_project(flask.request.headers),
resource=resource,
@ -597,7 +598,7 @@ def compute_duration_by_resource(resource, meter):
def _get_statistics(stats_type, meter=None, resource=None, project=None):
q_ts = _get_query_timestamps(flask.request.args)
f = storage.EventFilter(
f = storage.SampleFilter(
meter=meter,
project=project,
resource=resource,

View File

@ -69,13 +69,13 @@ def get_connection(conf):
return db
class EventFilter(object):
"""Holds the properties for building a query to filter events.
class SampleFilter(object):
"""Holds the properties for building a query from a meter/sample filter.
:param user: The event owner.
:param project: The event owner.
:param user: The sample owner.
:param project: The sample project.
:param start: Earliest timestamp to include.
:param end: Only include events with timestamp less than this.
:param end: Only include samples with timestamp less than this.
:param resource: Optional filter for resource id.
:param meter: Optional filter for meter type using the meter name.
:param source: Optional source filter.

View File

@ -126,13 +126,13 @@ class Connection(object):
"""
@abc.abstractmethod
def get_samples(self, event_filter):
def get_samples(self, sample_filter):
"""Return an iterable of model.Sample instances
"""
@abc.abstractmethod
def get_meter_statistics(self, event_filter, period=None):
"""Return an iterable of model.Statistics instances
def get_meter_statistics(self, sample_filter, period=None):
"""Return an iterable of model.Statistics instances.
The filter must have a meter value set.
"""

View File

@ -273,10 +273,10 @@ class Connection(base.Connection):
# add in reversed_ts here for time range scan
'f:rts': str(rts)
}
# Don't want to be changing the original data object
# Don't want to be changing the original data object.
data = copy.copy(data)
data['timestamp'] = ts
# Save original event
# Save original meter.
record['f:message'] = json.dumps(data)
self.meter.put(row, record)
@ -387,10 +387,10 @@ class Connection(base.Connection):
user_id=data['f:user_id'],
)
def get_samples(self, event_filter):
def get_samples(self, sample_filter):
"""Return an iterable of models.Sample instances
"""
q, start, stop = make_query_from_filter(event_filter,
q, start, stop = make_query_from_filter(sample_filter,
require_meter=False)
LOG.debug("q: %s" % q)
@ -422,7 +422,7 @@ class Connection(base.Connection):
timeutils.delta_seconds(stat.duration_start,
stat.duration_end)
def get_meter_statistics(self, event_filter, period=None):
def get_meter_statistics(self, sample_filter, period=None):
"""Return an iterable of models.Statistics instances containing meter
statistics described by the query parameters.
@ -435,7 +435,7 @@ class Connection(base.Connection):
because of all the Thrift traffic it is going to create.
"""
q, start, stop = make_query_from_filter(event_filter)
q, start, stop = make_query_from_filter(sample_filter)
meters = list(meter for (ignored, meter) in
self.meter.scan(filter=q,
@ -443,15 +443,15 @@ class Connection(base.Connection):
row_stop=stop)
)
if event_filter.start:
start_time = event_filter.start
if sample_filter.start:
start_time = sample_filter.start
elif meters:
start_time = timeutils.parse_strtime(meters[-1]['f:timestamp'])
else:
start_time = None
if event_filter.end:
end_time = event_filter.end
if sample_filter.end:
end_time = sample_filter.end
elif meters:
end_time = timeutils.parse_strtime(meters[0]['f:timestamp'])
else:
@ -684,29 +684,30 @@ def make_query(user=None, project=None, meter=None,
q.append("SingleColumnValueFilter ('f', 'rts', >=, 'binary:%s')" %
rts_end)
query_filter = None
sample_filter = None
if len(q):
query_filter = " AND ".join(q)
sample_filter = " AND ".join(q)
if query_only:
return query_filter
return sample_filter
else:
return query_filter, startRow, stopRow
return sample_filter, startRow, stopRow
def make_query_from_filter(event_filter, require_meter=True):
def make_query_from_filter(sample_filter, require_meter=True):
"""Return a query dictionary based on the settings in the filter.
:param filter: EventFilter instance
:param sample_filter: SampleFilter instance
:param require_meter: If true and the filter does not have a meter,
raise an error.
"""
if event_filter.metaquery is not None and len(event_filter.metaquery) > 0:
if sample_filter.metaquery is not None and \
len(sample_filter.metaquery) > 0:
raise NotImplementedError('metaquery not implemented')
return make_query(event_filter.user, event_filter.project,
event_filter.meter, event_filter.resource,
event_filter.source, event_filter.start,
event_filter.end, require_meter)
return make_query(sample_filter.user, sample_filter.project,
sample_filter.meter, sample_filter.resource,
sample_filter.source, sample_filter.start,
sample_filter.end, require_meter)
def _load_hbase_list(d, prefix):

View File

@ -118,13 +118,13 @@ class Connection(base.Connection):
"""
return []
def get_samples(self, event_filter):
def get_samples(self, sample_filter):
"""Return an iterable of samples as created by
:func:`ceilometer.meter.meter_message_from_counter`.
"""
return []
def get_meter_statistics(self, event_filter, period=None):
def get_meter_statistics(self, sample_filter, period=None):
"""Return a dictionary containing meter statistics.
described by the query parameters.
@ -144,3 +144,4 @@ class Connection(base.Connection):
}
"""
return []

View File

@ -91,38 +91,38 @@ def make_timestamp_range(start, end):
return ts_range
def make_query_from_filter(event_filter, require_meter=True):
def make_query_from_filter(sample_filter, require_meter=True):
"""Return a query dictionary based on the settings in the filter.
:param filter: EventFilter instance
:param filter: SampleFilter instance
:param require_meter: If true and the filter does not have a meter,
raise an error.
"""
q = {}
if event_filter.user:
q['user_id'] = event_filter.user
if event_filter.project:
q['project_id'] = event_filter.project
if sample_filter.user:
q['user_id'] = sample_filter.user
if sample_filter.project:
q['project_id'] = sample_filter.project
if event_filter.meter:
q['counter_name'] = event_filter.meter
if sample_filter.meter:
q['counter_name'] = sample_filter.meter
elif require_meter:
raise RuntimeError('Missing required meter specifier')
ts_range = make_timestamp_range(event_filter.start, event_filter.end)
ts_range = make_timestamp_range(sample_filter.start, sample_filter.end)
if ts_range:
q['timestamp'] = ts_range
if event_filter.resource:
q['resource_id'] = event_filter.resource
if event_filter.source:
q['source'] = event_filter.source
if sample_filter.resource:
q['resource_id'] = sample_filter.resource
if sample_filter.source:
q['source'] = sample_filter.source
# so the samples call metadata resource_metadata, so we convert
# to that.
q.update(dict(('resource_%s' % k, v)
for (k, v) in event_filter.metaquery.iteritems()))
for (k, v) in sample_filter.metaquery.iteritems()))
return q
@ -315,7 +315,7 @@ class Connection(base.Connection):
upsert=True,
)
# Record the raw data for the event. Use a copy so we do not
# Record the raw data for the meter. Use a copy so we do not
# modify a data structure owned by our caller (the driver adds
# a new key '_id').
record = copy.copy(data)
@ -436,33 +436,33 @@ class Connection(base.Connection):
user_id=r['user_id'],
)
def get_samples(self, event_filter):
def get_samples(self, sample_filter):
"""Return an iterable of samples as created by
:func:`ceilometer.meter.meter_message_from_counter`.
"""
q = make_query_from_filter(event_filter, require_meter=False)
q = make_query_from_filter(sample_filter, require_meter=False)
samples = self.db.meter.find(q)
for s in samples:
# Remove the ObjectId generated by the database when
# the event was inserted. It is an implementation
# the sample was inserted. It is an implementation
# detail that should not leak outside of the driver.
del s['_id']
yield models.Sample(**s)
def get_meter_statistics(self, event_filter, period=None):
def get_meter_statistics(self, sample_filter, period=None):
"""Return an iterable of models.Statistics instance containing meter
statistics described by the query parameters.
The filter must have a meter value set.
"""
q = make_query_from_filter(event_filter)
q = make_query_from_filter(sample_filter)
if period:
map_stats = self.MAP_STATS_PERIOD % \
(period,
int(event_filter.start.strftime('%s'))
if event_filter.start else 0)
int(sample_filter.start.strftime('%s'))
if sample_filter.start else 0)
else:
map_stats = self.MAP_STATS

View File

@ -91,34 +91,34 @@ class SQLAlchemyStorage(base.StorageEngine):
return Connection(conf)
def make_query_from_filter(query, event_filter, require_meter=True):
def make_query_from_filter(query, sample_filter, require_meter=True):
"""Return a query dictionary based on the settings in the filter.
:param filter: EventFilter instance
:param filter: QueryFilter instance
:param require_meter: If true and the filter does not have a meter,
raise an error.
"""
if event_filter.meter:
query = query.filter(Meter.counter_name == event_filter.meter)
if sample_filter.meter:
query = query.filter(Meter.counter_name == sample_filter.meter)
elif require_meter:
raise RuntimeError('Missing required meter specifier')
if event_filter.source:
query = query.filter(Meter.sources.any(id=event_filter.source))
if event_filter.start:
ts_start = event_filter.start
if sample_filter.source:
query = query.filter(Meter.sources.any(id=sample_filter.source))
if sample_filter.start:
ts_start = sample_filter.start
query = query.filter(Meter.timestamp >= ts_start)
if event_filter.end:
ts_end = event_filter.end
if sample_filter.end:
ts_end = sample_filter.end
query = query.filter(Meter.timestamp < ts_end)
if event_filter.user:
query = query.filter_by(user_id=event_filter.user)
if event_filter.project:
query = query.filter_by(project_id=event_filter.project)
if event_filter.resource:
query = query.filter_by(resource_id=event_filter.resource)
if sample_filter.user:
query = query.filter_by(user_id=sample_filter.user)
if sample_filter.project:
query = query.filter_by(project_id=sample_filter.project)
if sample_filter.resource:
query = query.filter_by(resource_id=sample_filter.resource)
if event_filter.metaquery:
if sample_filter.metaquery:
raise NotImplementedError('metaquery not implemented')
return query
@ -181,10 +181,10 @@ class Connection(base.Connection):
resource.user = user
# Current metadata being used and when it was last updated.
resource.resource_metadata = rmetadata
# autoflush didn't catch this one, requires manual flush
# Autoflush didn't catch this one, requires manual flush.
self.session.flush()
# Record the raw data for the event.
# Record the raw data for the meter.
meter = Meter(counter_type=data['counter_type'],
counter_unit=data['counter_unit'],
counter_name=data['counter_name'], resource=resource)
@ -305,17 +305,17 @@ class Connection(base.Connection):
user_id=resource.user_id,
)
def get_samples(self, event_filter):
def get_samples(self, sample_filter):
"""Return an iterable of api_models.Samples
"""
query = self.session.query(Meter)
query = make_query_from_filter(query, event_filter,
query = make_query_from_filter(query, sample_filter,
require_meter=False)
samples = query.all()
for s in samples:
# Remove the id generated by the database when
# the event was inserted. It is an implementation
# the sample was inserted. It is an implementation
# detail that should not leak outside of the driver.
yield api_models.Sample(
# Replace 'sources' with 'source' to meet the caller's
@ -335,16 +335,16 @@ class Connection(base.Connection):
message_signature=s.message_signature,
)
def _make_volume_query(self, event_filter, counter_volume_func):
def _make_volume_query(self, sample_filter, counter_volume_func):
"""Returns complex Meter counter_volume query for max and sum."""
subq = self.session.query(Meter.id)
subq = make_query_from_filter(subq, event_filter, require_meter=False)
subq = make_query_from_filter(subq, sample_filter, require_meter=False)
subq = subq.subquery()
mainq = self.session.query(Resource.id, counter_volume_func)
mainq = mainq.join(Meter).group_by(Resource.id)
return mainq.filter(Meter.id.in_(subq))
def _make_stats_query(self, event_filter):
def _make_stats_query(self, sample_filter):
query = self.session.query(
func.min(Meter.timestamp).label('tsmin'),
func.max(Meter.timestamp).label('tsmax'),
@ -354,7 +354,7 @@ class Connection(base.Connection):
func.max(Meter.counter_volume).label('max'),
func.count(Meter.counter_volume).label('count'))
return make_query_from_filter(query, event_filter)
return make_query_from_filter(query, sample_filter)
@staticmethod
def _stats_result_to_model(result, period, period_start, period_end):
@ -375,34 +375,34 @@ class Connection(base.Connection):
period_end=period_end,
)
def get_meter_statistics(self, event_filter, period=None):
def get_meter_statistics(self, sample_filter, period=None):
"""Return an iterable of api_models.Statistics instances containing
meter statistics described by the query parameters.
The filter must have a meter value set.
"""
if not period or not event_filter.start or not event_filter.end:
res = self._make_stats_query(event_filter).all()[0]
if not period or not sample_filter.start or not sample_filter.end:
res = self._make_stats_query(sample_filter).all()[0]
if not period:
yield self._stats_result_to_model(res, 0, res.tsmin, res.tsmax)
return
query = self._make_stats_query(event_filter)
query = self._make_stats_query(sample_filter)
# HACK(jd) This is an awful method to compute stats by period, but
# since we're trying to be SQL agnostic we have to write portable
# code, so here it is, admire! We're going to do one request to get
# stats by period. We would like to use GROUP BY, but there's no
# portable way to manipulate timestamp in SQL, so we can't.
for period_start, period_end in base.iter_period(
event_filter.start or res.tsmin,
event_filter.end or res.tsmax,
sample_filter.start or res.tsmin,
sample_filter.end or res.tsmax,
period):
q = query.filter(Meter.timestamp >= period_start)
q = q.filter(Meter.timestamp < period_end)
r = q.all()[0]
# Don't return results that didn't have any event
# Don't return results that didn't have any data.
if r.count:
yield self._stats_result_to_model(
result=r,

View File

@ -124,7 +124,7 @@ class Sample(Model):
: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 event and measurement
: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

View File

@ -257,24 +257,24 @@ class MeterTest(DBTestBase):
self.assertTrue(len(results) == 4)
class RawEventTest(DBTestBase):
class RawSampleTest(DBTestBase):
def test_get_samples_by_user(self):
f = storage.EventFilter(user='user-id')
f = storage.SampleFilter(user='user-id')
results = list(self.conn.get_samples(f))
assert len(results) == 2
for meter in results:
assert meter.as_dict() in [self.msg1, self.msg2]
def test_get_samples_by_project(self):
f = storage.EventFilter(project='project-id')
f = storage.SampleFilter(project='project-id')
results = list(self.conn.get_samples(f))
assert results
for meter in results:
assert meter.as_dict() in [self.msg1, self.msg2, self.msg3]
def test_get_samples_by_resource(self):
f = storage.EventFilter(user='user-id', resource='resource-id')
f = storage.SampleFilter(user='user-id', resource='resource-id')
results = list(self.conn.get_samples(f))
assert results
meter = results[0]
@ -283,7 +283,7 @@ class RawEventTest(DBTestBase):
def test_get_samples_by_metaquery(self):
q = {'metadata.display_name': 'test-server'}
f = storage.EventFilter(metaquery=q)
f = storage.SampleFilter(metaquery=q)
got_not_imp = False
try:
results = list(self.conn.get_samples(f))
@ -295,7 +295,7 @@ class RawEventTest(DBTestBase):
self.assertTrue(got_not_imp)
def test_get_samples_by_start_time(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-id',
start=datetime.datetime(2012, 7, 2, 10, 41),
)
@ -304,7 +304,7 @@ class RawEventTest(DBTestBase):
assert results[0].timestamp == datetime.datetime(2012, 7, 2, 10, 41)
def test_get_samples_by_end_time(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-id',
end=datetime.datetime(2012, 7, 2, 10, 41),
)
@ -314,7 +314,7 @@ class RawEventTest(DBTestBase):
assert results[0].timestamp == datetime.datetime(2012, 7, 2, 10, 40)
def test_get_samples_by_both_times(self):
f = storage.EventFilter(
f = storage.SampleFilter(
start=datetime.datetime(2012, 7, 2, 10, 42),
end=datetime.datetime(2012, 7, 2, 10, 43),
)
@ -324,17 +324,17 @@ class RawEventTest(DBTestBase):
assert results[0].timestamp == datetime.datetime(2012, 7, 2, 10, 42)
def test_get_samples_by_name(self):
f = storage.EventFilter(user='user-id', meter='no-such-meter')
f = storage.SampleFilter(user='user-id', meter='no-such-meter')
results = list(self.conn.get_samples(f))
assert not results
def test_get_samples_by_name2(self):
f = storage.EventFilter(user='user-id', meter='instance')
f = storage.SampleFilter(user='user-id', meter='instance')
results = list(self.conn.get_samples(f))
assert results
def test_get_samples_by_source(self):
f = storage.EventFilter(source='test-1')
f = storage.SampleFilter(source='test-1')
results = list(self.conn.get_samples(f))
assert results
assert len(results) == 1
@ -386,7 +386,7 @@ class StatisticsTest(DBTestBase):
self.conn.record_metering_data(msg)
def test_by_user(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-5',
meter='volume.size',
)
@ -401,7 +401,7 @@ class StatisticsTest(DBTestBase):
assert results.avg == 9
def test_no_period_in_query(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-5',
meter='volume.size',
)
@ -409,7 +409,7 @@ class StatisticsTest(DBTestBase):
assert results.period == 0
def test_period_is_int(self):
f = storage.EventFilter(
f = storage.SampleFilter(
meter='volume.size',
)
results = list(self.conn.get_meter_statistics(f))[0]
@ -417,7 +417,7 @@ class StatisticsTest(DBTestBase):
assert results.count == 6
def test_by_user_period(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-5',
meter='volume.size',
start='2012-09-25T10:28:00',
@ -449,7 +449,7 @@ class StatisticsTest(DBTestBase):
datetime.datetime(2012, 9, 25, 11, 31))
def test_by_user_period_start_end(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-5',
meter='volume.size',
start='2012-09-25T10:28:00',
@ -476,7 +476,7 @@ class StatisticsTest(DBTestBase):
datetime.datetime(2012, 9, 25, 10, 30))
def test_by_project(self):
f = storage.EventFilter(
f = storage.SampleFilter(
meter='volume.size',
resource='resource-id',
start='2012-09-25T11:30:00',
@ -491,7 +491,7 @@ class StatisticsTest(DBTestBase):
assert results.avg == 6
def test_one_resource(self):
f = storage.EventFilter(
f = storage.SampleFilter(
user='user-id',
meter='volume.size',
)
@ -565,20 +565,20 @@ class CounterDataTypeTest(DBTestBase):
self.conn.record_metering_data(msg)
def test_storage_can_handle_large_values(self):
f = storage.EventFilter(
f = storage.SampleFilter(
meter='dummyBigCounter',
)
results = list(self.conn.get_samples(f))
self.assertEqual(results[0].counter_volume, 3372036854775807)
f = storage.EventFilter(
f = storage.SampleFilter(
meter='dummySmallCounter',
)
results = list(self.conn.get_samples(f))
self.assertEqual(results[0].counter_volume, -3372036854775807)
def test_storage_can_handle_float_values(self):
f = storage.EventFilter(
f = storage.SampleFilter(
meter='floatCounter',
)
results = list(self.conn.get_samples(f))

View File

@ -47,7 +47,7 @@ class MeterTest(base.MeterTest, HBaseEngineTestBase):
pass
class RawEventTest(base.RawEventTest, HBaseEngineTestBase):
class RawSampleTest(base.RawSampleTest, HBaseEngineTestBase):
pass

View File

@ -86,7 +86,7 @@ class MeterTest(base.MeterTest, MongoDBEngineTestBase):
pass
class RawEventTest(base.RawEventTest, MongoDBEngineTestBase):
class RawSampleTest(base.RawSampleTest, MongoDBEngineTestBase):
pass

View File

@ -49,7 +49,7 @@ class MeterTest(base.MeterTest, SQLAlchemyEngineTestBase):
pass
class RawEventTest(base.RawEventTest, SQLAlchemyEngineTestBase):
class RawSampleTest(base.RawSampleTest, SQLAlchemyEngineTestBase):
pass

View File

@ -41,7 +41,7 @@ def show_resources(db, args):
for k, v in sorted(resource['metadata'].iteritems()):
print ' %-10s : %s' % (k, v)
for meter in resource['meter']:
totals = db.get_statistics(storage.EventFilter(
totals = db.get_statistics(storage.SampleFilter(
user=u,
meter=meter['counter_name'],
resource=resource['resource_id'],
@ -65,7 +65,7 @@ def show_total_resources(db, args):
for u in users:
print u
for meter in ['disk', 'cpu', 'instance']:
stats = db.get_statistics(storage.EventFilter(
stats = db.get_statistics(storage.SampleFilter(
user=u,
meter=meter,
))
@ -82,11 +82,11 @@ def show_raw(db, args):
print u
for resource in db.get_resources(user=u):
print ' ', resource['resource_id']
for event in db.get_samples(storage.EventFilter(
for sample in db.get_samples(storage.SampleFilter(
user=u,
resource=resource['resource_id'],
)):
print fmt % event
print fmt % sample
def show_help(db, args):