Merge branch 'core-instrumentation-asgi-v0.15b0'

This commit is contained in:
Nathaniel Ruiz Nowell
2020-11-02 11:18:48 -08:00
3 changed files with 31 additions and 23 deletions

View File

@ -39,8 +39,8 @@ package_dir=
=src
packages=find_namespace:
install_requires =
opentelemetry-api == 0.15.dev0
opentelemetry-instrumentation == 0.15.dev0
opentelemetry-api == 0.15b0
opentelemetry-instrumentation == 0.15b0
asgiref ~= 3.0
[options.extras_require]

View File

@ -28,22 +28,32 @@ from asgiref.compatibility import guarantee_single_callable
from opentelemetry import context, propagators, trace
from opentelemetry.instrumentation.asgi.version import __version__ # noqa
from opentelemetry.instrumentation.utils import http_status_to_canonical_code
from opentelemetry.trace.status import Status, StatusCanonicalCode
from opentelemetry.instrumentation.utils import http_status_to_status_code
from opentelemetry.trace.propagation.textmap import DictGetter
from opentelemetry.trace.status import Status, StatusCode
def get_header_from_scope(scope: dict, header_name: str) -> typing.List[str]:
"""Retrieve a HTTP header value from the ASGI scope.
class CarrierGetter(DictGetter):
def get(self, carrier: dict, key: str) -> typing.List[str]:
"""Getter implementation to retrieve a HTTP header value from the ASGI
scope.
Returns:
A list with a single string with the header value if it exists, else an empty list.
"""
headers = scope.get("headers")
return [
value.decode("utf8")
for (key, value) in headers
if key.decode("utf8") == header_name
]
Args:
carrier: ASGI scope object
key: header name in scope
Returns:
A list with a single string with the header value if it exists,
else an empty list.
"""
headers = carrier.get("headers")
return [
_value.decode("utf8")
for (_key, _value) in headers
if _key.decode("utf8") == key
]
carrier_getter = CarrierGetter()
def collect_request_attributes(scope):
@ -72,10 +82,10 @@ def collect_request_attributes(scope):
http_method = scope.get("method")
if http_method:
result["http.method"] = http_method
http_host_value = ",".join(get_header_from_scope(scope, "host"))
http_host_value = ",".join(carrier_getter.get(scope, "host"))
if http_host_value:
result["http.server_name"] = http_host_value
http_user_agent = get_header_from_scope(scope, "user-agent")
http_user_agent = carrier_getter.get(scope, "user-agent")
if len(http_user_agent) > 0:
result["http.user_agent"] = http_user_agent[0]
@ -98,13 +108,13 @@ def set_status_code(span, status_code):
except ValueError:
span.set_status(
Status(
StatusCanonicalCode.UNKNOWN,
StatusCode.ERROR,
"Non-integer HTTP status: " + repr(status_code),
)
)
else:
span.set_attribute("http.status_code", status_code)
span.set_status(Status(http_status_to_canonical_code(status_code)))
span.set_status(Status(http_status_to_status_code(status_code)))
def get_default_span_details(scope: dict) -> Tuple[str, dict]:
@ -154,9 +164,7 @@ class OpenTelemetryMiddleware:
if scope["type"] not in ("http", "websocket"):
return await self.app(scope, receive, send)
token = context.attach(
propagators.extract(get_header_from_scope, scope)
)
token = context.attach(propagators.extract(carrier_getter, scope))
span_name, additional_attributes = self.span_details_callback(scope)
try:

View File

@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
__version__ = "0.15.dev0"
__version__ = "0.15b0"