From a9267fd94e7854afa0720d761fbe75d946e7167d Mon Sep 17 00:00:00 2001 From: Tong Li Date: Thu, 11 Apr 2013 11:21:08 -0400 Subject: [PATCH] Extend swift middleware to collect number of requests. Current swift middleware does not collect # of requests against Swift, this patch adds the features. # of requests will be under the following topic storage.api.request Change-Id: I1b408d01344c9a986af1278a0b7fe3405051adca --- ceilometer/objectstore/swift_middleware.py | 18 +++++- doc/source/measurements.rst | 1 + tests/objectstore/test_swift_middleware.py | 70 +++++++++++++++++++--- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/ceilometer/objectstore/swift_middleware.py b/ceilometer/objectstore/swift_middleware.py index 9dee2c9f88..4fb8686860 100644 --- a/ceilometer/objectstore/swift_middleware.py +++ b/ceilometer/objectstore/swift_middleware.py @@ -144,7 +144,7 @@ class CeilometerMiddleware(object): if bytes_received: publisher([counter.Counter( name='storage.objects.incoming.bytes', - type='delta', + type=counter.TYPE_DELTA, unit='B', volume=bytes_received, user_id=env.get('HTTP_X_USER_ID'), @@ -156,7 +156,7 @@ class CeilometerMiddleware(object): if bytes_sent: publisher([counter.Counter( name='storage.objects.outgoing.bytes', - type='delta', + type=counter.TYPE_DELTA, unit='B', volume=bytes_sent, user_id=env.get('HTTP_X_USER_ID'), @@ -165,6 +165,20 @@ class CeilometerMiddleware(object): timestamp=now, resource_metadata=resource_metadata)]) + # publish the event for each request + # request method will be recorded in the metadata + resource_metadata['method'] = req.method.lower() + publisher([counter.Counter( + name='storage.api.request', + type=counter.TYPE_DELTA, + unit='request', + volume=1, + user_id=env.get('HTTP_X_USER_ID'), + project_id=env.get('HTTP_X_TENANT_ID'), + resource_id=account.partition('AUTH_')[2], + timestamp=now, + resource_metadata=resource_metadata)]) + def filter_factory(global_conf, **local_conf): conf = global_conf.copy() diff --git a/doc/source/measurements.rst b/doc/source/measurements.rst index a9c1c18ee8..84e89b2b4f 100644 --- a/doc/source/measurements.rst +++ b/doc/source/measurements.rst @@ -140,6 +140,7 @@ storage.objects.size Gauge B store ID Total size of storage.objects.containers Gauge containers store ID Number of containers storage.objects.incoming.bytes Delta B store ID Number of incoming bytes storage.objects.outgoing.bytes Delta B store ID Number of outgoing bytes +storage.api.request Delta request store ID Number of API requests against swift ============================== ========== ========== ======== ============================================== Energy (Kwapi) diff --git a/tests/objectstore/test_swift_middleware.py b/tests/objectstore/test_swift_middleware.py index ff508b3cbe..97bf955e60 100644 --- a/tests/objectstore/test_swift_middleware.py +++ b/tests/objectstore/test_swift_middleware.py @@ -84,28 +84,40 @@ class TestSwiftMiddleware(base.TestCase): resp = app(req.environ, self.start_response) self.assertEqual(list(resp), ["This string is 28 bytes long"]) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] self.assertEqual(data.volume, 28) self.assertEqual(data.resource_metadata['version'], '1.0') self.assertEqual(data.resource_metadata['container'], 'container') self.assertEqual(data.resource_metadata['object'], 'obj') + # test the # of request and the request method + data = counters[1] + self.assertEqual(data.name, 'storage.api.request') + self.assertEqual(data.volume, 1) + self.assertEqual(data.resource_metadata['method'], 'get') + def test_put(self): app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {}) req = Request.blank('/1.0/account/container/obj', - environ={'REQUEST_METHOD': 'GET', + environ={'REQUEST_METHOD': 'PUT', 'wsgi.input': StringIO.StringIO('some stuff')}) resp = list(app(req.environ, self.start_response)) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] self.assertEqual(data.volume, 10) self.assertEqual(data.resource_metadata['version'], '1.0') self.assertEqual(data.resource_metadata['container'], 'container') self.assertEqual(data.resource_metadata['object'], 'obj') + # test the # of request and the request method + data = counters[1] + self.assertEqual(data.name, 'storage.api.request') + self.assertEqual(data.volume, 1) + self.assertEqual(data.resource_metadata['method'], 'put') + def test_post(self): app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {}) req = Request.blank('/1.0/account/container/obj', @@ -114,20 +126,62 @@ class TestSwiftMiddleware(base.TestCase): StringIO.StringIO('some other stuff')}) resp = list(app(req.environ, self.start_response)) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] self.assertEqual(data.volume, 16) self.assertEqual(data.resource_metadata['version'], '1.0') self.assertEqual(data.resource_metadata['container'], 'container') self.assertEqual(data.resource_metadata['object'], 'obj') + # test the # of request and the request method + data = counters[1] + self.assertEqual(data.name, 'storage.api.request') + self.assertEqual(data.volume, 1) + self.assertEqual(data.resource_metadata['method'], 'post') + + def test_head(self): + app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {}) + req = Request.blank('/1.0/account/container/obj', + environ={'REQUEST_METHOD': 'HEAD'}) + resp = list(app(req.environ, self.start_response)) + counters = self.pipeline_manager.pipelines[0].counters + self.assertEqual(len(counters), 1) + data = counters[0] + self.assertEqual(data.resource_metadata['version'], '1.0') + self.assertEqual(data.resource_metadata['container'], 'container') + self.assertEqual(data.resource_metadata['object'], 'obj') + self.assertEqual(data.resource_metadata['method'], 'head') + + self.assertEqual(data.name, 'storage.api.request') + self.assertEqual(data.volume, 1) + + def test_bogus_request(self): + """ + test even for arbitrary request method, this will still work + """ + app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {}) + req = Request.blank('/1.0/account/container/obj', + environ={'REQUEST_METHOD': 'BOGUS'}) + resp = list(app(req.environ, self.start_response)) + counters = self.pipeline_manager.pipelines[0].counters + + self.assertEqual(len(counters), 1) + data = counters[0] + self.assertEqual(data.resource_metadata['version'], '1.0') + self.assertEqual(data.resource_metadata['container'], 'container') + self.assertEqual(data.resource_metadata['object'], 'obj') + self.assertEqual(data.resource_metadata['method'], 'bogus') + + self.assertEqual(data.name, 'storage.api.request') + self.assertEqual(data.volume, 1) + def test_get_container(self): app = swift_middleware.CeilometerMiddleware(FakeApp(), {}) req = Request.blank('/1.0/account/container', environ={'REQUEST_METHOD': 'GET'}) resp = list(app(req.environ, self.start_response)) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] self.assertEqual(data.volume, 28) self.assertEqual(data.resource_metadata['version'], '1.0') @@ -140,7 +194,7 @@ class TestSwiftMiddleware(base.TestCase): environ={'REQUEST_METHOD': 'GET'}) resp = list(app(req.environ, self.start_response)) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] http_headers = [k for k in data.resource_metadata.keys() if k.startswith('http_header_')] @@ -161,7 +215,7 @@ class TestSwiftMiddleware(base.TestCase): }) resp = list(app(req.environ, self.start_response)) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] http_headers = [k for k in data.resource_metadata.keys() if k.startswith('http_header_')] @@ -183,7 +237,7 @@ class TestSwiftMiddleware(base.TestCase): environ={'REQUEST_METHOD': 'GET'}) resp = list(app(req.environ, self.start_response)) counters = self.pipeline_manager.pipelines[0].counters - self.assertEqual(len(counters), 1) + self.assertEqual(len(counters), 2) data = counters[0] http_headers = [k for k in data.resource_metadata.keys() if k.startswith('http_header_')]