Allow publishing arbitrary headers via the "storage.objects.*.bytes"

counter

The change allow publishing arbitrary headers via the
"storage.objects.*.bytes" counter of the swift middleware.

The list of the headers to publish can be configured in the swift
middleware filter like this:

[filter:ceilometer]
use = egg:ceilometer#swift
metadata_headers = X_VAR1, x-var2

Change-Id: I26a4a573707a778c5b86d298840e7ae25a95deea
This commit is contained in:
Mehdi Abaakouk 2013-03-15 11:25:57 +00:00
parent 31b88b87b9
commit c131b2bfd5
2 changed files with 96 additions and 12 deletions

View File

@ -18,6 +18,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Ceilometer Middleware for Swift Proxy
Configuration:
In /etc/swift/proxy-server.conf on the main pipeline add "ceilometer" just
before "proxy-server" and add the following filter in the file:
[filter:ceilometer]
use = egg:ceilometer#swift
# Some optional configuration
# this allow to publish additional metadata
metadata_headers = X-TEST
"""
from __future__ import absolute_import
from oslo.config import cfg
@ -54,6 +71,12 @@ class CeilometerMiddleware(object):
def __init__(self, app, conf):
self.app = app
self.metadata_headers = [h.strip().replace('-', '_').lower()
for h in conf.get(
"metadata_headers",
"").split(",") if h.strip()]
service.prepare_service()
publisher_manager = dispatch.NameDispatchExtensionManager(
namespace=pipeline.PUBLISHER_NAMESPACE,
@ -97,6 +120,19 @@ class CeilometerMiddleware(object):
req = REQUEST.Request(env)
version, account, container, obj = split_path(req.path, 1, 4, True)
now = timeutils.utcnow().isoformat()
resource_metadata = {
"path": req.path,
"version": version,
"container": container,
"object": obj,
}
for header in self.metadata_headers:
if header.upper() in req.headers:
resource_metadata['http_header_%s' % header] = req.headers.get(
header.upper())
with pipeline.PublishContext(
context.get_admin_context(),
cfg.CONF.counter_source,
@ -112,12 +148,7 @@ class CeilometerMiddleware(object):
project_id=env.get('HTTP_X_TENANT_ID'),
resource_id=account.partition('AUTH_')[2],
timestamp=now,
resource_metadata={
"path": req.path,
"version": version,
"container": container,
"object": obj,
})])
resource_metadata=resource_metadata)])
if bytes_sent:
publisher([counter.Counter(
@ -129,12 +160,7 @@ class CeilometerMiddleware(object):
project_id=env.get('HTTP_X_TENANT_ID'),
resource_id=account.partition('AUTH_')[2],
timestamp=now,
resource_metadata={
"path": req.path,
"version": version,
"container": container,
"object": obj,
})])
resource_metadata=resource_metadata)])
def filter_factory(global_conf, **local_conf):

View File

@ -133,3 +133,61 @@ class TestSwiftMiddleware(base.TestCase):
self.assertEqual(data.resource_metadata['version'], '1.0')
self.assertEqual(data.resource_metadata['container'], 'container')
self.assertEqual(data.resource_metadata['object'], None)
def test_no_metadata_headers(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)
data = counters[0]
http_headers = [k for k in data.resource_metadata.keys()
if k.startswith('http_header_')]
self.assertEqual(len(http_headers), 0)
self.assertEqual(data.resource_metadata['version'], '1.0')
self.assertEqual(data.resource_metadata['container'], 'container')
self.assertEqual(data.resource_metadata['object'], None)
def test_metadata_headers(self):
app = swift_middleware.CeilometerMiddleware(FakeApp(), {
'metadata_headers': 'X_VAR1, x-var2, x-var3'
})
req = Request.blank('/1.0/account/container',
environ={'REQUEST_METHOD': 'GET'},
headers={
'X_VAR1': 'value1',
'X_VAR2': 'value2'
})
resp = list(app(req.environ, self.start_response))
counters = self.pipeline_manager.pipelines[0].counters
self.assertEqual(len(counters), 1)
data = counters[0]
http_headers = [k for k in data.resource_metadata.keys()
if k.startswith('http_header_')]
self.assertEqual(len(http_headers), 2)
self.assertEqual(data.resource_metadata['version'], '1.0')
self.assertEqual(data.resource_metadata['container'], 'container')
self.assertEqual(data.resource_metadata['object'], None)
self.assertEqual(data.resource_metadata['http_header_x_var1'],
'value1')
self.assertEqual(data.resource_metadata['http_header_x_var2'],
'value2')
self.assertFalse('http_header_x_var3' in data.resource_metadata)
def test_metadata_headers_on_not_existing_header(self):
app = swift_middleware.CeilometerMiddleware(FakeApp(), {
'metadata_headers': 'x-var3'
})
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)
data = counters[0]
http_headers = [k for k in data.resource_metadata.keys()
if k.startswith('http_header_')]
self.assertEqual(len(http_headers), 0)
self.assertEqual(data.resource_metadata['version'], '1.0')
self.assertEqual(data.resource_metadata['container'], 'container')
self.assertEqual(data.resource_metadata['object'], None)