Skip to content

Commit

Permalink
Merge branch 'main' into pymemcache_instruments_version_bump
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanthccv authored Apr 5, 2022
2 parents 0c2c470 + dbc3073 commit f4fba8f
Show file tree
Hide file tree
Showing 10 changed files with 387 additions and 63 deletions.
94 changes: 47 additions & 47 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,53 +45,53 @@ jobs:
key: v4-build-tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'gen-requirements.txt', 'dev-requirements.txt') }}
- name: run tox
run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- --benchmark-json=${{ env.RUN_MATRIX_COMBINATION }}-benchmark.json
- name: Find and merge ${{ matrix.package }} benchmarks
# TODO: Add at least one benchmark to every package type to remove this (#249)
if: matrix.package == 'sdkextension' || matrix.package == 'propagator'
run: >-
mkdir -p benchmarks;
jq -s '.[0].benchmarks = ([.[].benchmarks] | add)
| if .[0].benchmarks == null then null else .[0] end'
**/**/tests/*${{ matrix.package }}*-benchmark.json > benchmarks/output_${{ matrix.package }}.json
- name: Upload all benchmarks under same key as an artifact
if: ${{ success() }}
uses: actions/upload-artifact@v2
with:
name: benchmarks
path: benchmarks/output_${{ matrix.package }}.json
combine-benchmarks:
runs-on: ubuntu-latest
needs: build
if: ${{ always() }}
name: Combine benchmarks from previous build job
steps:
- name: Checkout Contrib Repo @ SHA - ${{ github.sha }}
uses: actions/checkout@v2
- name: Download all benchmarks as artifact using key
uses: actions/download-artifact@v2
with:
name: benchmarks
path: benchmarks
- name: Find and merge all benchmarks
run: >-
jq -s '.[0].benchmarks = ([.[].benchmarks] | add)
| if .[0].benchmarks == null then null else .[0] end'
benchmarks/output_*.json > output.json;
- name: Report on benchmark results
uses: benchmark-action/github-action-benchmark@v1
with:
name: OpenTelemetry Python Benchmarks - Python ${{ env[matrix.python-version ]}} - ${{ matrix.package }}
tool: pytest
output-file-path: output.json
github-token: ${{ secrets.GITHUB_TOKEN }}
max-items-in-chart: 100
# Alert with a commit comment on possible performance regression
alert-threshold: 200%
fail-on-alert: true
# Make a commit on `gh-pages` with benchmarks from previous step
auto-push: ${{ github.ref == 'refs/heads/main' }}
gh-pages-branch: gh-pages
benchmark-data-dir-path: benchmarks
# - name: Find and merge ${{ matrix.package }} benchmarks
# # TODO: Add at least one benchmark to every package type to remove this (#249)
# if: matrix.package == 'sdkextension' || matrix.package == 'propagator'
# run: >-
# mkdir -p benchmarks;
# jq -s '.[0].benchmarks = ([.[].benchmarks] | add)
# | if .[0].benchmarks == null then null else .[0] end'
# **/**/tests/*${{ matrix.package }}*-benchmark.json > benchmarks/output_${{ matrix.package }}.json
# - name: Upload all benchmarks under same key as an artifact
# if: ${{ success() }}
# uses: actions/upload-artifact@v2
# with:
# name: benchmarks
# path: benchmarks/output_${{ matrix.package }}.json
# combine-benchmarks:
# runs-on: ubuntu-latest
# needs: build
# if: ${{ always() }}
# name: Combine benchmarks from previous build job
# steps:
# - name: Checkout Contrib Repo @ SHA - ${{ github.sha }}
# uses: actions/checkout@v2
# - name: Download all benchmarks as artifact using key
# uses: actions/download-artifact@v2
# with:
# name: benchmarks
# path: benchmarks
# - name: Find and merge all benchmarks
# run: >-
# jq -s '.[0].benchmarks = ([.[].benchmarks] | add)
# | if .[0].benchmarks == null then null else .[0] end'
# benchmarks/output_*.json > output.json;
# - name: Report on benchmark results
# uses: benchmark-action/github-action-benchmark@v1
# with:
# name: OpenTelemetry Python Benchmarks - Python ${{ env[matrix.python-version ]}} - ${{ matrix.package }}
# tool: pytest
# output-file-path: output.json
# github-token: ${{ secrets.GITHUB_TOKEN }}
# max-items-in-chart: 100
# # Alert with a commit comment on possible performance regression
# alert-threshold: 200%
# fail-on-alert: true
# # Make a commit on `gh-pages` with benchmarks from previous step
# auto-push: ${{ github.ref == 'refs/heads/main' }}
# gh-pages-branch: gh-pages
# benchmark-data-dir-path: benchmarks
misc:
strategy:
fail-fast: false
Expand Down
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.10.0-0.29b0...HEAD)

### Added

- `opentelemetry-instrumentation-django` Capture custom request/response headers in span attributes
([#1024])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1024)
- `opentelemetry-instrumentation-asgi` Capture custom request/response headers in span attributes
([#1004])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1004)
- `opentelemetry-instrumentation-psycopg2` extended the sql commenter support of dbapi into psycopg2
([#940](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/940))
- `opentelemetry-instrumentation-flask` Fix non-recording span bug
Expand All @@ -24,9 +27,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [1.10.0-0.29b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.10.0-0.29b0) - 2022-03-10

- `opentelemetry-instrumentation-wsgi` Capture custom request/response headers in span attributes
([#1004])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1004)

- `opentelemetry-instrumentation-wsgi` Capture custom request/response headers in span attributes
([#925])(https://github.com/open-telemetry/opentelemetry-python-contrib/pull/925)
- `opentelemetry-instrumentation-flask` Flask: Capture custom request/response headers in span attributes
Expand Down
2 changes: 1 addition & 1 deletion docs-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ asyncpg>=0.12.0
boto~=2.0
botocore~=1.0
celery>=4.0
flask~=1.0
flask~=2.0
falcon~=2.0
grpcio~=1.27
mysql-connector-python~=8.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,52 @@ def response_hook(span, request, response):
Django Request object: https://docs.djangoproject.com/en/3.1/ref/request-response/#httprequest-objects
Django Response object: https://docs.djangoproject.com/en/3.1/ref/request-response/#httpresponse-objects
Capture HTTP request and response headers
*****************************************
You can configure the agent to capture predefined HTTP headers as span attributes, according to the `semantic convention <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-request-and-response-headers>`_.
Request headers
***************
To capture predefined HTTP request headers as span attributes, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST``
to a comma-separated list of HTTP header names.
For example,
::
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST="content_type,custom_request_header"
will extract content_type and custom_request_header from request headers and add them as span attributes.
It is recommended that you should give the correct names of the headers to be captured in the environment variable.
Request header names in django are case insensitive. So, giving header name as ``CUStom_Header`` in environment variable will be able capture header with name ``custom-header``.
The name of the added span attribute will follow the format ``http.request.header.<header_name>`` where ``<header_name>`` being the normalized HTTP header name (lowercase, with - characters replaced by _ ).
The value of the attribute will be single item list containing all the header values.
Example of the added span attribute,
``http.request.header.custom_request_header = ["<value1>,<value2>"]``
Response headers
****************
To capture predefined HTTP response headers as span attributes, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE``
to a comma-separated list of HTTP header names.
For example,
::
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE="content_type,custom_response_header"
will extract content_type and custom_response_header from response headers and add them as span attributes.
It is recommended that you should give the correct names of the headers to be captured in the environment variable.
Response header names captured in django are case insensitive. So, giving header name as ``CUStomHeader`` in environment variable will be able capture header with name ``customheader``.
The name of the added span attribute will follow the format ``http.response.header.<header_name>`` where ``<header_name>`` being the normalized HTTP header name (lowercase, with - characters replaced by _ ).
The value of the attribute will be single item list containing all the header values.
Example of the added span attribute,
``http.response.header.custom_response_header = ["<value1>,<value2>"]``
API
---
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,19 @@
_start_internal_or_server_span,
extract_attributes_from_object,
)
from opentelemetry.instrumentation.wsgi import (
add_custom_request_headers as wsgi_add_custom_request_headers,
)
from opentelemetry.instrumentation.wsgi import (
add_custom_response_headers as wsgi_add_custom_response_headers,
)
from opentelemetry.instrumentation.wsgi import add_response_attributes
from opentelemetry.instrumentation.wsgi import (
collect_request_attributes as wsgi_collect_request_attributes,
)
from opentelemetry.instrumentation.wsgi import wsgi_getter
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace import Span, use_span
from opentelemetry.trace import Span, SpanKind, use_span
from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs

try:
Expand Down Expand Up @@ -77,7 +83,13 @@ def __call__(self, request):

# try/except block exclusive for optional ASGI imports.
try:
from opentelemetry.instrumentation.asgi import asgi_getter
from opentelemetry.instrumentation.asgi import asgi_getter, asgi_setter
from opentelemetry.instrumentation.asgi import (
collect_custom_request_headers_attributes as asgi_collect_custom_request_attributes,
)
from opentelemetry.instrumentation.asgi import (
collect_custom_response_headers_attributes as asgi_collect_custom_response_attributes,
)
from opentelemetry.instrumentation.asgi import (
collect_request_attributes as asgi_collect_request_attributes,
)
Expand Down Expand Up @@ -213,6 +225,13 @@ def process_request(self, request):
self._traced_request_attrs,
attributes,
)
if span.is_recording() and span.kind == SpanKind.SERVER:
attributes.update(
asgi_collect_custom_request_attributes(carrier)
)
else:
if span.is_recording() and span.kind == SpanKind.SERVER:
wsgi_add_custom_request_headers(span, carrier)

for key, value in attributes.items():
span.set_attribute(key, value)
Expand Down Expand Up @@ -257,6 +276,7 @@ def process_exception(self, request, exception):
if self._environ_activation_key in request.META.keys():
request.META[self._environ_exception_key] = exception

# pylint: disable=too-many-branches
def process_response(self, request, response):
if self._excluded_urls.url_disabled(request.build_absolute_uri("?")):
return response
Expand All @@ -271,12 +291,25 @@ def process_response(self, request, response):
if activation and span:
if is_asgi_request:
set_status_code(span, response.status_code)

if span.is_recording() and span.kind == SpanKind.SERVER:
custom_headers = {}
for key, value in response.items():
asgi_setter.set(custom_headers, key, value)

custom_res_attributes = (
asgi_collect_custom_response_attributes(custom_headers)
)
for key, value in custom_res_attributes.items():
span.set_attribute(key, value)
else:
add_response_attributes(
span,
f"{response.status_code} {response.reason_phrase}",
response.items(),
)
if span.is_recording() and span.kind == SpanKind.SERVER:
wsgi_add_custom_response_headers(span, response.items())

propagator = get_global_response_propagator()
if propagator:
Expand Down
Loading

0 comments on commit f4fba8f

Please sign in to comment.