Add profiling support to neutronclient

To be able to create profiling traces for Neutron, client should be
able to send special HTTP header that contains trace info.
This patch is also important to be able to make cross project
traces. (Typical case nova calls neutron via python client, if
profiler is initialized in nova, neutron client will add extra
header, that will be parsed by special osprofiler middleware in neutron
api.)

Closes-Bug: #1335640

Co-Authored-By: Roman Podoliaka <rpodolyaka@mirantis.com>
Change-Id: Ic11796889075b2a0e589b70398fc4d4ed6f3ef7c
This commit is contained in:
Dina Belova
2016-02-17 12:15:21 -08:00
committed by Akihiro Motoki
parent 30fdde8e4e
commit badfc96046
4 changed files with 28 additions and 0 deletions

View File

@@ -24,12 +24,15 @@ import os
import debtcollector.renames import debtcollector.renames
from keystoneauth1 import access from keystoneauth1 import access
from keystoneauth1 import adapter from keystoneauth1 import adapter
from oslo_utils import importutils
import requests import requests
from neutronclient._i18n import _ from neutronclient._i18n import _
from neutronclient.common import exceptions from neutronclient.common import exceptions
from neutronclient.common import utils from neutronclient.common import utils
osprofiler_web = importutils.try_import("osprofiler.web")
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
if os.environ.get('NEUTRONCLIENT_DEBUG'): if os.environ.get('NEUTRONCLIENT_DEBUG'):
@@ -151,6 +154,10 @@ class HTTPClient(object):
headers.setdefault('Content-Type', content_type) headers.setdefault('Content-Type', content_type)
headers['User-Agent'] = USER_AGENT headers['User-Agent'] = USER_AGENT
# NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any
# headers in case if osprofiler is not initialized.
if osprofiler_web:
headers.update(osprofiler_web.get_trace_id_headers())
resp = requests.request( resp = requests.request(
method, method,
@@ -301,6 +308,10 @@ class SessionClient(adapter.Adapter):
headers = kwargs.setdefault('headers', {}) headers = kwargs.setdefault('headers', {})
headers.setdefault('Accept', content_type) headers.setdefault('Accept', content_type)
# NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any
# headers in case if osprofiler is not initialized.
if osprofiler_web:
headers.update(osprofiler_web.get_trace_id_headers())
try: try:
kwargs.setdefault('data', kwargs.pop('body')) kwargs.setdefault('data', kwargs.pop('body'))

View File

@@ -15,6 +15,8 @@
import abc import abc
import osprofiler.profiler
import osprofiler.web
from requests_mock.contrib import fixture as mock_fixture from requests_mock.contrib import fixture as mock_fixture
import six import six
import testtools import testtools
@@ -72,6 +74,14 @@ class TestHTTPClientMixin(object):
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
self._test_headers(headers, body=BODY, headers=headers) self._test_headers(headers, body=BODY, headers=headers)
def test_osprofiler_headers_are_injected(self):
osprofiler.profiler.init('SWORDFISH')
self.addCleanup(osprofiler.profiler._clean)
headers = {'Accept': 'application/json'}
headers.update(osprofiler.web.get_trace_id_headers())
self._test_headers(headers)
class TestHTTPClient(TestHTTPClientMixin, testtools.TestCase): class TestHTTPClient(TestHTTPClientMixin, testtools.TestCase):

View File

@@ -0,0 +1,6 @@
---
features:
- |
Add osprofiler support to the neutronclient python binding.
If osprofiler is initiated, neutronclient sends a special HTTP
header that contains trace info.

View File

@@ -9,6 +9,7 @@ mox3!=0.19.0,>=0.7.0 # Apache-2.0
mock>=2.0 # BSD mock>=2.0 # BSD
oslosphinx>=4.7.0 # Apache-2.0 oslosphinx>=4.7.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0 oslotest>=1.10.0 # Apache-2.0
osprofiler>=1.4.0 # Apache-2.0
python-openstackclient>=3.3.0 # Apache-2.0 python-openstackclient>=3.3.0 # Apache-2.0
python-subunit>=0.0.18 # Apache-2.0/BSD python-subunit>=0.0.18 # Apache-2.0/BSD
reno>=1.8.0 # Apache-2.0 reno>=1.8.0 # Apache-2.0