Skip to content

Commit 220ea1e

Browse files
committed
Add opentelemetry-instrumentation
Fixes #1958
1 parent bb41b81 commit 220ea1e

32 files changed

+1822
-16
lines changed

.github/pull_request_template.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Please describe the tests that you ran to verify your changes. Provide instructi
2323

2424
Answer the following question based on these examples of changes that would require a Contrib Repo Change:
2525
- [The OTel specification](https://github.com/open-telemetry/opentelemetry-specification) has changed which prompted this PR to update the method interfaces of `opentelemetry-api/` or `opentelemetry-sdk/`
26+
- The method interfaces of `opentelemetry-instrumentation/` have changed
2627
- The method interfaces of `test/util` have changed
2728
- Scripts in `scripts/` that were copied over to the Contrib repo have changed
2829
- Configuration files that were copied over to the Contrib repo have changed (when consistency between repositories is applicable) such as in

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ env:
1010
# Otherwise, set variable to the commit of your branch on
1111
# opentelemetry-python-contrib which is compatible with these Core repo
1212
# changes.
13-
CONTRIB_REPO_SHA: 7e9964d788c2f91697a682d5f0d01bcfeedf9524
13+
CONTRIB_REPO_SHA: 793ddb4ed638231f387eef2e11207ffb18c6682a
1414

1515
jobs:
1616
build:

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010

1111

1212
### Added
13+
- Moved `opentelemetry-instrumentation` to core repository.
14+
([#1959](https://github.com/open-telemetry/opentelemetry-python/pull/1959))
1315
- Dropped attributes/events/links count available exposed on ReadableSpans.
1416
([#1893](https://github.com/open-telemetry/opentelemetry-python/pull/1893))
1517
- Added dropped count to otlp, jaeger and zipkin exporters.

docs-requirements.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ sphinx-jekyll-builder
88
# doesn't work for pkg_resources.
99
./opentelemetry-api
1010
./opentelemetry-semantic-conventions
11-
./opentelemetry-python-contrib/opentelemetry-instrumentation
11+
./opentelemetry-instrumentation
1212
./opentelemetry-sdk
13+
./opentelemetry-instrumentation
1314

1415
# Required by instrumentation and exporter packages
16+
asgiref~=3.0
17+
asyncpg>=0.12.0
1518
ddtrace>=0.34.0
1619
grpcio~=1.27
1720
Deprecated>=1.2.6

docs/conf.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323

2424
settings.configure()
2525

26+
27+
source_dirs = [
28+
os.path.abspath("../opentelemetry-instrumentation/src/"),
29+
]
30+
2631
exp = "../exporter"
2732
exp_dirs = [
2833
os.path.abspath("/".join(["../exporter", f, "src"]))
@@ -37,7 +42,7 @@
3742
if isdir(join(shim, f))
3843
]
3944

40-
sys.path[:0] = exp_dirs + shim_dirs
45+
sys.path[:0] = source_dirs + exp_dirs + shim_dirs
4146

4247
# -- Project information -----------------------------------------------------
4348

eachdist.ini

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ignore=
77
sortfirst=
88
opentelemetry-api
99
opentelemetry-sdk
10+
opentelemetry-instrumentation
1011
opentelemetry-proto
1112
opentelemetry-distro
1213
tests/util
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
prune tests
2+
graft src
3+
global-exclude *.pyc
4+
global-exclude *.pyo
5+
global-exclude __pycache__/*
6+
include MANIFEST.in
7+
include README.rst
+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
OpenTelemetry Instrumentation
2+
=============================
3+
4+
|pypi|
5+
6+
.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation.svg
7+
:target: https://pypi.org/project/opentelemetry-instrumentation/
8+
9+
Installation
10+
------------
11+
12+
::
13+
14+
pip install opentelemetry-instrumentation
15+
16+
17+
This package provides a couple of commands that help automatically instruments a program:
18+
19+
20+
opentelemetry-bootstrap
21+
-----------------------
22+
23+
::
24+
25+
opentelemetry-bootstrap --action=install|requirements
26+
27+
This commands inspects the active Python site-packages and figures out which
28+
instrumentation packages the user might want to install. By default it prints out
29+
a list of the suggested instrumentation packages which can be added to a requirements.txt
30+
file. It also supports installing the suggested packages when run with :code:`--action=install`
31+
flag.
32+
33+
34+
opentelemetry-instrument
35+
------------------------
36+
37+
::
38+
39+
opentelemetry-instrument python program.py
40+
41+
The instrument command will try to automatically detect packages used by your python program
42+
and when possible, apply automatic tracing instrumentation on them. This means your program
43+
will get automatic distributed tracing for free without having to make any code changes
44+
at all. This will also configure a global tracer and tracing exporter without you having to
45+
make any code changes. By default, the instrument command will use the OTLP exporter but
46+
this can be overriden when needed.
47+
48+
The command supports the following configuration options as CLI arguments and environment vars:
49+
50+
51+
* ``--trace-exporter`` or ``OTEL_TRACE_EXPORTER``
52+
53+
Used to specify which trace exporter to use. Can be set to one or more of the well-known exporter
54+
names (see below).
55+
56+
- Defaults to `otlp`.
57+
- Can be set to `none` to disable automatic tracer initialization.
58+
59+
You can pass multiple values to configure multiple exporters e.g, ``zipkin,prometheus``
60+
61+
Well known trace exporter names:
62+
63+
- jaeger
64+
- opencensus
65+
- otlp
66+
- otlp_proto_grpc_span
67+
- zipkin
68+
69+
``otlp`` is an alias for ``otlp_proto_grpc_span``.
70+
71+
* ``--id-generator`` or ``OTEL_PYTHON_ID_GENERATOR``
72+
73+
Used to specify which IDs Generator to use for the global Tracer Provider. By default, it
74+
will use the random IDs generator.
75+
76+
The code in ``program.py`` needs to use one of the packages for which there is
77+
an OpenTelemetry integration. For a list of the available integrations please
78+
check `here <https://opentelemetry-python.readthedocs.io/en/stable/index.html#integrations>`_
79+
80+
* ``OTEL_PYTHON_DISABLED_INSTRUMENTATIONS``
81+
82+
If set by the user, opentelemetry-instrument will read this environment variable to disable specific instrumentations.
83+
e.g OTEL_PYTHON_DISABLED_INSTRUMENTATIONS = "requests,django"
84+
85+
86+
Examples
87+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88+
89+
::
90+
91+
opentelemetry-instrument --trace-exporter otlp flask run --port=3000
92+
93+
The above command will pass ``--trace-exporter otlp`` to the instrument command and ``--port=3000`` to ``flask run``.
94+
95+
::
96+
97+
opentelemetry-instrument --trace-exporter zipkin,otlp celery -A tasks worker --loglevel=info
98+
99+
The above command will configure global trace provider, attach zipkin and otlp exporters to it and then
100+
start celery with the rest of the arguments.
101+
102+
::
103+
104+
opentelemetry-instrument --ids-generator random flask run --port=3000
105+
106+
The above command will configure the global trace provider to use the Random IDs Generator, and then
107+
pass ``--port=3000`` to ``flask run``.
108+
109+
References
110+
----------
111+
112+
* `OpenTelemetry Project <https://opentelemetry.io/>`_
+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
[metadata]
16+
name = opentelemetry-instrumentation
17+
description = Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python
18+
long_description = file: README.rst
19+
long_description_content_type = text/x-rst
20+
author = OpenTelemetry Authors
21+
author_email = [email protected]
22+
url = https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation
23+
platforms = any
24+
license = Apache-2.0
25+
classifiers =
26+
Development Status :: 4 - Beta
27+
Intended Audience :: Developers
28+
License :: OSI Approved :: Apache Software License
29+
Programming Language :: Python
30+
Programming Language :: Python :: 3
31+
Programming Language :: Python :: 3.6
32+
Programming Language :: Python :: 3.7
33+
Programming Language :: Python :: 3.8
34+
Programming Language :: Python :: 3.9
35+
36+
[options]
37+
python_requires = >=3.6
38+
package_dir=
39+
=src
40+
packages=find_namespace:
41+
zip_safe = False
42+
include_package_data = True
43+
install_requires =
44+
opentelemetry-api ~= 1.3
45+
wrapt >= 1.0.0, < 2.0.0
46+
47+
[options.packages.find]
48+
where = src
49+
50+
[options.entry_points]
51+
console_scripts =
52+
opentelemetry-instrument = opentelemetry.instrumentation.auto_instrumentation:run
53+
opentelemetry-bootstrap = opentelemetry.instrumentation.bootstrap:run
54+
55+
[options.extras_require]
56+
test =
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
import setuptools
18+
19+
BASE_DIR = os.path.dirname(__file__)
20+
VERSION_FILENAME = os.path.join(
21+
BASE_DIR, "src", "opentelemetry", "instrumentation", "version.py"
22+
)
23+
PACKAGE_INFO = {}
24+
with open(VERSION_FILENAME) as f:
25+
exec(f.read(), PACKAGE_INFO)
26+
27+
setuptools.setup(version=PACKAGE_INFO["__version__"],)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import argparse
18+
from logging import getLogger
19+
from os import environ, execl, getcwd
20+
from os.path import abspath, dirname, pathsep
21+
from shutil import which
22+
23+
from opentelemetry.environment_variables import (
24+
OTEL_PYTHON_ID_GENERATOR,
25+
OTEL_TRACES_EXPORTER,
26+
)
27+
28+
logger = getLogger(__file__)
29+
30+
31+
def parse_args():
32+
parser = argparse.ArgumentParser(
33+
description="""
34+
opentelemetry-instrument automatically instruments a Python
35+
program and it's dependencies and then runs the program.
36+
"""
37+
)
38+
39+
parser.add_argument(
40+
"--trace-exporter",
41+
required=False,
42+
help="""
43+
Uses the specified exporter to export spans.
44+
Accepts multiple exporters as comma separated values.
45+
46+
Examples:
47+
48+
--trace-exporter=jaeger
49+
""",
50+
)
51+
52+
parser.add_argument(
53+
"--id-generator",
54+
required=False,
55+
help="""
56+
The IDs Generator to be used with the Tracer Provider.
57+
58+
Examples:
59+
60+
--id-generator=random
61+
""",
62+
)
63+
64+
parser.add_argument("command", help="Your Python application.")
65+
parser.add_argument(
66+
"command_args",
67+
help="Arguments for your application.",
68+
nargs=argparse.REMAINDER,
69+
)
70+
return parser.parse_args()
71+
72+
73+
def load_config_from_cli_args(args):
74+
if args.trace_exporter:
75+
environ[OTEL_TRACES_EXPORTER] = args.trace_exporter
76+
if args.id_generator:
77+
environ[OTEL_PYTHON_ID_GENERATOR] = args.id_generator
78+
79+
80+
def run() -> None:
81+
args = parse_args()
82+
load_config_from_cli_args(args)
83+
84+
python_path = environ.get("PYTHONPATH")
85+
86+
if not python_path:
87+
python_path = []
88+
89+
else:
90+
python_path = python_path.split(pathsep)
91+
92+
cwd_path = getcwd()
93+
94+
# This is being added to support applications that are being run from their
95+
# own executable, like Django.
96+
# FIXME investigate if there is another way to achieve this
97+
if cwd_path not in python_path:
98+
python_path.insert(0, cwd_path)
99+
100+
filedir_path = dirname(abspath(__file__))
101+
102+
python_path = [path for path in python_path if path != filedir_path]
103+
104+
python_path.insert(0, filedir_path)
105+
106+
environ["PYTHONPATH"] = pathsep.join(python_path)
107+
108+
executable = which(args.command)
109+
execl(executable, executable, *args.command_args)

0 commit comments

Comments
 (0)