diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 00000000000..7e4b1032a7d --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,34 @@ +# This action requires that any PR targeting the master branch should touch at +# least one CHANGELOG file. If a CHANGELOG entry is not required, add the "Skip +# Changelog" label to disable this action. + +name: changelog + +on: + pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled] + branches: + - master + +jobs: + changelog: + runs-on: ubuntu-latest + if: "!contains(github.event.pull_request.labels.*.name, 'Skip Changelog')" + + steps: + - uses: actions/checkout@v2 + + - name: Check for CHANGELOG changes + run: | + # Only the latest commit of the feature branch is available + # automatically. To diff with the base branch, we need to + # fetch that too (and we only need its latest commit). + git fetch origin ${{ github.base_ref }} --depth=1 + if [[ $(git diff --name-only FETCH_HEAD | grep CHANGELOG) ]] + then + echo "A CHANGELOG was modified. Looks good!" + else + echo "No CHANGELOG was modified." + echo "Please add a CHANGELOG entry, or add the \"Skip Changelog\" label if not required." + false + fi \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e71b58f94ae..4c7dbc0478b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: fd12b1d624fe44ca17d2c88c0ace39dc80db85df + CONTRIB_REPO_SHA: master jobs: build: @@ -20,24 +20,17 @@ jobs: py36: 3.6 py37: 3.7 py38: 3.8 + py39: 3.9 pypy3: pypy3 + RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - python-version: [ py35, py36, py37, py38, pypy3 ] + python-version: [ py35, py36, py37, py38, py39, pypy3 ] package: ["instrumentation", "core", "exporter"] os: [ ubuntu-latest ] include: - - python-version: py38 - package: "tracecontext" - os: ubuntu-latest - - python-version: py38 - package: "mypy" - os: ubuntu-latest - - python-version: py38 - package: "mypyinstalled" - os: ubuntu-latest # py35-instrumentation segfaults on 18.04 so we instead run on 20.04 - python-version: py35 package: instrumentation @@ -66,14 +59,38 @@ jobs: uses: actions/cache@v2 with: path: .tox - key: tox-cache-${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core + key: tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core - name: run tox - run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} + run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- --benchmark-json=${{ env.RUN_MATRIX_COMBINATION }}-benchmark.json + - name: Find and merge benchmarks + # TODO: Add at least one benchmark to every package type to remove this + if: matrix.package == 'core' + run: >- + jq -s '.[0].benchmarks = ([.[].benchmarks] | add) + | if .[0].benchmarks == null then null else .[0] end' + opentelemetry-*/tests/*${{ matrix.package }}*-benchmark.json > output.json + - name: Report on benchmark results + # TODO: Add at least one benchmark to every package type to remove this + if: matrix.package == 'core' + uses: rhysd/github-action-benchmark@v1 + with: + name: OpenTelemetry Python Benchmarks - Python ${{ env[matrix.python-version ]}} - ${{ matrix.package-group }} + tool: pytest + output-file-path: output.json + github-token: ${{ secrets.GITHUB_TOKEN }} + # Alert with a commit comment on possible performance regression + alert-threshold: 200% + comment-always: true + fail-on-alert: true + # Make a commit on `gh-pages` with benchmarks from previous step + auto-push: ${{ github.ref == 'refs/heads/master' }} + gh-pages-branch: gh-pages + benchmark-data-dir-path: benchmarks misc: strategy: fail-fast: false matrix: - tox-environment: [ "docker-tests", "lint", "docs" ] + tox-environment: [ "docker-tests", "lint", "docs", "mypy", "mypyinstalled", "tracecontext" ] name: ${{ matrix.tox-environment }} runs-on: ubuntu-latest steps: @@ -85,7 +102,7 @@ jobs: repository: open-telemetry/opentelemetry-python-contrib ref: ${{ env.CONTRIB_REPO_SHA }} path: opentelemetry-python-contrib - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 @@ -106,12 +123,13 @@ jobs: py36: 3.6 py37: 3.7 py38: 3.8 + py39: 3.9 pypy3: pypy3 runs-on: ${{ matrix.os }} strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - python-version: [ py35, py36, py37, py38, pypy3 ] + python-version: [ py35, py36, py37, py38, py39, pypy3 ] package: ["instrumentation", "exporter"] os: [ ubuntu-latest ] include: @@ -166,10 +184,10 @@ jobs: with: repository: open-telemetry/opentelemetry-python path: opentelemetry-python-core - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Install tox run: pip install -U tox - name: Cache tox environment diff --git a/.gitignore b/.gitignore index 5378aadb363..d1687658908 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,9 @@ var sdist develop-eggs .installed.cfg +pyvenv.cfg lib +share/ lib64 __pycache__ venv*/ diff --git a/.isort.cfg b/.isort.cfg index cbe7a33601e..85533188fa4 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -3,6 +3,7 @@ include_trailing_comma=True force_grid_wrap=0 use_parentheses=True line_length=79 +profile=black ; 3 stands for Vertical Hanging Indent, e.g. ; from third_party import ( @@ -13,6 +14,6 @@ line_length=79 ; docs: https://github.com/timothycrosley/isort#multi-line-output-modes multi_line_output=3 skip=target -skip_glob=**/gen/*,.venv*/*,venv*/*,**/proto/*,opentelemetry-python-contrib/* +skip_glob=**/gen/*,.venv*/*,venv*/*,**/proto/*,opentelemetry-python-contrib/*,.tox/* known_first_party=opentelemetry,opentelemetry_example_app known_third_party=psutil,pytest,redis,redis_opentracing diff --git a/.pylintrc b/.pylintrc index 58fe77eef1a..5daedb0139d 100644 --- a/.pylintrc +++ b/.pylintrc @@ -70,7 +70,11 @@ disable=missing-docstring, wrong-import-order, # Leave this up to isort bad-continuation, # Leave this up to black line-too-long, # Leave this up to black - exec-used + exec-used, + super-with-arguments, # temp-pylint-upgrade + isinstance-second-argument-not-valid-type, # temp-pylint-upgrade + raise-missing-from, # temp-pylint-upgrade + unused-argument, # temp-pylint-upgrade # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..73ec8a070c7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,492 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v0.16b1...HEAD) + +- Add support for Python 3.9 + ([#1441](https://github.com/open-telemetry/opentelemetry-python/pull/1441)) + +### Added +- Add `fields` to propagators + ([#1374](https://github.com/open-telemetry/opentelemetry-python/pull/1374)) +- Add local/remote samplers to parent based sampler + ([#1440](https://github.com/open-telemetry/opentelemetry-python/pull/1440)) +- Add support for OTEL_SPAN_{ATTRIBUTE_COUNT_LIMIT,EVENT_COUNT_LIMIT,LINK_COUNT_LIMIT} + ([#1377](https://github.com/open-telemetry/opentelemetry-python/pull/1377)) +- Return `None` for `DictGetter` if key not found + ([#1449](https://github.com/open-telemetry/opentelemetry-python/pull/1449)) +- Added support for Jaeger propagator + ([#1219](https://github.com/open-telemetry/opentelemetry-python/pull/1219)) + +## [0.16b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.16b1) - 2020-11-26 +### Added +- Add meter reference to observers + ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) + +## [0.16b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.16b0) - 2020-11-25 +### Added +- Add optional parameter to `record_exception` method + ([#1314](https://github.com/open-telemetry/opentelemetry-python/pull/1314)) +- Add pickle support to SpanContext class + ([#1380](https://github.com/open-telemetry/opentelemetry-python/pull/1380)) +- Add instrumentation library name and version to OTLP exported metrics + ([#1418](https://github.com/open-telemetry/opentelemetry-python/pull/1418)) +- Add Gzip compression for exporter + ([#1141](https://github.com/open-telemetry/opentelemetry-python/pull/1141)) +- Support for v2 api protobuf format + ([#1318](https://github.com/open-telemetry/opentelemetry-python/pull/1318)) +- Add IDs Generator as Configurable Property of Auto Instrumentation + ([#1404](https://github.com/open-telemetry/opentelemetry-python/pull/1404)) +- Added support for `OTEL_EXPORTER` to the `opentelemetry-instrument` command + ([#1036](https://github.com/open-telemetry/opentelemetry-python/pull/1036)) +### Changed +- Change temporality for Counter and UpDownCounter + ([#1384](https://github.com/open-telemetry/opentelemetry-python/pull/1384)) +- OTLP exporter: Handle error case when no credentials supplied + ([#1366](https://github.com/open-telemetry/opentelemetry-python/pull/1366)) +- Update protobuf versions + ([#1356](https://github.com/open-telemetry/opentelemetry-python/pull/1356)) +- Add missing references to instrumented packages + ([#1416](https://github.com/open-telemetry/opentelemetry-python/pull/1416)) +- Instrumentation Package depends on the OTel SDK + ([#1405](https://github.com/open-telemetry/opentelemetry-python/pull/1405)) +- Allow samplers to modify tracestate + ([#1319](https://github.com/open-telemetry/opentelemetry-python/pull/1319)) +- Update exception handling optional parameters, add escaped attribute to record_exception + ([#1365](https://github.com/open-telemetry/opentelemetry-python/pull/1365)) +- Rename `MetricRecord` to `ExportRecord` + ([#1367](https://github.com/open-telemetry/opentelemetry-python/pull/1367)) +- Rename `Record` to `Accumulation` + ([#1373](https://github.com/open-telemetry/opentelemetry-python/pull/1373)) +- Rename `Meter` to `Accumulator` + ([#1372](https://github.com/open-telemetry/opentelemetry-python/pull/1372)) +- Fix `ParentBased` sampler for implicit parent spans. Fix also `trace_state` + erasure for dropped spans or spans sampled by the `TraceIdRatioBased` sampler. + ([#1394](https://github.com/open-telemetry/opentelemetry-python/pull/1394)) + +## [0.15b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.15b0) -2020-11-02 + +### Added +- Add Env variables in OTLP exporter + ([#1101](https://github.com/open-telemetry/opentelemetry-python/pull/1101)) +- Add support for Jaeger Span Exporter configuration by environment variables and
+ change JaegerSpanExporter constructor parameters + ([#1114](https://github.com/open-telemetry/opentelemetry-python/pull/1114)) + +### Changed +- Updating status codes to adhere to specs + ([#1282](https://github.com/open-telemetry/opentelemetry-python/pull/1282)) +- Set initial checkpoint timestamp in aggregators + ([#1237](https://github.com/open-telemetry/opentelemetry-python/pull/1237)) +- Make `SpanProcessor.on_start` accept parent Context + ([#1251](https://github.com/open-telemetry/opentelemetry-python/pull/1251)) +- Fix b3 propagator entrypoint + ([#1265](https://github.com/open-telemetry/opentelemetry-python/pull/1265)) +- Allow None in sequence attributes values + ([#998](https://github.com/open-telemetry/opentelemetry-python/pull/998)) +- Samplers to accept parent Context + ([#1267](https://github.com/open-telemetry/opentelemetry-python/pull/1267)) +- Span.is_recording() returns false after span has ended + ([#1289](https://github.com/open-telemetry/opentelemetry-python/pull/1289)) +- Allow samplers to modify tracestate + ([#1319](https://github.com/open-telemetry/opentelemetry-python/pull/1319)) +- Remove TracerProvider coupling from Tracer init + ([#1295](https://github.com/open-telemetry/opentelemetry-python/pull/1295)) + +## [0.14b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.14b0) - 2020-10-13 + +### Added +- Add optional parameter to `record_exception` method + ([#1242](https://github.com/open-telemetry/opentelemetry-python/pull/1242)) +- Add support for `OTEL_PROPAGATORS` + ([#1123](https://github.com/open-telemetry/opentelemetry-python/pull/1123)) +- Add keys method to TextMap propagator Getter + ([#1196](https://github.com/open-telemetry/opentelemetry-python/issues/1196)) +- Add timestamps to OTLP exporter + ([#1199](https://github.com/open-telemetry/opentelemetry-python/pull/1199)) +- Add Global Error Handler + ([#1080](https://github.com/open-telemetry/opentelemetry-python/pull/1080)) +- Add support for `OTEL_BSP_MAX_QUEUE_SIZE`, `OTEL_BSP_SCHEDULE_DELAY_MILLIS`, `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` and `OTEL_BSP_EXPORT_TIMEOUT_MILLIS` environment variables + ([#1105](https://github.com/open-telemetry/opentelemetry-python/pull/1120)) +- Adding Resource to MeterRecord + ([#1209](https://github.com/open-telemetry/opentelemetry-python/pull/1209)) +s +### Changed +- Store `int`s as `int`s in the global Configuration object + ([#1118](https://github.com/open-telemetry/opentelemetry-python/pull/1118)) +- Allow for Custom Trace and Span IDs Generation - `IdsGenerator` for TracerProvider + ([#1153](https://github.com/open-telemetry/opentelemetry-python/pull/1153)) +- Update baggage propagation header + ([#1194](https://github.com/open-telemetry/opentelemetry-python/pull/1194)) +- Make instances of SpanContext immutable + ([#1134](https://github.com/open-telemetry/opentelemetry-python/pull/1134)) +- Parent is now always passed in via Context, intead of Span or SpanContext + ([#1146](https://github.com/open-telemetry/opentelemetry-python/pull/1146)) +- Update OpenTelemetry protos to v0.5.0 + ([#1143](https://github.com/open-telemetry/opentelemetry-python/pull/1143)) +- Zipkin exporter now accepts a ``max_tag_value_length`` attribute to customize the + maximum allowed size a tag value can have. + ([#1151](https://github.com/open-telemetry/opentelemetry-python/pull/1151)) +- Fixed OTLP events to Zipkin annotations translation. + ([#1161](https://github.com/open-telemetry/opentelemetry-python/pull/1161)) +- Fixed bootstrap command to correctly install opentelemetry-instrumentation-falcon instead of opentelemetry-instrumentation-flask. + ([#1138](https://github.com/open-telemetry/opentelemetry-python/pull/1138)) +- Update sampling result names + ([#1128](https://github.com/open-telemetry/opentelemetry-python/pull/1128)) +- Event attributes are now immutable + ([#1195](https://github.com/open-telemetry/opentelemetry-python/pull/1195)) +- Renaming metrics Batcher to Processor + ([#1203](https://github.com/open-telemetry/opentelemetry-python/pull/1203)) +- Protect access to Span implementation + ([#1188](https://github.com/open-telemetry/opentelemetry-python/pull/1188)) +- `start_as_current_span` and `use_span` can now optionally auto-record any exceptions raised inside the context manager. + ([#1162](https://github.com/open-telemetry/opentelemetry-python/pull/1162)) + +## [0.13b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.13b0) - 2020-09-17 + +### Added +- Add instrumentation info to exported spans + ([#1095](https://github.com/open-telemetry/opentelemetry-python/pull/1095)) +- Add metric OTLP exporter + ([#835](https://github.com/open-telemetry/opentelemetry-python/pull/835)) +- Add type hints to OTLP exporter + ([#1121](https://github.com/open-telemetry/opentelemetry-python/pull/1121)) +- Add support for OTEL_EXPORTER_ZIPKIN_ENDPOINT env var. As part of this change, the + configuration of the ZipkinSpanExporter exposes a `url` argument to replace `host_name`, + `port`, `protocol`, `endpoint`. This brings this implementation inline with other + implementations. + ([#1064](https://github.com/open-telemetry/opentelemetry-python/pull/1064)) +- Zipkin exporter report instrumentation info. + ([#1097](https://github.com/open-telemetry/opentelemetry-python/pull/1097)) +- Add status mapping to tags + ([#1111](https://github.com/open-telemetry/opentelemetry-python/issues/1111)) +- Report instrumentation info + ([#1098](https://github.com/open-telemetry/opentelemetry-python/pull/1098)) +- Add support for http metrics + ([#1116](https://github.com/open-telemetry/opentelemetry-python/pull/1116)) +- Populate resource attributes as per semantic conventions + ([#1053](https://github.com/open-telemetry/opentelemetry-python/pull/1053)) + +### Changed +- Refactor `SpanContext.is_valid` from a method to a data attribute + ([#1005](https://github.com/open-telemetry/opentelemetry-python/pull/1005)) +- Moved samplers from API to SDK + ([#1023](https://github.com/open-telemetry/opentelemetry-python/pull/1023)) +- Change return value type of `correlationcontext.get_correlations` to immutable `MappingProxyType` + ([#1024](https://github.com/open-telemetry/opentelemetry-python/pull/1024)) +- Sampling spec changes + ([#1034](https://github.com/open-telemetry/opentelemetry-python/pull/1034)) +- Remove lazy Event and Link API from Span interface + ([#1045](https://github.com/open-telemetry/opentelemetry-python/pull/1045)) +- Rename CorrelationContext to Baggage + ([#1060](https://github.com/open-telemetry/opentelemetry-python/pull/1060)) +- Rename HTTPTextFormat to TextMapPropagator. This change also updates `get_global_httptextformat` and + `set_global_httptextformat` to `get_global_textmap` and `set_global_textmap` + ([#1085](https://github.com/open-telemetry/opentelemetry-python/pull/1085)) +- Fix api/sdk setup.cfg to include missing python files + ([#1091](https://github.com/open-telemetry/opentelemetry-python/pull/1091)) +- Improve BatchExportSpanProcessor + ([#1062](https://github.com/open-telemetry/opentelemetry-python/pull/1062)) +- Rename Resource labels to attributes + ([#1082](https://github.com/open-telemetry/opentelemetry-python/pull/1082)) +- Rename members of `trace.sampling.Decision` enum + ([#1115](https://github.com/open-telemetry/opentelemetry-python/pull/1115)) +- Merge `OTELResourceDetector` result when creating resources + ([#1096](https://github.com/open-telemetry/opentelemetry-python/pull/1096)) + +### Removed +- Drop support for Python 3.4 + ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) + +## [0.12b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.12.0) - 2020-08-14 + +### Added +- Implement Views in metrics SDK + ([#596](https://github.com/open-telemetry/opentelemetry-python/pull/596)) + +### Changed +- Update environment variable names, prefix changed from `OPENTELEMETRY` to `OTEL` + ([#904](https://github.com/open-telemetry/opentelemetry-python/pull/904)) +- Stop TracerProvider and MeterProvider from being overridden + ([#959](https://github.com/open-telemetry/opentelemetry-python/pull/959)) +- Update default port to 55680 + ([#977](https://github.com/open-telemetry/opentelemetry-python/pull/977)) +- Add proper length zero padding to hex strings of traceId, spanId, parentId sent on the wire, for compatibility with jaeger-collector + ([#908](https://github.com/open-telemetry/opentelemetry-python/pull/908)) +- Send start_timestamp and convert labels to strings + ([#937](https://github.com/open-telemetry/opentelemetry-python/pull/937)) +- Renamed several packages + ([#953](https://github.com/open-telemetry/opentelemetry-python/pull/953)) +- Thrift URL for Jaeger exporter doesn't allow HTTPS (hardcoded to HTTP) + ([#978](https://github.com/open-telemetry/opentelemetry-python/pull/978)) +- Change reference names to opentelemetry-instrumentation-opentracing-shim + ([#969](https://github.com/open-telemetry/opentelemetry-python/pull/969)) +- Changed default Sampler to `ParentOrElse(AlwaysOn)` + ([#960](https://github.com/open-telemetry/opentelemetry-python/pull/960)) +- Update environment variable names, prefix changed from `OPENTELEMETRY` to `OTEL` + ([#904](https://github.com/open-telemetry/opentelemetry-python/pull/904)) +- Update environment variable `OTEL_RESOURCE` to `OTEL_RESOURCE_ATTRIBUTES` as per + the specification + +## [0.11b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.11.0) - 2020-07-28 + +### Added +- Add support for resources and resource detector + ([#853](https://github.com/open-telemetry/opentelemetry-python/pull/853)) +### Changed +- Return INVALID_SPAN if no TracerProvider set for get_current_span + ([#751](https://github.com/open-telemetry/opentelemetry-python/pull/751)) +- Rename record_error to record_exception + ([#927](https://github.com/open-telemetry/opentelemetry-python/pull/927)) +- Update span exporter to use OpenTelemetry Proto v0.4.0 + ([#872](https://github.com/open-telemetry/opentelemetry-python/pull/889)) + +## [0.10b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.10.0) - 2020-06-23 + +### Changed +- Regenerate proto code and add pyi stubs + ([#823](https://github.com/open-telemetry/opentelemetry-python/pull/823)) +- Rename CounterAggregator -> SumAggregator + ([#816](https://github.com/open-telemetry/opentelemetry-python/pull/816)) + +## [0.9b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.9.0) - 2020-06-10 + +### Added +- Adding trace.get_current_span, Removing Tracer.get_current_span + ([#552](https://github.com/open-telemetry/opentelemetry-python/pull/552)) +- Add SumObserver, UpDownSumObserver and LastValueAggregator in metrics + ([#789](https://github.com/open-telemetry/opentelemetry-python/pull/789)) +- Add start_pipeline to MeterProvider + ([#791](https://github.com/open-telemetry/opentelemetry-python/pull/791)) +- Initial release of opentelemetry-ext-otlp, opentelemetry-proto +### Changed +- Move stateful & resource from Meter to MeterProvider + ([#751](https://github.com/open-telemetry/opentelemetry-python/pull/751)) +- Rename Measure to ValueRecorder in metrics + ([#761](https://github.com/open-telemetry/opentelemetry-python/pull/761)) +- Rename Observer to ValueObserver + ([#764](https://github.com/open-telemetry/opentelemetry-python/pull/764)) +- Log a warning when replacing the global Tracer/Meter provider + ([#856](https://github.com/open-telemetry/opentelemetry-python/pull/856)) +- bugfix: byte type attributes are decoded before adding to attributes dict + ([#775](https://github.com/open-telemetry/opentelemetry-python/pull/775)) +- Rename opentelemetry-auto-instrumentation to opentelemetry-instrumentation, + and console script `opentelemetry-auto-instrumentation` to `opentelemetry-instrument` + +## [0.8b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.8.0) - 2020-05-27 + +### Added +- Add a new bootstrap command that enables automatic instrument installations. + ([#650](https://github.com/open-telemetry/opentelemetry-python/pull/650)) + +### Changed +- Handle boolean, integer and float values in Configuration + ([#662](https://github.com/open-telemetry/opentelemetry-python/pull/662)) +- bugfix: ensure status is always string + ([#640](https://github.com/open-telemetry/opentelemetry-python/pull/640)) +- Transform resource to tags when exporting + ([#707](https://github.com/open-telemetry/opentelemetry-python/pull/707)) +- Rename otcollector to opencensus + ([#695](https://github.com/open-telemetry/opentelemetry-python/pull/695)) +- Transform resource to tags when exporting + ([#645](https://github.com/open-telemetry/opentelemetry-python/pull/645)) +- `ext/boto`: Could not serialize attribute aws.region to tag when exporting via jaeger + Serialize tuple type values by coercing them into a string, since Jaeger does not + support tuple types. + ([#865](https://github.com/open-telemetry/opentelemetry-python/pull/865)) +- Validate span attribute types in SDK + ([#678](https://github.com/open-telemetry/opentelemetry-python/pull/678)) +- Specify to_json indent from arguments + ([#718](https://github.com/open-telemetry/opentelemetry-python/pull/718)) +- Span.resource will now default to an empty resource + ([#724](https://github.com/open-telemetry/opentelemetry-python/pull/724)) +- bugfix: Fix error message + ([#729](https://github.com/open-telemetry/opentelemetry-python/pull/729)) +- deep copy empty attributes + ([#714](https://github.com/open-telemetry/opentelemetry-python/pull/714)) + +## [0.7b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.7.1) - 2020-05-12 + +### Added +- Add reset for the global configuration object, for testing purposes + ([#636](https://github.com/open-telemetry/opentelemetry-python/pull/636)) +- Add support for programmatic instrumentation + ([#579](https://github.com/open-telemetry/opentelemetry-python/pull/569)) + +### Changed +- tracer.get_tracer now optionally accepts a TracerProvider + ([#602](https://github.com/open-telemetry/opentelemetry-python/pull/602)) +- Configuration object can now be used by any component of opentelemetry, + including 3rd party instrumentations + ([#563](https://github.com/open-telemetry/opentelemetry-python/pull/563)) +- bugfix: configuration object now matches fields in a case-sensitive manner + ([#583](https://github.com/open-telemetry/opentelemetry-python/pull/583)) +- bugfix: configuration object now accepts all valid python variable names + ([#583](https://github.com/open-telemetry/opentelemetry-python/pull/583)) +- bugfix: configuration undefined attributes now return None instead of raising + an AttributeError. + ([#583](https://github.com/open-telemetry/opentelemetry-python/pull/583)) +- bugfix: 'debug' field is now correct + ([#549](https://github.com/open-telemetry/opentelemetry-python/pull/549)) +- bugfix: enable auto-instrumentation command to work for custom entry points + (e.g. flask_run) + ([#567](https://github.com/open-telemetry/opentelemetry-python/pull/567)) +- Exporter API: span parents are now always spancontext + ([#548](https://github.com/open-telemetry/opentelemetry-python/pull/548)) +- Console span exporter now prints prettier, more legible messages + ([#505](https://github.com/open-telemetry/opentelemetry-python/pull/505)) +- bugfix: B3 propagation now retrieves parentSpanId correctly + ([#621](https://github.com/open-telemetry/opentelemetry-python/pull/621)) +- bugfix: a DefaultSpan now longer causes an exception when used with tracer + ([#577](https://github.com/open-telemetry/opentelemetry-python/pull/577)) +- move last_updated_timestamp into aggregators instead of bound metric + instrument + ([#522](https://github.com/open-telemetry/opentelemetry-python/pull/522)) +- bugfix: suppressing instrumentation in metrics to eliminate an infinite loop + of telemetry + ([#529](https://github.com/open-telemetry/opentelemetry-python/pull/529)) +- bugfix: freezing span attribute sequences, reducing potential user errors + ([#529](https://github.com/open-telemetry/opentelemetry-python/pull/529)) + +## [0.6b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.6.0) - 2020-03-30 + +### Added +- Add support for lazy events and links + ([#474](https://github.com/open-telemetry/opentelemetry-python/pull/474)) +- Adding is_remote flag to SpanContext, indicating when a span is remote + ([#516](https://github.com/open-telemetry/opentelemetry-python/pull/516)) +- Adding a solution to release metric handles and observers + ([#435](https://github.com/open-telemetry/opentelemetry-python/pull/435)) +- Initial release: opentelemetry-instrumentation + +### Changed +- Metrics API no longer uses LabelSet + ([#527](https://github.com/open-telemetry/opentelemetry-python/pull/527)) +- Allow digit as first char in vendor specific trace state key + ([#511](https://github.com/open-telemetry/opentelemetry-python/pull/511)) +- Exporting to collector now works + ([#508](https://github.com/open-telemetry/opentelemetry-python/pull/508)) + +## [0.5b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.5.0) - 2020-03-16 + +### Added +- Adding Correlation Context API/SDK and propagator + ([#471](https://github.com/open-telemetry/opentelemetry-python/pull/471)) +- Adding a global configuration module to simplify setting and getting globals + ([#466](https://github.com/open-telemetry/opentelemetry-python/pull/466)) +- Adding named meters, removing batchers + ([#431](https://github.com/open-telemetry/opentelemetry-python/pull/431)) +- Adding attach/detach methods as per spec + ([#429](https://github.com/open-telemetry/opentelemetry-python/pull/429)) +- Adding OT Collector metrics exporter + ([#454](https://github.com/open-telemetry/opentelemetry-python/pull/454)) +- Initial release opentelemetry-ext-otcollector + +### Changed +- Rename metric handle to bound metric instrument + ([#470](https://github.com/open-telemetry/opentelemetry-python/pull/470)) +- Moving resources to sdk + ([#464](https://github.com/open-telemetry/opentelemetry-python/pull/464)) +- Implementing propagators to API to use context + ([#446](https://github.com/open-telemetry/opentelemetry-python/pull/446)) +- Renaming TraceOptions to TraceFlags + ([#450](https://github.com/open-telemetry/opentelemetry-python/pull/450)) +- Renaming TracerSource to TracerProvider + ([#441](https://github.com/open-telemetry/opentelemetry-python/pull/441)) +- Improve validation of attributes + ([#460](https://github.com/open-telemetry/opentelemetry-python/pull/460)) +- Re-raise errors caught in opentelemetry.sdk.trace.Tracer.use_span() + ([#469](https://github.com/open-telemetry/opentelemetry-python/pull/469)) +- Implement observer instrument + ([#425](https://github.com/open-telemetry/opentelemetry-python/pull/425)) + +## [0.4a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.4.0) - 2020-02-21 + +### Added +- Added named Tracers + ([#301](https://github.com/open-telemetry/opentelemetry-python/pull/301)) +- Add int and valid sequenced to AttributeValue type + ([#368](https://github.com/open-telemetry/opentelemetry-python/pull/368)) +- Add ABC for Metric + ([#391](https://github.com/open-telemetry/opentelemetry-python/pull/391)) +- Metrics export pipeline, and stdout exporter + ([#341](https://github.com/open-telemetry/opentelemetry-python/pull/341)) +- Adding Context API Implementation + ([#395](https://github.com/open-telemetry/opentelemetry-python/pull/395)) +- Adding trace.get_tracer function + ([#430](https://github.com/open-telemetry/opentelemetry-python/pull/430)) +- Add runtime validation for set_attribute + ([#348](https://github.com/open-telemetry/opentelemetry-python/pull/348)) +- Add support for B3 ParentSpanID + ([#286](https://github.com/open-telemetry/opentelemetry-python/pull/286)) +- Implement MinMaxSumCount aggregator + ([#422](https://github.com/open-telemetry/opentelemetry-python/pull/422)) +- Initial release opentelemetry-ext-zipkin, opentelemetry-ext-prometheus + +### Changed +- Separate Default classes from interface descriptions + ([#311](https://github.com/open-telemetry/opentelemetry-python/pull/311)) +- Export span status + ([#367](https://github.com/open-telemetry/opentelemetry-python/pull/367)) +- Export span kind + ([#387](https://github.com/open-telemetry/opentelemetry-python/pull/387)) +- Set status for ended spans + ([#297](https://github.com/open-telemetry/opentelemetry-python/pull/297) and + [#358](https://github.com/open-telemetry/opentelemetry-python/pull/358)) +- Use module loggers + ([#351](https://github.com/open-telemetry/opentelemetry-python/pull/351)) +- Protect start_time and end_time from being set manually by the user + ([#363](https://github.com/open-telemetry/opentelemetry-python/pull/363)) +- Set status in start_as_current_span + ([#377](https://github.com/open-telemetry/opentelemetry-python/pull/377)) +- Implement force_flush for span processors + ([#389](https://github.com/open-telemetry/opentelemetry-python/pull/389)) +- Set sampled flag on sampling trace + ([#407](https://github.com/open-telemetry/opentelemetry-python/pull/407)) +- Add io and formatter options to console exporter + ([#412](https://github.com/open-telemetry/opentelemetry-python/pull/412)) +- Clean up ProbabilitySample for 64 bit trace IDs + ([#238](https://github.com/open-telemetry/opentelemetry-python/pull/238)) + +### Removed +- Remove monotonic and absolute metric instruments + ([#410](https://github.com/open-telemetry/opentelemetry-python/pull/410)) + +## [0.3a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.3.0) - 2019-12-11 + +### Added +- Add metrics exporters + ([#192](https://github.com/open-telemetry/opentelemetry-python/pull/192)) +- Implement extract and inject support for HTTP_HEADERS and TEXT_MAP formats + ([#256](https://github.com/open-telemetry/opentelemetry-python/pull/256)) + +### Changed +- Multiple tracing API/SDK changes +- Multiple metrics API/SDK changes + +### Removed +- Remove option to create unstarted spans from API + ([#290](https://github.com/open-telemetry/opentelemetry-python/pull/290)) + +## [0.2a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.2.0) - 2019-10-29 + +### Added +- W3C TraceContext fixes and compliance tests + ([#228](https://github.com/open-telemetry/opentelemetry-python/pull/228)) +- Sampler API/SDK + ([#225](https://github.com/open-telemetry/opentelemetry-python/pull/225)) +- Initial release: opentelemetry-ext-jaeger, opentelemetry-opentracing-shim + +### Changed +- Multiple metrics API/SDK changes +- Multiple tracing API/SDK changes +- Multiple context API changes +- Multiple bugfixes and improvements + +## [0.1a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.1.0) - 2019-09-30 + +### Added +- Initial release api/sdk diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4981eb5547f..7612cb8516c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,6 +66,31 @@ See [`tox.ini`](https://github.com/open-telemetry/opentelemetry-python/blob/master/tox.ini) for more detail on available tox commands. +### Benchmarks + +Performance progression of benchmarks for packages distributed by OpenTelemetry Python can be viewed as a [graph of throughput vs commit history](https://opentelemetry-python.readthedocs.io/en/latest/performance/benchmarks.html). From the linked page, you can download a JSON file with the performance results. + +Running the `tox` tests also runs the performance tests if any are available. Benchmarking tests are done with `pytest-benchmark` and they output a table with results to the console. + +To write benchmarks, simply use the [pytest benchmark fixture](https://pytest-benchmark.readthedocs.io/en/latest/usage.html#usage) like the following: + +```python +def test_simple_start_span(benchmark): + def benchmark_start_as_current_span(span_name, attribute_num): + span = tracer.start_span( + span_name, + attributes={"count": attribute_num}, + ) + span.end() + + benchmark(benchmark_start_as_current_span, "benchmarkedSpan", 42) +``` + +Make sure the test file is under the `tests/performance/benchmarks/` folder of +the package it is benchmarking and further has a path that corresponds to the +file in the package it is testing. Make sure that the file name begins with +`test_benchmark_`. (e.g. `opentelemetry-sdk/tests/performance/benchmarks/trace/propagation/test_benchmark_b3_format.py`) + ## Pull Requests ### How to Send Pull Requests diff --git a/README.md b/README.md index 507ebaf6499..8d211cd118e 100644 --- a/README.md +++ b/README.md @@ -38,23 +38,22 @@ ## OpenTelemetry Python -The Python [OpenTelemetry](https://opentelemetry.io/) implementation. +This page describes the Python [OpenTelemetry](https://opentelemetry.io/) implementation. OpenTelemetry is an observability framework for cloud-native software. ## Getting started -OpenTelemetry's goal is to provide a single set of APIs to capture distributed traces and metrics from your application and send them to an observability platform. This project allows you to do just that for applications written in Python. +The goal of OpenTelemetry is to provide a single set of APIs to capture distributed traces and metrics from your application and send them to an observability platform. This project lets you do just that for applications written in Python. This repository includes multiple installable packages. The `opentelemetry-api` -package includes abstract classes and no-op implementations that comprise the OpenTelemetry API following -[the -specification](https://github.com/open-telemetry/opentelemetry-specification). +package includes abstract classes and no-op implementations that comprise the OpenTelemetry API following the +[OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification). The `opentelemetry-sdk` package is the reference implementation of the API. Libraries that produce telemetry data should only depend on `opentelemetry-api`, and defer the choice of the SDK to the application developer. Applications may depend on `opentelemetry-sdk` or another package that implements the API. -The API and SDK packages are available on PyPI, and can installed via `pip`: +The API and SDK packages are available on the Python Package Index (PyPI). You can install them via `pip` with the following commands: ```sh pip install opentelemetry-api @@ -63,7 +62,7 @@ pip install opentelemetry-sdk The [`instrumentation/`](https://github.com/open-telemetry/opentelemetry-python/tree/master/instrumentation) -directory includes OpenTelemetry instrumentation packages, which can be installed separately as: +directory includes OpenTelemetry instrumentation packages. You can install the packages separately with the following command: ```sh pip install opentelemetry-instrumentation-{instrumentation} @@ -71,14 +70,14 @@ pip install opentelemetry-instrumentation-{instrumentation} The [`exporter/`](https://github.com/open-telemetry/opentelemetry-python/tree/master/exporter) -directory includes OpenTelemetry exporter packages, which can be installed separately as: +directory includes OpenTelemetry exporter packages. You can install the packages separately with the following command: ```sh pip install opentelemetry-exporter-{exporter} ``` To install the development versions of these packages instead, clone or fork -this repo and do an [editable +this repository and perform an [editable install](https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs): ```sh @@ -87,17 +86,20 @@ pip install -e ./opentelemetry-sdk pip install -e ./instrumentation/opentelemetry-instrumentation-{instrumentation} ``` +For additional exporter and instrumentation packages, see the +[`opentelemetry-python-contrib`](https://github.com/open-telemetry/opentelemetry-python-contrib) repository. + ## Documentation -The online documentation is available at https://opentelemetry-python.readthedocs.io/, -if you want to access the documentation for the latest version use +The online documentation is available at https://opentelemetry-python.readthedocs.io/. +To access the latest version of the documentation, see https://opentelemetry-python.readthedocs.io/en/latest/. ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md). +For information about contributing to OpenTelemetry Python, see [CONTRIBUTING.md](CONTRIBUTING.md). -We meet weekly on Thursday at 9AM PT. The meeting is subject to change depending on contributors' availability. Check the [OpenTelemetry community calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com) for specific dates. +We meet weekly on Thursdays at 9AM PST. The meeting is subject to change depending on contributors' availability. Check the [OpenTelemetry community calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com) for specific dates. Meetings take place via [Zoom video conference](https://zoom.us/j/6729396170). @@ -115,14 +117,14 @@ Approvers ([@open-telemetry/python-approvers](https://github.com/orgs/open-telem - [Reiley Yang](https://github.com/reyang), Microsoft - [Yusuke Tsutsumi](https://github.com/toumorokoshi), Google -*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).* +*For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).* Maintainers ([@open-telemetry/python-maintainers](https://github.com/orgs/open-telemetry/teams/python-maintainers)): - [Alex Boten](https://github.com/codeboten), Lightstep - [Leighton Chen](https://github.com/lzchen), Microsoft -*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer).* +*For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer).* ### Thanks to all the people who already contributed! @@ -132,5 +134,9 @@ Maintainers ([@open-telemetry/python-maintainers](https://github.com/orgs/open-t ## Project Status -Project [boards](https://github.com/open-telemetry/opentelemetry-python/projects) and [milestones](https://github.com/open-telemetry/opentelemetry-python/milestones) can be found at the respective links. We try to keep these accurate and should be the best place to go for answers on project status. The dates and features described in issues -and milestones are estimates, and subject to change. +For project boards and milestones, see the following links: +- [Project boards](https://github.com/open-telemetry/opentelemetry-python/projects) +- [Milestones](https://github.com/open-telemetry/opentelemetry-python/milestones) + +We try to keep these links accurate, so they're the best place to go for questions about project status. The dates and features described in the issues +and milestones are estimates and subject to change. diff --git a/dev-requirements.txt b/dev-requirements.txt index 489fc33fcb4..bd2515b1170 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1,9 @@ -pylint==2.4.4 +pylint==2.6.0 flake8~=3.7 -isort~=4.3 +isort~=5.6 black>=19.3b0,==19.* -mypy==0.770 +httpretty~=1.0 +mypy==0.790 sphinx~=2.1 sphinx-rtd-theme~=0.4 sphinx-autodoc-typehints~=1.10.2 diff --git a/docs-requirements.txt b/docs-requirements.txt index 9a175692051..64fd71c5a99 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -6,13 +6,13 @@ sphinx-autodoc-typehints~=1.10.2 # doesn't work for pkg_resources. ./opentelemetry-api ./opentelemetry-sdk -./opentelemetry-python-contrib/exporter/opentelemetry-exporter-datadog -./opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-grpc +-e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-exporter-datadog&subdirectory=exporter/opentelemetry-exporter-datadog" +-e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-instrumentation-grpc&subdirectory=instrumentation/opentelemetry-instrumentation-grpc" ./opentelemetry-instrumentation -./opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-requests -./opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-wsgi -./opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-django -./opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-flask +-e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-instrumentation-requests&subdirectory=instrumentation/opentelemetry-instrumentation-requests" +-e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-instrumentation-wsgi&subdirectory=instrumentation/opentelemetry-instrumentation-wsgi" +-e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-instrumentation-django&subdirectory=instrumentation/opentelemetry-instrumentation-django" +-e "git+https://github.com/open-telemetry/opentelemetry-python-contrib.git#egg=opentelemetry-instrumentation-flask&subdirectory=instrumentation/opentelemetry-instrumentation-flask" # Required by ext packages asgiref~=3.0 diff --git a/docs/examples/auto-instrumentation/README.rst b/docs/examples/auto-instrumentation/README.rst index 36132daf5e2..d7e59eedefc 100644 --- a/docs/examples/auto-instrumentation/README.rst +++ b/docs/examples/auto-instrumentation/README.rst @@ -37,9 +37,8 @@ Manually instrumented server def server_request(): with tracer.start_as_current_span( "server_request", - parent=propagators.extract( - lambda dict_, key: dict_.get(key, []), request.headers - )["current-span"], + context=propagators.extract(DictGetter(), request.headers + ), ): print(request.args.get("param")) return "served" @@ -137,7 +136,12 @@ similar to the following example: "http.flavor": "1.1" }, "events": [], - "links": [] + "links": [], + "resource": { + "telemetry.sdk.language": "python", + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.version": "0.16b1" + } } Execute an automatically instrumented server @@ -148,7 +152,7 @@ and run the following command instead: .. code:: sh - $ opentelemetry-instrument python server_uninstrumented.py + $ opentelemetry-instrument -e console_span,console_metrics python server_uninstrumented.py In the console where you previously executed ``client.py``, run the following command again: @@ -192,7 +196,13 @@ similar to the following example: "http.status_code": 200 }, "events": [], - "links": [] + "links": [], + "resource": { + "telemetry.sdk.language": "python", + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.version": "0.16b1", + "service.name": "" + } } You can see that both outputs are the same because automatic instrumentation does diff --git a/docs/examples/auto-instrumentation/server_instrumented.py b/docs/examples/auto-instrumentation/server_instrumented.py index c8562828be9..6212ec33336 100644 --- a/docs/examples/auto-instrumentation/server_instrumented.py +++ b/docs/examples/auto-instrumentation/server_instrumented.py @@ -21,6 +21,7 @@ ConsoleSpanExporter, SimpleExportSpanProcessor, ) +from opentelemetry.trace.propagation.textmap import DictGetter app = Flask(__name__) @@ -36,9 +37,7 @@ def server_request(): with tracer.start_as_current_span( "server_request", - parent=propagators.extract( - lambda dict_, key: dict_.get(key, []), request.headers - )["current-span"], + context=propagators.extract(DictGetter(), request.headers), kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(request.environ), ): diff --git a/docs/examples/basic_meter/basic_metrics.py b/docs/examples/basic_meter/basic_metrics.py index 0d57238c2db..73415682056 100644 --- a/docs/examples/basic_meter/basic_metrics.py +++ b/docs/examples/basic_meter/basic_metrics.py @@ -16,9 +16,9 @@ This module serves as an example for a simple application using metrics. It shows: -- How to configure a meter passing a sateful or stateless. +- How to configure a meter passing a stateful or stateless. - How to configure an exporter and how to create a controller. -- How to create some metrics intruments and how to capture data with them. +- How to create some metrics instruments and how to capture data with them. - How to use views to specify aggregation types for each metric instrument. """ import sys diff --git a/docs/examples/django/pages/views.py b/docs/examples/django/pages/views.py index 9d277e2b7f7..4083888e17b 100644 --- a/docs/examples/django/pages/views.py +++ b/docs/examples/django/pages/views.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from django.http import HttpResponse + from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg index d0a7b6275e3..e3c039c0453 100644 --- a/docs/examples/error_hander/error_handler_0/setup.cfg +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -29,6 +29,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg index 304b32fd5e9..749b0d827f7 100644 --- a/docs/examples/error_hander/error_handler_1/setup.cfg +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -29,6 +29,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/docs/examples/opentracing/main.py b/docs/examples/opentracing/main.py index 0653ca82ece..bff9a7c3da8 100755 --- a/docs/examples/opentracing/main.py +++ b/docs/examples/opentracing/main.py @@ -1,11 +1,12 @@ #!/usr/bin/env python +from rediscache import RedisCache + from opentelemetry import trace from opentelemetry.exporter.jaeger import JaegerSpanExporter from opentelemetry.instrumentation import opentracing_shim from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor -from rediscache import RedisCache # Configure the tracer using the default implementation trace.set_tracer_provider(TracerProvider()) diff --git a/docs/index.rst b/docs/index.rst index e39b969b2c9..5a6a3a77159 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -91,6 +91,14 @@ install instrumentation/** +.. toctree:: + :maxdepth: 1 + :caption: OpenTelemetry Python Performance + :name: performance-tests + :glob: + + performance/** + .. toctree:: :maxdepth: 1 :caption: Examples diff --git a/docs/performance/benchmarks.rst b/docs/performance/benchmarks.rst new file mode 100644 index 00000000000..9c406c0323f --- /dev/null +++ b/docs/performance/benchmarks.rst @@ -0,0 +1,4 @@ +Performance Tests - Benchmarks +============================== + +Click `here `_ to view the latest performance benchmarks for packages in this repo. diff --git a/exporter/opentelemetry-exporter-jaeger/CHANGELOG.md b/exporter/opentelemetry-exporter-jaeger/CHANGELOG.md deleted file mode 100644 index 32454b4bca6..00000000000 --- a/exporter/opentelemetry-exporter-jaeger/CHANGELOG.md +++ /dev/null @@ -1,63 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.15b0 - -Released 2020-11-02 -- Add support for Jaeger Span Exporter configuration by environment variables and
- change JaegerSpanExporter constructor parameters - ([#1114](https://github.com/open-telemetry/opentelemetry-python/pull/1114)) - -## Version 0.13b0 - -Released 2020-09-17 -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) -- Report instrumentation info - ([#1098](https://github.com/open-telemetry/opentelemetry-python/pull/1098)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Change package name to opentelemetry-exporter-jaeger - ([#953](https://github.com/open-telemetry/opentelemetry-python/pull/953)) - -- Thrift URL for Jaeger exporter doesn't allow HTTPS (hardcoded to HTTP) - ([#978] (https://github.com/open-telemetry/opentelemetry-python/pull/978)) - -## 0.8b0 - -Released 2020-05-27 - -- Transform resource to tags when exporting - ([#645](https://github.com/open-telemetry/opentelemetry-python/pull/645)) -- ext/boto: Could not serialize attribute aws.region to tag when exporting via jaeger - Serialize tuple type values by coercing them into a string, since Jaeger does not - support tuple types. - ([#865](https://github.com/open-telemetry/opentelemetry-python/pull/865)) - -## 0.6b0 - -Released 2020-03-30 - -- Exporting to collector now works - ([#508](https://github.com/open-telemetry/opentelemetry-python/pull/508)) - -## 0.4a0 - -Released 2020-02-21 - -- Export span status ([#367](https://github.com/open-telemetry/opentelemetry-python/pull/367)) -- Export span kind ([#387](https://github.com/open-telemetry/opentelemetry-python/pull/387)) - -## 0.3a0 - -Released 2019-12-11 - -## 0.2a0 - -Released 2019-10-29 - -- Initial release diff --git a/exporter/opentelemetry-exporter-jaeger/tests/test_jaeger_exporter.py b/exporter/opentelemetry-exporter-jaeger/tests/test_jaeger_exporter.py index c49a3216884..75ab622c954 100644 --- a/exporter/opentelemetry-exporter-jaeger/tests/test_jaeger_exporter.py +++ b/exporter/opentelemetry-exporter-jaeger/tests/test_jaeger_exporter.py @@ -41,6 +41,12 @@ def setUp(self): self._test_span = trace._Span("test_span", context=context) self._test_span.start() self._test_span.end() + # pylint: disable=protected-access + Configuration._reset() + + def tearDown(self): + # pylint: disable=protected-access + Configuration._reset() def test_constructor_default(self): """Test the default values assigned by constructor.""" @@ -142,8 +148,6 @@ def test_constructor_by_environment_variables(self): environ_patcher.stop() - Configuration._reset() - def test_nsec_to_usec_round(self): # pylint: disable=protected-access nsec_to_usec_round = jaeger_exporter._nsec_to_usec_round diff --git a/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md b/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md deleted file mode 100644 index 33ccae1d455..00000000000 --- a/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md +++ /dev/null @@ -1,39 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.16b0 - -Released 2020-11-25 - -- Update protobuf versions - ([#1356](https://github.com/open-telemetry/opentelemetry-python/pull/1356)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Drop support for Python 3.4' - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Change package name to opentelemetry-exporter-opencensus - ([#953](https://github.com/open-telemetry/opentelemetry-python/pull/953)) -- Send start_timestamp and convert labels to strings - ([#937](https://github.com/open-telemetry/opentelemetry-python/pull/937)) - -## 0.8b0 - -Released 2020-05-27 - -- Rename otcollector to opencensus - ([#695](https://github.com/open-telemetry/opentelemetry-python/pull/695)) - -## 0.5b0 - -Released 2020-03-16 - -- Initial release. diff --git a/exporter/opentelemetry-exporter-opencensus/setup.cfg b/exporter/opentelemetry-exporter-opencensus/setup.cfg index 2ff3b2bc2b4..c707b86b9fb 100644 --- a/exporter/opentelemetry-exporter-opencensus/setup.cfg +++ b/exporter/opentelemetry-exporter-opencensus/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_metrics_exporter.py b/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_metrics_exporter.py index b48a4a5a33d..3b40b8d75ab 100644 --- a/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_metrics_exporter.py @@ -91,13 +91,13 @@ def test_get_collector_metric_type(self): def test_get_collector_point(self): aggregator = aggregate.SumAggregator() int_counter = self._meter.create_counter( - "testName", "testDescription", "unit", int, + "testNameIntCounter", "testDescription", "unit", int, ) float_counter = self._meter.create_counter( - "testName", "testDescription", "unit", float, + "testNameFloatCounter", "testDescription", "unit", float, ) valuerecorder = self._meter.create_valuerecorder( - "testName", "testDescription", "unit", float, + "testNameValueRecorder", "testDescription", "unit", float, ) result = metrics_exporter.get_collector_point( ExportRecord( @@ -168,7 +168,7 @@ def test_export(self): def test_translate_to_collector(self): test_metric = self._meter.create_counter( - "testname", "testdesc", "unit", int, self._labels.keys() + "testcollector", "testdesc", "unit", int, self._labels.keys() ) aggregator = aggregate.SumAggregator() aggregator.update(123) @@ -185,7 +185,9 @@ def test_translate_to_collector(self): ) self.assertEqual(len(output_metrics), 1) self.assertIsInstance(output_metrics[0], metrics_pb2.Metric) - self.assertEqual(output_metrics[0].metric_descriptor.name, "testname") + self.assertEqual( + output_metrics[0].metric_descriptor.name, "testcollector" + ) self.assertEqual( output_metrics[0].metric_descriptor.description, "testdesc" ) diff --git a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md deleted file mode 100644 index e3968d6825e..00000000000 --- a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md +++ /dev/null @@ -1,70 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.16b1 - -Released 2020-11-26 - -- Add meter reference to observers - ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) - -## Version 0.16b0 - -Released 2020-11-25 - -- Add instrumentation library name and version to OTLP exported metrics - ([#1418](https://github.com/open-telemetry/opentelemetry-python/pull/1418)) -- Change temporality for Counter and UpDownCounter - ([#1384](https://github.com/open-telemetry/opentelemetry-python/pull/1384)) -- Add Gzip compression for exporter - ([#1141](https://github.com/open-telemetry/opentelemetry-python/pull/1141)) -- OTLP exporter: Handle error case when no credentials supplied - ([#1366](https://github.com/open-telemetry/opentelemetry-python/pull/1366)) -## Version 0.15b0 - -Released 2020-11-02 - -- Add Env variables in OTLP exporter - ([#1101](https://github.com/open-telemetry/opentelemetry-python/pull/1101)) -- Do not use bound instruments in OTLP exporter - ([#1237](https://github.com/open-telemetry/opentelemetry-python/pull/1237)) - -## Version 0.14b0 - -Released 2020-10-13 - -- Add timestamps to OTLP exporter - ([#1199](https://github.com/open-telemetry/opentelemetry-python/pull/1199)) -- Update OpenTelemetry protos to v0.5.0 - ([#1143](https://github.com/open-telemetry/opentelemetry-python/pull/1143)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Add instrumentation info to exported spans - ([#1095](https://github.com/open-telemetry/opentelemetry-python/pull/1095)) -- Add metric OTLP exporter - ([#835](https://github.com/open-telemetry/opentelemetry-python/pull/835)) -- Add type hints to OTLP exporter - ([#1121](https://github.com/open-telemetry/opentelemetry-python/pull/1121)) - -## Version 0.12b0 - -- Change package name to opentelemetry-exporter-otlp - ([#953](https://github.com/open-telemetry/opentelemetry-python/pull/953)) -- Update default port to 55680 - ([#977](https://github.com/open-telemetry/opentelemetry-python/pull/977)) - -## Version 0.11b0 - -Released 2020-07-28 - -- Update span exporter to use OpenTelemetry Proto v0.4.0 ([#872](https://github.com/open-telemetry/opentelemetry-python/pull/889)) - -## 0.9b0 - -Released 2020-06-10 - -- Initial release diff --git a/exporter/opentelemetry-exporter-otlp/setup.cfg b/exporter/opentelemetry-exporter-otlp/setup.cfg index 20d724e8676..cb11e0e041f 100644 --- a/exporter/opentelemetry-exporter-otlp/setup.cfg +++ b/exporter/opentelemetry-exporter-otlp/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py index d005232d3eb..7265003fee8 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py @@ -50,7 +50,7 @@ "service.name": "service" }) - trace.set_tracer_provider(TracerProvider(resource=resource))) + trace.set_tracer_provider(TracerProvider(resource=resource)) tracer = trace.get_tracer(__name__) otlp_exporter = OTLPSpanExporter(endpoint="localhost:55680", insecure=True) diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py index 93a87b8cf76..915e5f4d3ee 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py @@ -123,8 +123,8 @@ def _get_resource_data( def _load_credential_from_file(filepath) -> ChannelCredentials: try: - with open(filepath, "rb") as f: - credential = f.read() + with open(filepath, "rb") as creds_file: + credential = creds_file.read() return ssl_channel_credentials(credential) except FileNotFoundError: logger.exception("Failed to read credential file") diff --git a/exporter/opentelemetry-exporter-prometheus/CHANGELOG.md b/exporter/opentelemetry-exporter-prometheus/CHANGELOG.md deleted file mode 100644 index 618e2c41460..00000000000 --- a/exporter/opentelemetry-exporter-prometheus/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.13b0 - -Released 2020-09-17 - -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Change package name to opentelemetry-exporter-prometheus - ([#953](https://github.com/open-telemetry/opentelemetry-python/pull/953)) - -## 0.4a0 - -Released 2020-02-21 - -- Initial release diff --git a/exporter/opentelemetry-exporter-prometheus/setup.cfg b/exporter/opentelemetry-exporter-prometheus/setup.cfg index 6ab2101f8cb..40991ace388 100644 --- a/exporter/opentelemetry-exporter-prometheus/setup.cfg +++ b/exporter/opentelemetry-exporter-prometheus/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md b/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md deleted file mode 100644 index bb10a1a629b..00000000000 --- a/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md +++ /dev/null @@ -1,62 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.16b0 - -Released 2020-11-25 - -- Support for v2 api protobuf format ([#1318](https://github.com/open-telemetry/opentelemetry-python/pull/1318)) - -## Version 0.14b0 - -Released 2020-10-13 - -- Zipkin exporter now accepts a ``max_tag_value_length`` attribute to customize the - maximum allowed size a tag value can have. ([#1151](https://github.com/open-telemetry/opentelemetry-python/pull/1151)) -- Fixed OTLP events to Zipkin annotations translation. ([#1161](https://github.com/open-telemetry/opentelemetry-python/pull/1161)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Add support for OTEL_EXPORTER_ZIPKIN_ENDPOINT env var. As part of this change, the - configuration of the ZipkinSpanExporter exposes a `url` argument to replace `host_name`, - `port`, `protocol`, `endpoint`. This brings this implementation inline with other - implementations. - ([#1064](https://github.com/open-telemetry/opentelemetry-python/pull/1064)) -- Zipkin exporter report instrumentation info. - ([#1097](https://github.com/open-telemetry/opentelemetry-python/pull/1097)) -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) -- Add status mapping to tags - ([#1111](https://github.com/open-telemetry/opentelemetry-python/issues/1111)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Change package name to opentelemetry-exporter-zipkin - ([#953](https://github.com/open-telemetry/opentelemetry-python/pull/953)) -- Add proper length zero padding to hex strings of traceId, spanId, parentId sent on the wire, for compatibility with jaeger-collector - ([#908](https://github.com/open-telemetry/opentelemetry-python/pull/908)) - -## 0.8b0 - -Released 2020-05-27 - -- Transform resource to tags when exporting - ([#707](https://github.com/open-telemetry/opentelemetry-python/pull/707)) - -## 0.7b1 - -Released 2020-05-12 - -- bugfix: 'debug' field is now correct - ([#549](https://github.com/open-telemetry/opentelemetry-python/pull/549)) - -## 0.4a0 - -Released 2020-02-21 - -- Initial release diff --git a/exporter/opentelemetry-exporter-zipkin/setup.cfg b/exporter/opentelemetry-exporter-zipkin/setup.cfg index 6fda3370146..f8002c583d5 100644 --- a/exporter/opentelemetry-exporter-zipkin/setup.cfg +++ b/exporter/opentelemetry-exporter-zipkin/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/CHANGELOG.md b/instrumentation/opentelemetry-instrumentation-opentracing-shim/CHANGELOG.md deleted file mode 100644 index be243d95847..00000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.13b0 - -Released 2020-09-17 - -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Change reference names to opentelemetry-instrumentation-opentracing-shim - ([#969](https://github.com/open-telemetry/opentelemetry-python/pull/969)) - -## 0.3a0 - -Released 2019-12-11 - -- Implement extract and inject support for HTTP_HEADERS and TEXT_MAP formats - ([#256](https://github.com/open-telemetry/opentelemetry-python/pull/256)) - -## 0.2a0 - -Released 2019-10-29 - -- Initial release diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg b/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg index 87def810899..abe7bc58158 100644 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/opentelemetry-api/CHANGELOG.md b/opentelemetry-api/CHANGELOG.md deleted file mode 100644 index 84604f4bb27..00000000000 --- a/opentelemetry-api/CHANGELOG.md +++ /dev/null @@ -1,212 +0,0 @@ -# Changelog - -## Unreleased - -- Add `fields` to propagators - ([#1374](https://github.com/open-telemetry/opentelemetry-python/pull/1374)) - -## Version 0.16b0 - -Released 2020-11-25 - -- Add optional parameter to `record_exception` method - ([#1314](https://github.com/open-telemetry/opentelemetry-python/pull/1314)) -- Add pickle support to SpanContext class - ([#1380](https://github.com/open-telemetry/opentelemetry-python/pull/1380)) - -## Version 0.15b0 - -Released 2020-11-02 - -- Updating status codes to adhere to specs - ([#1282](https://github.com/open-telemetry/opentelemetry-python/pull/1282)) - -## Version 0.14b0 - -Released 2020-10-13 -- Add optional parameter to `record_exception` method - ([#1242](https://github.com/open-telemetry/opentelemetry-python/pull/1242)) -- Add support for `OTEL_PROPAGATORS` - ([#1123](https://github.com/open-telemetry/opentelemetry-python/pull/1123)) -- Store `int`s as `int`s in the global Configuration object - ([#1118](https://github.com/open-telemetry/opentelemetry-python/pull/1118)) -- Allow for Custom Trace and Span IDs Generation - `IdsGenerator` for TracerProvider - ([#1153](https://github.com/open-telemetry/opentelemetry-python/pull/1153)) -- Update baggage propagation header - ([#1194](https://github.com/open-telemetry/opentelemetry-python/pull/1194)) -- Make instances of SpanContext immutable - ([#1134](https://github.com/open-telemetry/opentelemetry-python/pull/1134)) -- Parent is now always passed in via Context, intead of Span or SpanContext - ([#1146](https://github.com/open-telemetry/opentelemetry-python/pull/1146)) -- Add keys method to TextMap propagator Getter - ([#1196](https://github.com/open-telemetry/opentelemetry-python/issues/1196)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Refactor `SpanContext.is_valid` from a method to a data attribute - ([#1005](https://github.com/open-telemetry/opentelemetry-python/pull/1005)) -- Moved samplers from API to SDK - ([#1023](https://github.com/open-telemetry/opentelemetry-python/pull/1023)) -- Change return value type of `correlationcontext.get_correlations` to immutable `MappingProxyType` - ([#1024](https://github.com/open-telemetry/opentelemetry-python/pull/1024)) -- Change is_recording_events to is_recording - ([#1034](https://github.com/open-telemetry/opentelemetry-python/pull/1034)) -- Remove lazy Event and Link API from Span interface - ([#1045](https://github.com/open-telemetry/opentelemetry-python/pull/1045)) -- Rename CorrelationContext to Baggage - ([#1060](https://github.com/open-telemetry/opentelemetry-python/pull/1060)) -- Rename HTTPTextFormat to TextMapPropagator. This change also updates `get_global_httptextformat` and - `set_global_httptextformat` to `get_global_textmap` and `set_global_textmap` - ([#1085](https://github.com/open-telemetry/opentelemetry-python/pull/1085)) -- Fix api/sdk setup.cfg to include missing python files - ([#1091](https://github.com/open-telemetry/opentelemetry-python/pull/1091)) -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Update environment variable names, prefix changed from `OPENTELEMETRY` to `OTEL` - ([#904](https://github.com/open-telemetry/opentelemetry-python/pull/904)) -- Stop TracerProvider and MeterProvider from being overridden - ([#959](https://github.com/open-telemetry/opentelemetry-python/pull/959)) - -## Version 0.11b0 - -- Return INVALID_SPAN if no TracerProvider set for get_current_span - ([#751](https://github.com/open-telemetry/opentelemetry-python/pull/751)) -- Rename record_error to record_exception - ([#927](https://github.com/open-telemetry/opentelemetry-python/pull/927)) - -## 0.9b0 - -Released 2020-06-10 - -- Move stateful from Meter to MeterProvider - ([#751](https://github.com/open-telemetry/opentelemetry-python/pull/751)) -- Rename Measure to ValueRecorder in metrics - ([#761](https://github.com/open-telemetry/opentelemetry-python/pull/761)) -- Adding trace.get_current_span, Removing Tracer.get_current_span - ([#552](https://github.com/open-telemetry/opentelemetry-python/pull/552)) -- Rename Observer to ValueObserver - ([#764](https://github.com/open-telemetry/opentelemetry-python/pull/764)) -- Add SumObserver and UpDownSumObserver in metrics - ([#789](https://github.com/open-telemetry/opentelemetry-python/pull/789)) -- Log a warning when replacing the global Tracer/Meter provider - ([#856](https://github.com/open-telemetry/opentelemetry-python/pull/856)) - -## 0.8b0 - -Released 2020-05-27 - -- Handle boolean, integer and float values in Configuration - ([#662](https://github.com/open-telemetry/opentelemetry-python/pull/662)) -- bugfix: ensure status is always string - ([#640](https://github.com/open-telemetry/opentelemetry-python/pull/640)) - -## 0.7b1 - -Released 2020-05-12 - -- Add reset for the global configuration object, for testing purposes - ([#636](https://github.com/open-telemetry/opentelemetry-python/pull/636)) -- tracer.get_tracer now optionally accepts a TracerProvider - ([#602](https://github.com/open-telemetry/opentelemetry-python/pull/602)) -- Configuration object can now be used by any component of opentelemetry, - including 3rd party instrumentations - ([#563](https://github.com/open-telemetry/opentelemetry-python/pull/563)) -- bugfix: configuration object now matches fields in a case-sensitive manner - ([#583](https://github.com/open-telemetry/opentelemetry-python/pull/583)) -- bugfix: configuration object now accepts all valid python variable names - ([#583](https://github.com/open-telemetry/opentelemetry-python/pull/583)) -- bugfix: configuration undefined attributes now return None instead of raising - an AttributeError. - ([#583](https://github.com/open-telemetry/opentelemetry-python/pull/583)) - -## 0.6b0 - -Released 2020-03-30 - -- Add support for lazy events and links - ([#474](https://github.com/open-telemetry/opentelemetry-python/pull/474)) -- Metrics API no longer uses LabelSet - ([#527](https://github.com/open-telemetry/opentelemetry-python/pull/527)) -- Adding is_remote flag to SpanContext, indicating when a span is remote - ([#516](https://github.com/open-telemetry/opentelemetry-python/pull/516)) -- Allow digit as first char in vendor specific trace state key - ([#511](https://github.com/open-telemetry/opentelemetry-python/pull/511)) - -## 0.5b0 - -Released 2020-03-16 - -- Adding Correlation Context API and propagator - ([#471](https://github.com/open-telemetry/opentelemetry-python/pull/471)) -- Adding a global configuration module to simplify setting and getting globals - ([#466](https://github.com/open-telemetry/opentelemetry-python/pull/466)) -- Rename metric handle to bound metric instrument - ([#470](https://github.com/open-telemetry/opentelemetry-python/pull/470)) -- Moving resources to sdk - ([#464](https://github.com/open-telemetry/opentelemetry-python/pull/464)) -- Implementing propagators to API to use context - ([#446](https://github.com/open-telemetry/opentelemetry-python/pull/446)) -- Adding named meters, removing batchers - ([#431](https://github.com/open-telemetry/opentelemetry-python/pull/431)) -- Renaming TraceOptions to TraceFlags - ([#450](https://github.com/open-telemetry/opentelemetry-python/pull/450)) -- Renaming TracerSource to TracerProvider - ([#441](https://github.com/open-telemetry/opentelemetry-python/pull/441)) -- Adding attach/detach methods as per spec - ([#429](https://github.com/open-telemetry/opentelemetry-python/pull/450) - -## 0.4a0 - -Released 2020-02-21 - -- Separate Default classes from interface descriptions - ([#311](https://github.com/open-telemetry/opentelemetry-python/pull/311)) -- Added named Tracers - ([#301](https://github.com/open-telemetry/opentelemetry-python/pull/301)) -- Add int and valid sequenced to AttributeValue type - ([#368](https://github.com/open-telemetry/opentelemetry-python/pull/368)) -- Add ABC for Metric - ([#391](https://github.com/open-telemetry/opentelemetry-python/pull/391)) -- Metric classes required for export pipeline - ([#341](https://github.com/open-telemetry/opentelemetry-python/pull/341)) -- Adding Context API Implementation - ([#395](https://github.com/open-telemetry/opentelemetry-python/pull/395)) -- Remove monotonic and absolute metric instruments - ([#410](https://github.com/open-telemetry/opentelemetry-python/pull/410)) -- Adding trace.get_tracer function - ([#430](https://github.com/open-telemetry/opentelemetry-python/pull/430)) - -## 0.3a0 - -Released 2019-12-11 - -- Multiple tracing API changes -- Multiple metrics API changes -- Remove option to create unstarted spans from API - ([#290](https://github.com/open-telemetry/opentelemetry-python/pull/290)) - -## 0.2a0 - -Released 2019-10-29 - -- W3C TraceContext fixes and compliance tests - ([#228](https://github.com/open-telemetry/opentelemetry-python/pull/228)) -- Multiple metrics API changes -- Multiple tracing API changes -- Multiple context API changes -- Sampler API - ([#225](https://github.com/open-telemetry/opentelemetry-python/pull/225)) -- Multiple bugfixes and improvements - -## 0.1a0 - -Released 2019-09-30 - -- Initial release diff --git a/opentelemetry-api/setup.cfg b/opentelemetry-api/setup.cfg index 78c3123222a..8bb3e6cc6f7 100644 --- a/opentelemetry-api/setup.cfg +++ b/opentelemetry-api/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py index ad47179c3de..75ba25bbe8d 100644 --- a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py +++ b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py @@ -101,7 +101,7 @@ def _format_baggage(baggage_entries: typing.Mapping[str, object]) -> str: def _extract_first_element( - items: typing.Iterable[textmap.TextMapPropagatorT], + items: typing.Optional[typing.Iterable[textmap.TextMapPropagatorT]], ) -> typing.Optional[textmap.TextMapPropagatorT]: if items is None: return None diff --git a/opentelemetry-api/src/opentelemetry/trace/propagation/textmap.py b/opentelemetry-api/src/opentelemetry/trace/propagation/textmap.py index fb92d371680..0612a740f64 100644 --- a/opentelemetry-api/src/opentelemetry/trace/propagation/textmap.py +++ b/opentelemetry-api/src/opentelemetry/trace/propagation/textmap.py @@ -29,7 +29,9 @@ class Getter(typing.Generic[TextMapPropagatorT]): """ - def get(self, carrier: TextMapPropagatorT, key: str) -> typing.List[str]: + def get( + self, carrier: TextMapPropagatorT, key: str + ) -> typing.Optional[typing.List[str]]: """Function that can retrieve zero or more values from the carrier. In the case that the value does not exist, returns an empty list. @@ -38,8 +40,8 @@ def get(self, carrier: TextMapPropagatorT, key: str) -> typing.List[str]: carrier: An object which contains values that are used to construct a Context. key: key of a field in carrier. - Returns: first value of the propagation key or an empty list if the - key doesn't exist. + Returns: first value of the propagation key or None if the key doesn't + exist. """ raise NotImplementedError() @@ -58,8 +60,10 @@ def keys(self, carrier: TextMapPropagatorT) -> typing.List[str]: class DictGetter(Getter[typing.Dict[str, CarrierValT]]): def get( self, carrier: typing.Dict[str, CarrierValT], key: str - ) -> typing.List[str]: - val = carrier.get(key, []) + ) -> typing.Optional[typing.List[str]]: + val = carrier.get(key, None) + if val is None: + return None if isinstance(val, typing.Iterable) and not isinstance(val, str): return list(val) return [val] diff --git a/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py b/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py index adcdb5e1255..146ba47772a 100644 --- a/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py +++ b/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py @@ -91,7 +91,10 @@ def extract( return trace.set_span_in_context(trace.INVALID_SPAN, context) tracestate_headers = getter.get(carrier, self._TRACESTATE_HEADER_NAME) - tracestate = _parse_tracestate(tracestate_headers) + if tracestate_headers is None: + tracestate = None + else: + tracestate = _parse_tracestate(tracestate_headers) span_context = trace.SpanContext( trace_id=int(trace_id, 16), diff --git a/opentelemetry-api/src/opentelemetry/trace/span.py b/opentelemetry-api/src/opentelemetry/trace/span.py index d41a0c3fbd4..6506f6f949d 100644 --- a/opentelemetry-api/src/opentelemetry/trace/span.py +++ b/opentelemetry-api/src/opentelemetry/trace/span.py @@ -175,8 +175,8 @@ def __new__( trace_id: int, span_id: int, is_remote: bool, - trace_flags: "TraceFlags" = DEFAULT_TRACE_OPTIONS, - trace_state: "TraceState" = DEFAULT_TRACE_STATE, + trace_flags: typing.Optional["TraceFlags"] = DEFAULT_TRACE_OPTIONS, + trace_state: typing.Optional["TraceState"] = DEFAULT_TRACE_STATE, ) -> "SpanContext": if trace_flags is None: trace_flags = DEFAULT_TRACE_OPTIONS diff --git a/opentelemetry-api/src/opentelemetry/util/__init__.py b/opentelemetry-api/src/opentelemetry/util/__init__.py index 58c297269e0..c1c5a77f098 100644 --- a/opentelemetry-api/src/opentelemetry/util/__init__.py +++ b/opentelemetry-api/src/opentelemetry/util/__init__.py @@ -21,8 +21,8 @@ from opentelemetry.configuration import Configuration if TYPE_CHECKING: - from opentelemetry.trace import TracerProvider from opentelemetry.metrics import MeterProvider + from opentelemetry.trace import TracerProvider Provider = Union["TracerProvider", "MeterProvider"] diff --git a/opentelemetry-api/tests/context/test_contextvars_context.py b/opentelemetry-api/tests/context/test_contextvars_context.py index 7a384f16782..0c2ec1e6c2c 100644 --- a/opentelemetry-api/tests/context/test_contextvars_context.py +++ b/opentelemetry-api/tests/context/test_contextvars_context.py @@ -21,6 +21,7 @@ try: import contextvars # pylint: disable=unused-import + from opentelemetry.context.contextvars_context import ( ContextVarsRuntimeContext, ) diff --git a/opentelemetry-api/tests/trace/propagation/test_textmap.py b/opentelemetry-api/tests/trace/propagation/test_textmap.py new file mode 100644 index 00000000000..830f7ac2c1c --- /dev/null +++ b/opentelemetry-api/tests/trace/propagation/test_textmap.py @@ -0,0 +1,42 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from opentelemetry.trace.propagation.textmap import DictGetter + + +class TestDictGetter(unittest.TestCase): + def test_get_none(self): + getter = DictGetter() + carrier = {} + val = getter.get(carrier, "test") + self.assertIsNone(val) + + def test_get_str(self): + getter = DictGetter() + carrier = {"test": "val"} + val = getter.get(carrier, "test") + self.assertEqual(val, ["val"]) + + def test_get_iter(self): + getter = DictGetter() + carrier = {"test": ["val"]} + val = getter.get(carrier, "test") + self.assertEqual(val, ["val"]) + + def test_keys(self): + getter = DictGetter() + keys = getter.keys({"test": "val"}) + self.assertEqual(keys, ["test"]) diff --git a/opentelemetry-instrumentation/CHANGELOG.md b/opentelemetry-instrumentation/CHANGELOG.md deleted file mode 100644 index 2a93c09ba5c..00000000000 --- a/opentelemetry-instrumentation/CHANGELOG.md +++ /dev/null @@ -1,61 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.16b0 - -Released 2020-11-25 - -- Add IDs Generator as Configurable Property of Auto Instrumentation - ([#1404](https://github.com/open-telemetry/opentelemetry-python/pull/1404)) -- Added support for `OTEL_EXPORTER` to the `opentelemetry-instrument` command ([#1036](https://github.com/open-telemetry/opentelemetry-python/pull/1036)) -- Add missing references to instrumented packages - ([#1416](https://github.com/open-telemetry/opentelemetry-python/pull/1416)) -- Instrumentation Package depends on the OTel SDK - ([#1405](https://github.com/open-telemetry/opentelemetry-python/pull/1405)) - -## Version 0.14b0 - -Released 2020-10-13 - -- Fixed bootstrap command to correctly install opentelemetry-instrumentation-falcon instead of opentelemetry-instrumentation-flask. ([#1138](https://github.com/open-telemetry/opentelemetry-python/pull/1138)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) -- Add support for http metrics - ([#1116](https://github.com/open-telemetry/opentelemetry-python/pull/1116)) - -## 0.9b0 - -Released 2020-06-10 - -- Rename opentelemetry-auto-instrumentation to opentelemetry-instrumentation, - and console script `opentelemetry-auto-instrumentation` to `opentelemetry-instrument` - -## 0.8b0 - -Released 2020-05-27 - -- Add a new bootstrap command that enables automatic instrument installations. - ([#650](https://github.com/open-telemetry/opentelemetry-python/pull/650)) - -## 0.7b1 - -Released 2020-05-12 - -- Add support for programmatic instrumentation - ([#579](https://github.com/open-telemetry/opentelemetry-python/pull/569)) -- bugfix: enable auto-instrumentation command to work for custom entry points - (e.g. flask_run) - ([#567](https://github.com/open-telemetry/opentelemetry-python/pull/567)) - - -## 0.6b0 - -Released 2020-03-30 - -- Initial release. diff --git a/opentelemetry-instrumentation/setup.cfg b/opentelemetry-instrumentation/setup.cfg index 558e6a54e2f..e38e80d1bef 100644 --- a/opentelemetry-instrumentation/setup.cfg +++ b/opentelemetry-instrumentation/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/opentelemetry-instrumentation/tests/test_metric.py b/opentelemetry-instrumentation/tests/test_metric.py index 8e676c737e2..c0bdcca15ad 100644 --- a/opentelemetry-instrumentation/tests/test_metric.py +++ b/opentelemetry-instrumentation/tests/test_metric.py @@ -72,7 +72,7 @@ def test_ctor(self): "measures the duration of the outbound HTTP request", ) - def test_ctor_types(self): + def test_ctor_type_client(self): meter = metrics_api.get_meter(__name__) recorder = HTTPMetricRecorder(meter, HTTPMetricType.CLIENT) self.assertEqual(recorder._http_type, HTTPMetricType.CLIENT) @@ -81,6 +81,8 @@ def test_ctor_types(self): ) self.assertIsNone(recorder._server_duration) + def test_ctor_type_server(self): + meter = metrics_api.get_meter(__name__) recorder = HTTPMetricRecorder(meter, HTTPMetricType.SERVER) self.assertEqual(recorder._http_type, HTTPMetricType.SERVER) self.assertTrue( @@ -88,6 +90,8 @@ def test_ctor_types(self): ) self.assertIsNone(recorder._client_duration) + def test_ctor_type_both(self): + meter = metrics_api.get_meter(__name__) recorder = HTTPMetricRecorder(meter, HTTPMetricType.BOTH) self.assertEqual(recorder._http_type, HTTPMetricType.BOTH) self.assertTrue( diff --git a/opentelemetry-proto/CHANGELOG.md b/opentelemetry-proto/CHANGELOG.md deleted file mode 100644 index 9906bdee12c..00000000000 --- a/opentelemetry-proto/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.16b0 - -Released 2020-11-25 - -- Update protobuf versions - ([#1356](https://github.com/open-telemetry/opentelemetry-python/pull/1356)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) - -## Version 0.10b0 - -Released 2020-06-23 - -- Regenerate proto code and add pyi stubs - ([#823](https://github.com/open-telemetry/opentelemetry-python/pull/823)) - -## 0.9b0 - -Released 2020-06-10 - -- Initial release diff --git a/opentelemetry-proto/setup.cfg b/opentelemetry-proto/setup.cfg index 9f8087df66d..6b924a7a390 100644 --- a/opentelemetry-proto/setup.cfg +++ b/opentelemetry-proto/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md deleted file mode 100644 index 9f94dff63c0..00000000000 --- a/opentelemetry-sdk/CHANGELOG.md +++ /dev/null @@ -1,286 +0,0 @@ -# Changelog - -## Unreleased - -- Add meter reference to observers - ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) -- Add local/remote samplers to parent based sampler - ([#1440](https://github.com/open-telemetry/opentelemetry-python/pull/1440)) -- Add `fields` to propagators - ([#1374](https://github.com/open-telemetry/opentelemetry-python/pull/1374)) - -## Version 0.16b0 - -Released 2020-11-25 - -- Allow samplers to modify tracestate - ([#1319](https://github.com/open-telemetry/opentelemetry-python/pull/1319)) -- Add optional parameter to `record_exception` method - ([#1314](https://github.com/open-telemetry/opentelemetry-python/pull/1314)) -- Update exception handling optional parameters, add escaped attribute to record_exception - ([#1365](https://github.com/open-telemetry/opentelemetry-python/pull/1365)) -- Rename `MetricRecord` class to `ExportRecord` - ([#1367](https://github.com/open-telemetry/opentelemetry-python/pull/1367)) -- Rename Record in Metrics SDK to Accumulation - ([#1373](https://github.com/open-telemetry/opentelemetry-python/pull/1373)) -- Rename Meter class to Accumulator in Metrics SDK - ([#1372](https://github.com/open-telemetry/opentelemetry-python/pull/1372)) -- Fix `ParentBased` sampler for implicit parent spans. Fix also `trace_state` - erasure for dropped spans or spans sampled by the `TraceIdRatioBased` sampler. - ([#1394](https://github.com/open-telemetry/opentelemetry-python/pull/1394)) - -## Version 0.15b0 - -Released 2020-11-02 - -- Make `SpanProcessor.on_start` accept parent Context - ([#1251](https://github.com/open-telemetry/opentelemetry-python/pull/1251)) -- Fix b3 propagator entrypoint - ([#1265](https://github.com/open-telemetry/opentelemetry-python/pull/1265)) -- Allow None in sequence attributes values - ([#998](https://github.com/open-telemetry/opentelemetry-python/pull/998)) -- Samplers to accept parent Context - ([#1267](https://github.com/open-telemetry/opentelemetry-python/pull/1267)) -- Updating status codes to adhere to spec - ([#1282](https://github.com/open-telemetry/opentelemetry-python/pull/1282)) -- Span.is_recording() returns false after span has ended - ([#1289](https://github.com/open-telemetry/opentelemetry-python/pull/1289)) -- Set initial checkpoint timestamp in aggregators - ([#1237](https://github.com/open-telemetry/opentelemetry-python/pull/1237)) -- Allow samplers to modify tracestate - ([#1319](https://github.com/open-telemetry/opentelemetry-python/pull/1319)) -- Remove TracerProvider coupling from Tracer init - ([#1295](https://github.com/open-telemetry/opentelemetry-python/pull/1295)) - -## Version 0.14b0 - -Released 2020-10-13 -- Add optional parameter to `record_exception` method - ([#1242](https://github.com/open-telemetry/opentelemetry-python/pull/1242)) -- Add timestamps to aggregators - ([#1199](https://github.com/open-telemetry/opentelemetry-python/pull/1199)) -- Add Global Error Handler - ([#1080](https://github.com/open-telemetry/opentelemetry-python/pull/1080)) -- Update sampling result names - ([#1128](https://github.com/open-telemetry/opentelemetry-python/pull/1128)) -- Add support for `OTEL_BSP_MAX_QUEUE_SIZE`, `OTEL_BSP_SCHEDULE_DELAY_MILLIS`, `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` and `OTEL_BSP_EXPORT_TIMEOUT_MILLIS` environment variables - ([#1105](https://github.com/open-telemetry/opentelemetry-python/pull/1120)) -- Allow for Custom Trace and Span IDs Generation - `IdsGenerator` for TracerProvider - ([#1153](https://github.com/open-telemetry/opentelemetry-python/pull/1153)) -- Event attributes are now immutable - ([#1195](https://github.com/open-telemetry/opentelemetry-python/pull/1195)) -- Renaming metrics Batcher to Processor - ([#1203](https://github.com/open-telemetry/opentelemetry-python/pull/1203)) -- Protect access to Span implementation - ([#1188](https://github.com/open-telemetry/opentelemetry-python/pull/1188)) -- `start_as_current_span` and `use_span` can now optionally auto-record any exceptions raised inside the context manager. - ([#1162](https://github.com/open-telemetry/opentelemetry-python/pull/1162)) -- Adding Resource to MeterRecord - ([#1209](https://github.com/open-telemetry/opentelemetry-python/pull/1209)) -- Parent is now always passed in via Context, intead of Span or SpanContext - ([#1146](https://github.com/open-telemetry/opentelemetry-python/pull/1146)) -- Add keys method to TextMap propagator Getter - ([#1196](https://github.com/open-telemetry/opentelemetry-python/issues/1196)) - -## Version 0.13b0 - -Released 2020-09-17 - -- Moved samplers from API to SDK - ([#1023](https://github.com/open-telemetry/opentelemetry-python/pull/1023)) -- Sampling spec changes - ([#1034](https://github.com/open-telemetry/opentelemetry-python/pull/1034)) -- Remove lazy Event and Link API from Span interface - ([#1045](https://github.com/open-telemetry/opentelemetry-python/pull/1045)) -- Improve BatchExportSpanProcessor - ([#1062](https://github.com/open-telemetry/opentelemetry-python/pull/1062)) -- Populate resource attributes as per semantic conventions - ([#1053](https://github.com/open-telemetry/opentelemetry-python/pull/1053)) -- Rename Resource labels to attributes - ([#1082](https://github.com/open-telemetry/opentelemetry-python/pull/1082)) -- Fix api/sdk setup.cfg to include missing python files - ([#1091](https://github.com/open-telemetry/opentelemetry-python/pull/1091)) -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) -- Rename members of `trace.sampling.Decision` enum - ([#1115](https://github.com/open-telemetry/opentelemetry-python/pull/1115)) -- Merge `OTELResourceDetector` result when creating resources - ([#1096](https://github.com/open-telemetry/opentelemetry-python/pull/1096)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Changed default Sampler to `ParentOrElse(AlwaysOn)` - ([#960](https://github.com/open-telemetry/opentelemetry-python/pull/960)) -- Update environment variable names, prefix changed from `OPENTELEMETRY` to `OTEL` - ([#904](https://github.com/open-telemetry/opentelemetry-python/pull/904)) -- Implement Views in metrics SDK - ([#596](https://github.com/open-telemetry/opentelemetry-python/pull/596)) -- Update environment variable OTEL_RESOURCE to OTEL_RESOURCE_ATTRIBUTES as per - the specification - -## Version 0.11b0 - -- Add support for resources and resource detector - ([#853](https://github.com/open-telemetry/opentelemetry-python/pull/853)) -- Rename record_error to record_exception - ([#927](https://github.com/open-telemetry/opentelemetry-python/pull/927)) - -## Version 0.10b0 - -Released 2020-06-23 - -- Rename CounterAggregator -> SumAggregator - ([#816](https://github.com/open-telemetry/opentelemetry-python/pull/816)) - -## 0.9b0 - -Released 2020-06-10 - -- Move stateful & resource from Meter to MeterProvider - ([#751](https://github.com/open-telemetry/opentelemetry-python/pull/751)) -- Rename Measure to ValueRecorder in metrics - ([#761](https://github.com/open-telemetry/opentelemetry-python/pull/761)) -- Adding trace.get_current_span, Removing Tracer.get_current_span - ([#552](https://github.com/open-telemetry/opentelemetry-python/pull/552)) -- bugfix: byte type attributes are decoded before adding to attributes dict - ([#775](https://github.com/open-telemetry/opentelemetry-python/pull/775)) -- Rename Observer to ValueObserver - ([#764](https://github.com/open-telemetry/opentelemetry-python/pull/764)) -- Add SumObserver, UpDownSumObserver and LastValueAggregator in metrics - ([#789](https://github.com/open-telemetry/opentelemetry-python/pull/789)) -- Add start_pipeline to MeterProvider - ([#791](https://github.com/open-telemetry/opentelemetry-python/pull/791)) - -## 0.8b0 - -Released 2020-05-27 - -- Validate span attribute types in SDK - ([#678](https://github.com/open-telemetry/opentelemetry-python/pull/678)) -- Specify to_json indent from arguments - ([#718](https://github.com/open-telemetry/opentelemetry-python/pull/718)) -- Span.resource will now default to an empty resource - ([#724](https://github.com/open-telemetry/opentelemetry-python/pull/724)) -- bugfix: Fix error message - ([#729](https://github.com/open-telemetry/opentelemetry-python/pull/729)) -- deep copy empty attributes - ([#714](https://github.com/open-telemetry/opentelemetry-python/pull/714)) - -## 0.7b1 - -Released 2020-05-12 - -- Exporter API: span parents are now always spancontext - ([#548](https://github.com/open-telemetry/opentelemetry-python/pull/548)) -- tracer.get_tracer now optionally accepts a TracerProvider - ([#602](https://github.com/open-telemetry/opentelemetry-python/pull/602)) -- Console span exporter now prints prettier, more legible messages - ([#505](https://github.com/open-telemetry/opentelemetry-python/pull/505)) -- bugfix: B3 propagation now retrieves parentSpanId correctly - ([#621](https://github.com/open-telemetry/opentelemetry-python/pull/621)) -- bugfix: a DefaultSpan now longer causes an exception when used with tracer - ([#577](https://github.com/open-telemetry/opentelemetry-python/pull/577)) -- move last_updated_timestamp into aggregators instead of bound metric - instrument - ([#522](https://github.com/open-telemetry/opentelemetry-python/pull/522)) -- bugfix: suppressing instrumentation in metrics to eliminate an infinite loop - of telemetry - ([#529](https://github.com/open-telemetry/opentelemetry-python/pull/529)) -- bugfix: freezing span attribute sequences, reducing potential user errors - ([#529](https://github.com/open-telemetry/opentelemetry-python/pull/529)) - -## 0.6b0 - -Released 2020-03-30 - -- Add support for lazy events and links - ([#474](https://github.com/open-telemetry/opentelemetry-python/pull/474)) -- Metrics API no longer uses LabelSet - ([#527](https://github.com/open-telemetry/opentelemetry-python/pull/527)) -- Adding is_remote flag to SpanContext, indicating when a span is remote - ([#516](https://github.com/open-telemetry/opentelemetry-python/pull/516)) -- Adding a solution to release metric handles and observers - ([#435](https://github.com/open-telemetry/opentelemetry-python/pull/435)) - -## 0.5b0 - -Released 2020-03-16 - -- Adding Correlation Context SDK and propagator - ([#471](https://github.com/open-telemetry/opentelemetry-python/pull/471)) -- Adding OT Collector metrics exporter - ([#454](https://github.com/open-telemetry/opentelemetry-python/pull/454)) -- Improve validation of attributes - ([#460](https://github.com/open-telemetry/opentelemetry-python/pull/460)) -- Moving resources to sdk - ([#464](https://github.com/open-telemetry/opentelemetry-python/pull/464)) -- Re-raise errors caught in opentelemetry.sdk.trace.Tracer.use_span() - ([#469](https://github.com/open-telemetry/opentelemetry-python/pull/469)) -- Implement observer instrument - ([#425](https://github.com/open-telemetry/opentelemetry-python/pull/425)) - -## 0.4a0 - -Released 2020-02-21 - -- Added named Tracers - ([#301](https://github.com/open-telemetry/opentelemetry-python/pull/301)) -- Set status for ended spans - ([#297](https://github.com/open-telemetry/opentelemetry-python/pull/297) and - [#358](https://github.com/open-telemetry/opentelemetry-python/pull/358)) -- Use module loggers - ([#351](https://github.com/open-telemetry/opentelemetry-python/pull/351)) -- Protect start_time and end_time from being set manually by the user - ([#363](https://github.com/open-telemetry/opentelemetry-python/pull/363)) -- Add runtime validation for set_attribute - ([#348](https://github.com/open-telemetry/opentelemetry-python/pull/348)) -- Add support for B3 ParentSpanID - ([#286](https://github.com/open-telemetry/opentelemetry-python/pull/286)) -- Set status in start_as_current_span - ([#377](https://github.com/open-telemetry/opentelemetry-python/pull/377)) -- Implement force_flush for span processors - ([#389](https://github.com/open-telemetry/opentelemetry-python/pull/389)) -- Metrics export pipeline, and stdout exporter - ([#341](https://github.com/open-telemetry/opentelemetry-python/pull/389)) -- Set sampled flag on sampling trace - ([#407](https://github.com/open-telemetry/opentelemetry-python/pull/407)) -- Add io and formatter options to console exporter - ([#412](https://github.com/open-telemetry/opentelemetry-python/pull/412)) -- Clean up ProbabilitySample for 64 bit trace IDs - ([#238](https://github.com/open-telemetry/opentelemetry-python/pull/238)) -- Adding Context API Implementation - ([#395](https://github.com/open-telemetry/opentelemetry-python/pull/395)) -- Remove monotonic and absolute metric instruments - ([#410](https://github.com/open-telemetry/opentelemetry-python/pull/410)) -- Implement MinMaxSumCount aggregator - ([#422](https://github.com/open-telemetry/opentelemetry-python/pull/422)) - -## 0.3a0 - -Released 2019-12-11 - -- Multiple tracing SDK changes -- Multiple metrics SDK changes -- Add metrics exporters - ([#192](https://github.com/open-telemetry/opentelemetry-python/pull/192)) -- Multiple bugfixes and improvements - -## 0.2a0 - -Released 2019-10-29 - -- W3C TraceContext fixes and compliance tests - ([#228](https://github.com/open-telemetry/opentelemetry-python/pull/228)) -- Multiple metrics SDK changes -- Multiple tracing SDK changes -- Sampler SDK - ([#225](https://github.com/open-telemetry/opentelemetry-python/pull/225)) -- Multiple bugfixes and improvements - -## 0.1a0 - -Released 2019-09-30 - -- Initial release diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index 4acb6ca1fcb..94dfbd18bc8 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -32,6 +32,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 @@ -53,6 +54,9 @@ opentelemetry_tracer_provider = sdk_tracer_provider = opentelemetry.sdk.trace:TracerProvider opentelemetry_propagator = b3 = opentelemetry.sdk.trace.propagation.b3_format:B3Format +opentelemetry_exporter = + console_span = opentelemetry.sdk.trace.export:ConsoleSpanExporter + console_metrics = opentelemetry.sdk.metrics.export:ConsoleMetricsExporter [options.extras_require] test = diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py index a09047e5231..ca0ec2f967c 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py @@ -15,7 +15,7 @@ import atexit import logging import threading -from typing import Dict, Sequence, Tuple, Type, TypeVar +from typing import Dict, Sequence, Tuple, Type, TypeVar, Union from opentelemetry import metrics as metrics_api from opentelemetry.sdk.metrics.export import ( @@ -356,12 +356,23 @@ def __init__( ): self.instrumentation_info = instrumentation_info self.processor = Processor(source.stateful, source.resource) - self.metrics = set() - self.observers = set() - self.metrics_lock = threading.Lock() - self.observers_lock = threading.Lock() + self.instruments = {} + self.instruments_lock = threading.Lock() self.view_manager = ViewManager() + def _register_instrument( + self, instrument: Union[metrics_api.Metric, metrics_api.Observer] + ): + name = instrument.name.strip().lower() + with self.instruments_lock: + if name in self.instruments: + raise ValueError( + "Multiple instruments can't be registered by the same name: ({})".format( + name + ) + ) + self.instruments[name] = instrument + def collect(self) -> None: """Collects all the metrics created with this `Meter` for export. @@ -369,46 +380,41 @@ def collect(self) -> None: each aggregator belonging to the metrics that were created with this meter instance. """ - - self._collect_metrics() - self._collect_observers() - - def _collect_metrics(self) -> None: - for metric in self.metrics: - if not metric.enabled: - continue - to_remove = [] - with metric.bound_instruments_lock: - for ( - labels, - bound_instrument, - ) in metric.bound_instruments.items(): - for view_data in bound_instrument.view_datas: + with self.instruments_lock: + for instrument in self.instruments.values(): + if not instrument.enabled: + continue + if isinstance(instrument, metrics_api.Metric): + to_remove = [] + with instrument.bound_instruments_lock: + for ( + labels, + bound_instrument, + ) in instrument.bound_instruments.items(): + for view_data in bound_instrument.view_datas: + accumulation = Accumulation( + instrument, + view_data.labels, + view_data.aggregator, + ) + self.processor.process(accumulation) + + if bound_instrument.ref_count() == 0: + to_remove.append(labels) + + # Remove handles that were released + for labels in to_remove: + del instrument.bound_instruments[labels] + elif isinstance(instrument, metrics_api.Observer): + if not instrument.run(): + continue + + for labels, aggregator in instrument.aggregators.items(): accumulation = Accumulation( - metric, view_data.labels, view_data.aggregator + instrument, labels, aggregator ) self.processor.process(accumulation) - if bound_instrument.ref_count() == 0: - to_remove.append(labels) - - # Remove handles that were released - for labels in to_remove: - del metric.bound_instruments[labels] - - def _collect_observers(self) -> None: - with self.observers_lock: - for observer in self.observers: - if not observer.enabled: - continue - - if not observer.run(): - continue - - for labels, aggregator in observer.aggregators.items(): - accumulation = Accumulation(observer, labels, aggregator) - self.processor.process(accumulation) - def record_batch( self, labels: Dict[str, str], @@ -432,8 +438,7 @@ def create_counter( counter = Counter( name, description, unit, value_type, self, enabled=enabled ) - with self.metrics_lock: - self.metrics.add(counter) + self._register_instrument(counter) return counter def create_updowncounter( @@ -448,8 +453,7 @@ def create_updowncounter( counter = UpDownCounter( name, description, unit, value_type, self, enabled=enabled ) - with self.metrics_lock: - self.metrics.add(counter) + self._register_instrument(counter) return counter def create_valuerecorder( @@ -464,8 +468,7 @@ def create_valuerecorder( recorder = ValueRecorder( name, description, unit, value_type, self, enabled=enabled ) - with self.metrics_lock: - self.metrics.add(recorder) + self._register_instrument(recorder) return recorder def register_sumobserver( @@ -488,8 +491,7 @@ def register_sumobserver( label_keys, enabled, ) - with self.observers_lock: - self.observers.add(ob) + self._register_instrument(ob) return ob def register_updownsumobserver( @@ -512,8 +514,7 @@ def register_updownsumobserver( label_keys, enabled, ) - with self.observers_lock: - self.observers.add(ob) + self._register_instrument(ob) return ob def register_valueobserver( @@ -536,13 +537,13 @@ def register_valueobserver( label_keys, enabled, ) - with self.observers_lock: - self.observers.add(ob) + self._register_instrument(ob) return ob def unregister_observer(self, observer: metrics_api.Observer) -> None: - with self.observers_lock: - self.observers.remove(observer) + name = observer.name.strip().lower() + with self.instruments_lock: + self.instruments.pop(name) def register_view(self, view): self.view_manager.register_view(view) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 65e91fe97b1..c8dec7bc62e 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -37,6 +37,7 @@ from opentelemetry import context as context_api from opentelemetry import trace as trace_api +from opentelemetry.configuration import Configuration from opentelemetry.sdk import util from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import sampling @@ -49,9 +50,11 @@ logger = logging.getLogger(__name__) -MAX_NUM_ATTRIBUTES = 1000 -MAX_NUM_EVENTS = 1000 -MAX_NUM_LINKS = 1000 +SPAN_ATTRIBUTE_COUNT_LIMIT = Configuration().get( + "SPAN_ATTRIBUTE_COUNT_LIMIT", 1000 +) +SPAN_EVENT_COUNT_LIMIT = Configuration().get("SPAN_EVENT_COUNT_LIMIT", 1000) +SPAN_LINK_COUNT_LIMIT = Configuration().get("SPAN_LINK_COUNT_LIMIT", 1000) VALID_ATTR_VALUE_TYPES = (bool, str, int, float) @@ -446,7 +449,7 @@ def __init__( self.attributes = self._new_attributes() else: self.attributes = BoundedDict.from_map( - MAX_NUM_ATTRIBUTES, attributes + SPAN_ATTRIBUTE_COUNT_LIMIT, attributes ) self.events = self._new_events() @@ -462,7 +465,7 @@ def __init__( if links is None: self.links = self._new_links() else: - self.links = BoundedList.from_seq(MAX_NUM_LINKS, links) + self.links = BoundedList.from_seq(SPAN_LINK_COUNT_LIMIT, links) self._end_time = None # type: Optional[int] self._start_time = None # type: Optional[int] @@ -483,15 +486,15 @@ def __repr__(self): @staticmethod def _new_attributes(): - return BoundedDict(MAX_NUM_ATTRIBUTES) + return BoundedDict(SPAN_ATTRIBUTE_COUNT_LIMIT) @staticmethod def _new_events(): - return BoundedList(MAX_NUM_EVENTS) + return BoundedList(SPAN_EVENT_COUNT_LIMIT) @staticmethod def _new_links(): - return BoundedList(MAX_NUM_LINKS) + return BoundedList(SPAN_LINK_COUNT_LIMIT) @staticmethod def _format_context(context): diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py index 53f85dcbb2e..d8786e6d21a 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py @@ -13,12 +13,14 @@ # limitations under the License. import collections +import json import logging import os import sys import threading import typing from enum import Enum +from typing import Optional from opentelemetry.configuration import Configuration from opentelemetry.context import Context, attach, detach, set_value @@ -370,12 +372,14 @@ class ConsoleSpanExporter(SpanExporter): def __init__( self, + service_name: Optional[str] = None, out: typing.IO = sys.stdout, formatter: typing.Callable[[Span], str] = lambda span: span.to_json() + os.linesep, ): self.out = out self.formatter = formatter + self.service_name = service_name def export(self, spans: typing.Sequence[Span]) -> SpanExportResult: for span in spans: diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/__init__.py index e69de29bb2d..a02a07ea2af 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/__init__.py @@ -0,0 +1,26 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import typing + +from opentelemetry.trace.propagation.textmap import TextMapPropagatorT + + +def extract_first_element( + items: typing.Iterable[TextMapPropagatorT], +) -> typing.Optional[TextMapPropagatorT]: + if items is None: + return None + return next(iter(items), None) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/jaeger_propagator.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/jaeger_propagator.py new file mode 100644 index 00000000000..e4d2b1cb2cc --- /dev/null +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/jaeger_propagator.py @@ -0,0 +1,137 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import typing +import urllib.parse + +import opentelemetry.trace as trace +from opentelemetry import baggage +from opentelemetry.context import Context, get_current +from opentelemetry.sdk.trace.propagation import extract_first_element +from opentelemetry.trace.propagation.textmap import ( + Getter, + Setter, + TextMapPropagator, + TextMapPropagatorT, +) + + +class JaegerPropagator(TextMapPropagator): + """Propagator for the Jaeger format. + + See: https://www.jaegertracing.io/docs/1.19/client-libraries/#propagation-format + """ + + TRACE_ID_KEY = "uber-trace-id" + BAGGAGE_PREFIX = "uberctx-" + DEBUG_FLAG = 0x02 + + def extract( + self, + getter: Getter[TextMapPropagatorT], + carrier: TextMapPropagatorT, + context: typing.Optional[Context] = None, + ) -> Context: + + if context is None: + context = get_current() + fields = extract_first_element( + getter.get(carrier, self.TRACE_ID_KEY) + ).split(":") + + context = self._extract_baggage(getter, carrier, context) + if len(fields) != 4: + return trace.set_span_in_context(trace.INVALID_SPAN, context) + + trace_id, span_id, _parent_id, flags = fields + if ( + trace_id == trace.INVALID_TRACE_ID + or span_id == trace.INVALID_SPAN_ID + ): + return trace.set_span_in_context(trace.INVALID_SPAN, context) + + span = trace.DefaultSpan( + trace.SpanContext( + trace_id=int(trace_id, 16), + span_id=int(span_id, 16), + is_remote=True, + trace_flags=trace.TraceFlags( + int(flags, 16) & trace.TraceFlags.SAMPLED + ), + ) + ) + return trace.set_span_in_context(span, context) + + def inject( + self, + set_in_carrier: Setter[TextMapPropagatorT], + carrier: TextMapPropagatorT, + context: typing.Optional[Context] = None, + ) -> None: + span = trace.get_current_span(context=context) + span_context = span.get_span_context() + if span_context == trace.INVALID_SPAN_CONTEXT: + return + + span_parent_id = span.parent.span_id if span.parent else 0 + trace_flags = span_context.trace_flags + if trace_flags.sampled: + trace_flags |= self.DEBUG_FLAG + + # set span identity + set_in_carrier( + carrier, + self.TRACE_ID_KEY, + _format_uber_trace_id( + span_context.trace_id, + span_context.span_id, + span_parent_id, + trace_flags, + ), + ) + + # set span baggage, if any + baggage_entries = baggage.get_all(context=context) + if not baggage_entries: + return + for key, value in baggage_entries.items(): + baggage_key = self.BAGGAGE_PREFIX + key + set_in_carrier( + carrier, baggage_key, urllib.parse.quote(str(value)) + ) + + @property + def fields(self) -> typing.Set[str]: + return {self.TRACE_ID_KEY} + + def _extract_baggage(self, getter, carrier, context): + baggage_keys = [ + key + for key in getter.keys(carrier) + if key.startswith(self.BAGGAGE_PREFIX) + ] + for key in baggage_keys: + value = extract_first_element(getter.get(carrier, key)) + context = baggage.set_baggage( + key.replace(self.BAGGAGE_PREFIX, ""), + urllib.parse.unquote(value).strip(), + context=context, + ) + return context + + +def _format_uber_trace_id(trace_id, span_id, parent_span_id, flags): + return "{:032x}:{:016x}:{:016x}:{:02x}".format( + trace_id, span_id, parent_span_id, flags + ) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py index 09d7283cab7..b2d3930bb10 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py @@ -17,12 +17,10 @@ try: # pylint: disable=ungrouped-imports - from collections.abc import MutableMapping - from collections.abc import Sequence + from collections.abc import MutableMapping, Sequence except ImportError: # pylint: disable=no-name-in-module,ungrouped-imports - from collections import MutableMapping - from collections import Sequence + from collections import MutableMapping, Sequence def ns_to_iso_str(nanoseconds): diff --git a/opentelemetry-sdk/tests/context/test_asyncio.py b/opentelemetry-sdk/tests/context/test_asyncio.py index 452915d86c4..c235e71d83e 100644 --- a/opentelemetry-sdk/tests/context/test_asyncio.py +++ b/opentelemetry-sdk/tests/context/test_asyncio.py @@ -25,6 +25,7 @@ try: import contextvars # pylint: disable=unused-import + from opentelemetry.context.contextvars_context import ( ContextVarsRuntimeContext, ) diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 1697d8e6c85..32c22c8c6bb 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -118,11 +118,9 @@ def callback(observer): self.assertIsInstance(observer, metrics_api.Observer) observer.observe(45, {}) - observer = metrics.ValueObserver( + meter.register_valueobserver( callback, "name", "desc", "unit", int, (), True ) - - meter.observers.add(observer) meter.collect() self.assertTrue(processor_mock.process.called) @@ -164,6 +162,23 @@ def test_create_counter(self): self.assertIs(meter_provider.resource, resource) self.assertEqual(counter.meter, meter) + def test_instrument_same_name_error(self): + resource = Mock(spec=resources.Resource) + meter_provider = metrics.MeterProvider(resource=resource) + meter = meter_provider.get_meter(__name__) + counter = meter.create_counter("name", "desc", "unit", int,) + self.assertIsInstance(counter, metrics.Counter) + self.assertEqual(counter.value_type, int) + self.assertEqual(counter.name, "name") + self.assertIs(meter_provider.resource, resource) + self.assertEqual(counter.meter, meter) + with self.assertRaises(ValueError) as ctx: + _ = meter.create_counter("naME", "desc", "unit", int,) + self.assertTrue( + "Multiple instruments can't be registered by the same name: (name)" + in str(ctx.exception) + ) + def test_create_updowncounter(self): meter = metrics.MeterProvider().get_meter(__name__) updowncounter = meter.create_updowncounter( @@ -193,7 +208,7 @@ def test_register_sumobserver(self): ) self.assertIsInstance(observer, metrics.SumObserver) - self.assertEqual(len(meter.observers), 1) + self.assertEqual(len(meter.instruments), 1) self.assertEqual(observer.callback, callback) self.assertEqual(observer.name, "name") @@ -213,7 +228,7 @@ def test_register_updownsumobserver(self): ) self.assertIsInstance(observer, metrics.UpDownSumObserver) - self.assertEqual(len(meter.observers), 1) + self.assertEqual(len(meter.instruments), 1) self.assertEqual(observer.callback, callback) self.assertEqual(observer.name, "name") @@ -233,7 +248,7 @@ def test_register_valueobserver(self): ) self.assertIsInstance(observer, metrics.ValueObserver) - self.assertEqual(len(meter.observers), 1) + self.assertEqual(len(meter.instruments), 1) self.assertEqual(observer.callback, callback) self.assertEqual(observer.name, "name") @@ -253,7 +268,27 @@ def test_unregister_observer(self): ) meter.unregister_observer(observer) - self.assertEqual(len(meter.observers), 0) + self.assertEqual(len(meter.instruments), 0) + + def test_unregister_and_reregister_observer(self): + meter = metrics.MeterProvider().get_meter(__name__) + + callback = Mock() + + observer = meter.register_valueobserver( + callback, + "nameCaSEinSENsitive", + "desc", + "unit", + int, + metrics.ValueObserver, + ) + + meter.unregister_observer(observer) + self.assertEqual(len(meter.instruments), 0) + observer = meter.register_valueobserver( + callback, "name", "desc", "unit", int, metrics.ValueObserver + ) class TestMetric(unittest.TestCase): diff --git a/opentelemetry-sdk/tests/performance/benchmarks/trace/test_benchmark_trace.py b/opentelemetry-sdk/tests/performance/benchmarks/trace/test_benchmark_trace.py new file mode 100644 index 00000000000..a407a341f45 --- /dev/null +++ b/opentelemetry-sdk/tests/performance/benchmarks/trace/test_benchmark_trace.py @@ -0,0 +1,51 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import opentelemetry.sdk.trace as trace +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import sampling + +tracer = trace.TracerProvider( + sampler=sampling.DEFAULT_ON, + resource=Resource( + { + "service.name": "A123456789", + "service.version": "1.34567890", + "service.instance.id": "123ab456-a123-12ab-12ab-12340a1abc12", + } + ), +).get_tracer("sdk_tracer_provider") + + +def test_simple_start_span(benchmark): + def benchmark_start_as_current_span(): + span = tracer.start_span( + "benchmarkedSpan", + attributes={"long.attribute": -10000000001000000000}, + ) + span.add_event("benchmarkEvent") + span.end() + + benchmark(benchmark_start_as_current_span) + + +def test_simple_start_as_current_span(benchmark): + def benchmark_start_as_current_span(): + with tracer.start_as_current_span( + "benchmarkedSpan", + attributes={"long.attribute": -10000000001000000000}, + ) as span: + span.add_event("benchmarkEvent") + + benchmark(benchmark_start_as_current_span) diff --git a/opentelemetry-sdk/tests/trace/export/test_export.py b/opentelemetry-sdk/tests/trace/export/test_export.py index 4ad23dd8631..92d4f65d136 100644 --- a/opentelemetry-sdk/tests/trace/export/test_export.py +++ b/opentelemetry-sdk/tests/trace/export/test_export.py @@ -477,14 +477,15 @@ def test_batch_span_processor_parameters(self): class TestConsoleSpanExporter(unittest.TestCase): def test_export(self): # pylint: disable=no-self-use """Check that the console exporter prints spans.""" - exporter = export.ConsoleSpanExporter() + exporter = export.ConsoleSpanExporter() # Mocking stdout interferes with debugging and test reporting, mock on # the exporter instance instead. span = trace._Span("span name", trace_api.INVALID_SPAN_CONTEXT) with mock.patch.object(exporter, "out") as mock_stdout: exporter.export([span]) mock_stdout.write.assert_called_once_with(span.to_json() + os.linesep) + self.assertEqual(mock_stdout.write.call_count, 1) self.assertEqual(mock_stdout.flush.call_count, 1) diff --git a/opentelemetry-sdk/tests/trace/propagation/test_jaeger_propagator.py b/opentelemetry-sdk/tests/trace/propagation/test_jaeger_propagator.py new file mode 100644 index 00000000000..bd80770368b --- /dev/null +++ b/opentelemetry-sdk/tests/trace/propagation/test_jaeger_propagator.py @@ -0,0 +1,184 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +from unittest.mock import Mock + +import opentelemetry.sdk.trace as trace +import opentelemetry.sdk.trace.propagation.jaeger_propagator as jaeger +import opentelemetry.trace as trace_api +from opentelemetry import baggage +from opentelemetry.trace.propagation.textmap import DictGetter + +FORMAT = jaeger.JaegerPropagator() + + +carrier_getter = DictGetter() + + +def get_context_new_carrier(old_carrier, carrier_baggage=None): + + ctx = FORMAT.extract(carrier_getter, old_carrier) + if carrier_baggage: + for key, value in carrier_baggage.items(): + ctx = baggage.set_baggage(key, value, ctx) + parent_span_context = trace_api.get_current_span(ctx).get_span_context() + + parent = trace._Span("parent", parent_span_context) + child = trace._Span( + "child", + trace_api.SpanContext( + parent_span_context.trace_id, + trace_api.RandomIdsGenerator().generate_span_id(), + is_remote=False, + trace_flags=parent_span_context.trace_flags, + trace_state=parent_span_context.trace_state, + ), + parent=parent.get_span_context(), + ) + + new_carrier = {} + ctx = trace_api.set_span_in_context(child, ctx) + + FORMAT.inject(dict.__setitem__, new_carrier, context=ctx) + + return ctx, new_carrier + + +def _format_uber_trace_id(trace_id, span_id, parent_span_id, flags): + return "{:032x}:{:016x}:{:016x}:{:02x}".format( + trace_id, span_id, parent_span_id, flags + ) + + +class TestJaegerPropagator(unittest.TestCase): + @classmethod + def setUpClass(cls): + ids_generator = trace_api.RandomIdsGenerator() + cls.trace_id = ids_generator.generate_trace_id() + cls.span_id = ids_generator.generate_span_id() + cls.parent_span_id = ids_generator.generate_span_id() + cls.serialized_uber_trace_id = _format_uber_trace_id( + cls.trace_id, cls.span_id, cls.parent_span_id, 11 + ) + + def test_extract_valid_span(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + ctx = FORMAT.extract(carrier_getter, old_carrier) + span_context = trace_api.get_current_span(ctx).get_span_context() + self.assertEqual(span_context.trace_id, self.trace_id) + self.assertEqual(span_context.span_id, self.span_id) + + def test_trace_id(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + _, new_carrier = get_context_new_carrier(old_carrier) + self.assertEqual( + self.serialized_uber_trace_id.split(":")[0], + new_carrier[FORMAT.TRACE_ID_KEY].split(":")[0], + ) + + def test_parent_span_id(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + _, new_carrier = get_context_new_carrier(old_carrier) + span_id = self.serialized_uber_trace_id.split(":")[1] + parent_span_id = new_carrier[FORMAT.TRACE_ID_KEY].split(":")[2] + self.assertEqual(span_id, parent_span_id) + + def test_sampled_flag_set(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + _, new_carrier = get_context_new_carrier(old_carrier) + sample_flag_value = ( + int(new_carrier[FORMAT.TRACE_ID_KEY].split(":")[3]) & 0x01 + ) + self.assertEqual(1, sample_flag_value) + + def test_debug_flag_set(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + _, new_carrier = get_context_new_carrier(old_carrier) + debug_flag_value = ( + int(new_carrier[FORMAT.TRACE_ID_KEY].split(":")[3]) + & FORMAT.DEBUG_FLAG + ) + self.assertEqual(FORMAT.DEBUG_FLAG, debug_flag_value) + + def test_sample_debug_flags_unset(self): + uber_trace_id = _format_uber_trace_id( + self.trace_id, self.span_id, self.parent_span_id, 0 + ) + old_carrier = {FORMAT.TRACE_ID_KEY: uber_trace_id} + _, new_carrier = get_context_new_carrier(old_carrier) + flags = int(new_carrier[FORMAT.TRACE_ID_KEY].split(":")[3]) + sample_flag_value = flags & 0x01 + debug_flag_value = flags & FORMAT.DEBUG_FLAG + self.assertEqual(0, sample_flag_value) + self.assertEqual(0, debug_flag_value) + + def test_baggage(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + input_baggage = {"key1": "value1"} + _, new_carrier = get_context_new_carrier(old_carrier, input_baggage) + ctx = FORMAT.extract(carrier_getter, new_carrier) + self.assertDictEqual(input_baggage, ctx["baggage"]) + + def test_non_string_baggage(self): + old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id} + input_baggage = {"key1": 1, "key2": True} + formatted_baggage = {"key1": "1", "key2": "True"} + _, new_carrier = get_context_new_carrier(old_carrier, input_baggage) + ctx = FORMAT.extract(carrier_getter, new_carrier) + self.assertDictEqual(formatted_baggage, ctx["baggage"]) + + def test_extract_invalid_uber_trace_id(self): + old_carrier = { + "uber-trace-id": "000000000000000000000000deadbeef:00000000deadbef0:00", + "uberctx-key1": "value1", + } + formatted_baggage = {"key1": "value1"} + context = FORMAT.extract(carrier_getter, old_carrier) + span_context = trace_api.get_current_span(context).get_span_context() + self.assertEqual(span_context.span_id, trace_api.INVALID_SPAN_ID) + self.assertDictEqual(formatted_baggage, context["baggage"]) + + def test_extract_invalid_trace_id(self): + old_carrier = { + "uber-trace-id": "00000000000000000000000000000000:00000000deadbef0:00:00", + "uberctx-key1": "value1", + } + formatted_baggage = {"key1": "value1"} + context = FORMAT.extract(carrier_getter, old_carrier) + span_context = trace_api.get_current_span(context).get_span_context() + self.assertEqual(span_context.trace_id, trace_api.INVALID_TRACE_ID) + self.assertDictEqual(formatted_baggage, context["baggage"]) + + def test_extract_invalid_span_id(self): + old_carrier = { + "uber-trace-id": "000000000000000000000000deadbeef:0000000000000000:00:00", + "uberctx-key1": "value1", + } + formatted_baggage = {"key1": "value1"} + context = FORMAT.extract(carrier_getter, old_carrier) + span_context = trace_api.get_current_span(context).get_span_context() + self.assertEqual(span_context.span_id, trace_api.INVALID_SPAN_ID) + self.assertDictEqual(formatted_baggage, context["baggage"]) + + def test_fields(self): + tracer = trace.TracerProvider().get_tracer("sdk_tracer_provider") + mock_set_in_carrier = Mock() + with tracer.start_as_current_span("parent"): + with tracer.start_as_current_span("child"): + FORMAT.inject(mock_set_in_carrier, {}) + inject_fields = set() + for call in mock_set_in_carrier.mock_calls: + inject_fields.add(call[1][1]) + self.assertEqual(FORMAT.fields, inject_fields) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index ea3e58b938b..bfefdfcb42a 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -16,11 +16,15 @@ import shutil import subprocess import unittest +from importlib import reload from logging import ERROR, WARNING from typing import Optional from unittest import mock +import pytest + from opentelemetry import trace as trace_api +from opentelemetry.configuration import Configuration from opentelemetry.context import Context from opentelemetry.sdk import resources, trace from opentelemetry.sdk.trace import Resource, sampling @@ -1213,3 +1217,49 @@ def test_attributes_to_json(self): + date_str + '", "attributes": {"key2": "value2"}}], "links": [], "resource": {}}', ) + + +class TestSpanLimits(unittest.TestCase): + def setUp(self): + # reset global state of configuration object + # pylint: disable=protected-access + Configuration._reset() + + def tearDown(self): + # reset global state of configuration object + # pylint: disable=protected-access + Configuration._reset() + + @mock.patch.dict( + "os.environ", + { + "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT": "10", + "OTEL_SPAN_EVENT_COUNT_LIMIT": "20", + "OTEL_SPAN_LINK_COUNT_LIMIT": "30", + }, + ) + def test_span_environment_limits(self): + reload(trace) + tracer = new_tracer() + ids_generator = trace_api.RandomIdsGenerator() + some_links = [ + trace_api.Link( + trace_api.SpanContext( + trace_id=ids_generator.generate_trace_id(), + span_id=ids_generator.generate_span_id(), + is_remote=False, + ) + ) + for _ in range(100) + ] + with pytest.raises(ValueError): + with tracer.start_as_current_span("root", links=some_links): + pass + + with tracer.start_as_current_span("root") as root: + for idx in range(100): + root.set_attribute("my_attribute_{}".format(idx), 0) + root.add_event("my_event_{}".format(idx)) + + self.assertEqual(len(root.attributes), 10) + self.assertEqual(len(root.events), 20) diff --git a/scripts/eachdist.py b/scripts/eachdist.py index cfa1764ab37..4bf1f33370b 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -509,7 +509,7 @@ def lint_args(args): ) runsubprocess( args.dry_run, - ("isort", "--recursive", ".") + ("isort", ".") + (("--diff", "--check-only") if args.check_only else ()), cwd=rootdir, check=True, diff --git a/tests/util/setup.cfg b/tests/util/setup.cfg index c788346791c..a1fdf1a01e3 100644 --- a/tests/util/setup.cfg +++ b/tests/util/setup.cfg @@ -30,6 +30,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [options] python_requires = >=3.5 diff --git a/tox.ini b/tox.ini index b9682256458..c5044993b81 100644 --- a/tox.ini +++ b/tox.ini @@ -5,52 +5,52 @@ envlist = ; Environments are organized by individual package, allowing ; for specifying supported Python versions per package. ; opentelemetry-api - py3{5,6,7,8}-test-core-api + py3{5,6,7,8,9}-test-core-api pypy3-test-core-api ; opentelemetry-proto - py3{5,6,7,8}-test-core-proto + py3{5,6,7,8,9}-test-core-proto pypy3-test-core-proto ; opentelemetry-sdk - py3{5,6,7,8}-test-core-sdk + py3{5,6,7,8,9}-test-core-sdk pypy3-test-core-sdk ; opentelemetry-instrumentation - py3{5,6,7,8}-test-core-instrumentation + py3{5,6,7,8,9}-test-core-instrumentation pypy3-test-core-instrumentation ; docs/getting-started - py3{5,6,7,8}-test-core-getting-started + py3{5,6,7,8,9}-test-core-getting-started pypy3-test-core-getting-started ; opentelemetry-exporter-jaeger - py3{5,6,7,8}-test-exporter-jaeger + py3{5,6,7,8,9}-test-exporter-jaeger pypy3-test-exporter-jaeger ; opentelemetry-exporter-opencensus - py3{5,6,7,8}-test-exporter-opencensus + py3{5,6,7,8,9}-test-exporter-opencensus ; exporter-opencensus intentionally excluded from pypy3 ; opentelemetry-exporter-otlp - py3{5,6,7,8}-test-exporter-otlp + py3{5,6,7,8,9}-test-exporter-otlp ; exporter-otlp intentionally excluded from pypy3 ; opentelemetry-exporter-prometheus - py3{5,6,7,8}-test-exporter-prometheus + py3{5,6,7,8,9}-test-exporter-prometheus pypy3-test-exporter-prometheus ; opentelemetry-exporter-zipkin - py3{5,6,7,8}-test-exporter-zipkin + py3{5,6,7,8,9}-test-exporter-zipkin pypy3-test-exporter-zipkin ; opentelemetry-opentracing-shim - py3{5,6,7,8}-test-core-opentracing-shim + py3{5,6,7,8,9}-test-core-opentracing-shim pypy3-test-core-opentracing-shim lint - py38-tracecontext - py38-{mypy,mypyinstalled} + tracecontext + mypy,mypyinstalled docs docker-tests @@ -58,6 +58,7 @@ envlist = deps = -c dev-requirements.txt test: pytest + test: pytest-benchmark coverage: pytest coverage: pytest-cov mypy,mypyinstalled: mypy @@ -80,7 +81,7 @@ changedir = commands_pre = ; Install without -e to test the actual installation - py3{5,6,7,8}: python -m pip install -U pip setuptools wheel + py3{5,6,7,8,9}: python -m pip install -U pip setuptools wheel ; Install common packages for all the tests. These are not needed in all the ; cases but it saves a lot of boilerplate in this file. test: pip install {toxinidir}/opentelemetry-api {toxinidir}/opentelemetry-sdk {toxinidir}/tests/util @@ -139,7 +140,17 @@ deps = httpretty commands_pre = - python scripts/eachdist.py install --editable --with-test-deps + python -m pip install -e {toxinidir}/opentelemetry-api[test] + python -m pip install -e {toxinidir}/opentelemetry-sdk[test] + python -m pip install -e {toxinidir}/opentelemetry-instrumentation[test] + python -m pip install -e {toxinidir}/opentelemetry-proto[test] + python -m pip install -e {toxinidir}/tests/util[test] + python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-opentracing-shim[test] + python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-jaeger[test] + python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-opencensus[test] + python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-otlp[test] + python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-prometheus[test] + python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-zipkin[test] commands = python scripts/eachdist.py lint --check-only @@ -154,8 +165,8 @@ changedir = docs commands = sphinx-build -E -a -W -b html -T . _build/html -[testenv:py38-tracecontext] -basepython: python3.8 +[testenv:tracecontext] +basepython: python3.9 deps = # needed for tracecontext aiohttp~=3.6