Skip to content

Commit 66d56ac

Browse files
authored
Merge branch 'main' into fix-tox-deps
2 parents ed57999 + 4e992dd commit 66d56ac

File tree

15 files changed

+369
-116
lines changed

15 files changed

+369
-116
lines changed

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extension-pkg-whitelist=cassandra
77

88
# Add list of files or directories to be excluded. They should be base names, not
99
# paths.
10-
ignore=CVS,gen,Dockerfile,docker-compose.yml,README.md,requirements.txt,docs
10+
ignore=CVS,gen,Dockerfile,docker-compose.yml,README.md,requirements.txt,docs,.venv
1111

1212
# Add files or directories matching the regex patterns to be excluded. The
1313
# regex matches against base names, not paths.

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
- `opentelemetry-instrumentation-sqlalchemy` Update unit tests to run with SQLALchemy 2
1717
([#2976](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2976))
18-
- Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap`
18+
- Add `opentelemetry-instrumentation-openai-v2` to `opentelemetry-bootstrap`
1919
([#2996](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2996))
20+
- `opentelemetry-instrumentation-sqlalchemy` Add sqlcomment to `db.statement` attribute
21+
([#2937](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2937))
22+
- `opentelemetry-instrumentation-dbapi` Add sqlcomment to `db.statement` attribute
23+
([#2935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2935))
24+
- `opentelemetry-instrumentation-dbapi` instrument_connection accepts optional connect_module
25+
([#3027](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3027))
2026

2127
### Fixed
2228

2329
- `opentelemetry-instrumentation-httpx`: instrument_client is a static method again
2430
([#3003](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3003))
31+
- `opentelemetry-instrumentation-httpx`: Check if mount transport is none before wrap it
32+
([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022))
2533

2634
### Breaking changes
2735

RELEASING.md

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
(otherwise the workflow will pick up the version from `main` and just remove the `.dev` suffix).
1010
* Review the two pull requests that it creates.
1111
(one is targeted to the release branch and one is targeted to `main`).
12-
* Merge the one targeted towards the release branch.
13-
* The builds will fail for the `main` pr because of validation rules. Follow the [release workflow](https://github.com/open-telemetry/opentelemetry-python/blob/main/RELEASING.md) for the core repo up until this same point. Change the SHAs of each PR to point at each other to get the `main` builds to pass.
12+
* The builds will fail for both the `main` and release pr because of validation rules. Follow the [release workflow](https://github.com/open-telemetry/opentelemetry-python/blob/main/RELEASING.md) for the core repo up until this same point. Change the SHAs of each PR to point at each other to get the `main` and release builds to pass.
13+
* Merge the release PR.
14+
* Merge the PR to main (this can be done separately from [making the release](#making-the-release))
1415

1516
### Preparing a major or minor release for individual package
1617

@@ -62,6 +63,7 @@ The workflow can only be run against long-term release branch such as `package-r
6263
* Review and merge the pull request that it creates for updating the change log in main
6364
(note that if this is not a patch release then the change log on main may already be up-to-date,
6465
in which case no pull request will be created).
66+
* Verify that a new [Github release](https://github.com/open-telemetry/opentelemetry-python-contrib/releases) has been created and that the CHANGELOGs look correct.
6567

6668
### Releasing individual package
6769

@@ -79,6 +81,14 @@ to pick a specific package to release.
7981

8082
The workflow can only be run against long-term release branch such as `package-release/{package-name}/v{major}.{minor}.x` or `package-release/{package-name}/v{major}.{minor}bx`.
8183

84+
## After the release
85+
86+
* Check PyPI
87+
* This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/release.yml).
88+
* Check the [action logs](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml) to make sure packages have been uploaded to PyPI
89+
* Check the release history (e.g. https://pypi.org/project/opentelemetry-instrumentation/#history) on PyPI
90+
* If for some reason the action failed, see [Publish failed](#publish-failed) below
91+
8292
## Notes about version numbering for stable components
8393

8494
* The version number for stable components in the `main` branch is always `X.Y.0.dev`,
@@ -110,28 +120,6 @@ The workflow can only be run against long-term release branch such as `package-r
110120
* The version number for unstable components in the `main` branch will be bumped to the next version,
111121
e.g. `0.{Y+1}b0.dev`.
112122

113-
## After the release
114-
115-
* Check PyPI
116-
* This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/release.yml).
117-
* Check the [action logs](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml) to make sure packages have been uploaded to PyPI
118-
* Check the release history (e.g. https://pypi.org/project/opentelemetry-instrumentation/#history) on PyPI
119-
* If for some reason the action failed, see [Publish failed](#publish-failed) below
120-
* Move stable tag
121-
* Run the following (TODO automate):
122-
123-
```bash
124-
git tag -d stable
125-
git tag stable
126-
git push --delete origin tagname
127-
git push origin stable
128-
```
129-
130-
* This will ensure the docs are pointing at the stable release.
131-
* To validate this worked, ensure the stable build has run successfully:
132-
<https://readthedocs.org/projects/opentelemetry-python/builds/>.
133-
If the build has not run automatically, it can be manually trigger via the readthedocs interface.
134-
135123
## Releasing dev version of new packages to claim namespace
136124

137125
When a contribution introduces a new package, in order to mitigate name-squatting incidents, release the current development version of the new package under the `opentelemetry` user to simply claim the namespace. This should be done shortly after the PR that introduced this package has been merged into `main`.

instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Add example to `opentelemetry-instrumentation-openai-v2`
11+
([#3006](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3006))
1012
- Support for `AsyncOpenAI/AsyncCompletions` ([#2984](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2984))
1113

1214
## Version 2.0b0 (2024-11-08)

instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@ OpenTelemetry OpenAI Instrumentation
66
.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-openai-v2.svg
77
:target: https://pypi.org/project/opentelemetry-instrumentation-openai-v2/
88

9-
Instrumentation with OpenAI that supports the OpenAI library and is
10-
specified to trace_integration using 'OpenAI'.
9+
This library allows tracing LLM requests and logging of messages made by the
10+
`OpenAI Python API library <https://pypi.org/project/openai/>`_.
1111

1212

1313
Installation
1414
------------
1515

16+
If your application is already instrumented with OpenTelemetry, add this
17+
package to your requirements.
1618
::
1719

1820
pip install opentelemetry-instrumentation-openai-v2
1921

22+
If you don't have an OpenAI application, yet, try our `example <example>`_
23+
which only needs a valid OpenAI API key.
2024

2125
References
2226
----------
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Update this with your real OpenAI API key
2+
OPENAI_API_KEY=sk-YOUR_API_KEY
3+
4+
# Uncomment to use Ollama instead of OpenAI
5+
# OPENAI_BASE_URL=http://localhost:11434/v1
6+
# OPENAI_API_KEY=unused
7+
# CHAT_MODEL=qwen2.5:0.5b
8+
9+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
10+
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
11+
OTEL_SERVICE_NAME=opentelemetry-python-openai
12+
13+
# Change to 'false' to disable logging
14+
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
15+
# Change to 'console' if your OTLP endpoint doesn't support logs
16+
OTEL_LOGS_EXPORTER=otlp_proto_http
17+
# Change to 'false' to hide prompt and completion content
18+
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
OpenTelemetry OpenAI Instrumentation Example
2+
============================================
3+
4+
This is an example of how to instrument OpenAI calls with zero code changes,
5+
using `opentelemetry-instrument`.
6+
7+
When `main.py <main.py>`_ is run, it exports traces and logs to an OTLP
8+
compatible endpoint. Traces include details such as the model used and the
9+
duration of the chat request. Logs capture the chat request and the generated
10+
response, providing a comprehensive view of the performance and behavior of
11+
your OpenAI requests.
12+
13+
Setup
14+
-----
15+
16+
Minimally, update the `.env <.env>`_ file with your "OPENAI_API_KEY". An
17+
OTLP compatible endpoint should be listening for traces and logs on
18+
http://localhost:4318. If not, update "OTEL_EXPORTER_OTLP_ENDPOINT" as well.
19+
20+
Next, set up a virtual environment like this:
21+
22+
::
23+
24+
python3 -m venv .venv
25+
source .venv/bin/activate
26+
pip install "python-dotenv[cli]"
27+
pip install -r requirements.txt
28+
29+
Run
30+
---
31+
32+
Run the example like this:
33+
34+
::
35+
36+
dotenv run -- opentelemetry-instrument python main.py
37+
38+
You should see a poem generated by OpenAI while traces and logs export to your
39+
configured observability tool.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import os
2+
3+
from openai import OpenAI
4+
5+
6+
def main():
7+
client = OpenAI()
8+
chat_completion = client.chat.completions.create(
9+
model=os.getenv("CHAT_MODEL", "gpt-4o-mini"),
10+
messages=[
11+
{
12+
"role": "user",
13+
"content": "Write a short poem on OpenTelemetry.",
14+
},
15+
],
16+
)
17+
print(chat_completion.choices[0].message.content)
18+
19+
20+
if __name__ == "__main__":
21+
main()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
openai~=1.54.4
2+
3+
opentelemetry-sdk~=1.28.2
4+
opentelemetry-exporter-otlp-proto-http~=1.28.2
5+
opentelemetry-distro~=0.49b2
6+
opentelemetry-instrumentation-openai-v2~=2.0b0

instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def instrument_connection(
190190
capture_parameters: bool = False,
191191
enable_commenter: bool = False,
192192
commenter_options: dict = None,
193+
connect_module: typing.Callable[..., typing.Any] = None,
193194
):
194195
"""Enable instrumentation in a database connection.
195196
@@ -204,6 +205,7 @@ def instrument_connection(
204205
capture_parameters: Configure if db.statement.parameters should be captured.
205206
enable_commenter: Flag to enable/disable sqlcommenter.
206207
commenter_options: Configurations for tags to be appended at the sql query.
208+
connect_module: Module name where connect method is available.
207209
208210
Returns:
209211
An instrumented connection.
@@ -221,6 +223,7 @@ def instrument_connection(
221223
capture_parameters=capture_parameters,
222224
enable_commenter=enable_commenter,
223225
commenter_options=commenter_options,
226+
connect_module=connect_module,
224227
)
225228
db_integration.get_connection_attributes(connection)
226229
return get_traced_connection_proxy(connection, db_integration)
@@ -492,49 +495,54 @@ def traced_execution(
492495
with self._db_api_integration._tracer.start_as_current_span(
493496
name, kind=SpanKind.CLIENT
494497
) as span:
495-
self._populate_span(span, cursor, *args)
496-
if args and self._commenter_enabled:
497-
try:
498-
args_list = list(args)
499-
500-
# lazy capture of mysql-connector client version using cursor
501-
if (
502-
self._db_api_integration.database_system == "mysql"
503-
and self._db_api_integration.connect_module.__name__
504-
== "mysql.connector"
505-
and not self._db_api_integration.commenter_data[
506-
"mysql_client_version"
507-
]
508-
):
509-
self._db_api_integration.commenter_data[
510-
"mysql_client_version"
511-
] = cursor._cnx._cmysql.get_client_info()
512-
513-
commenter_data = dict(
514-
self._db_api_integration.commenter_data
515-
)
516-
if self._commenter_options.get(
517-
"opentelemetry_values", True
518-
):
519-
commenter_data.update(**_get_opentelemetry_values())
520-
521-
# Filter down to just the requested attributes.
522-
commenter_data = {
523-
k: v
524-
for k, v in commenter_data.items()
525-
if self._commenter_options.get(k, True)
526-
}
527-
statement = _add_sql_comment(
528-
args_list[0], **commenter_data
529-
)
530-
531-
args_list[0] = statement
532-
args = tuple(args_list)
533-
534-
except Exception as exc: # pylint: disable=broad-except
535-
_logger.exception(
536-
"Exception while generating sql comment: %s", exc
537-
)
498+
if span.is_recording():
499+
if args and self._commenter_enabled:
500+
try:
501+
args_list = list(args)
502+
503+
# lazy capture of mysql-connector client version using cursor
504+
if (
505+
self._db_api_integration.database_system == "mysql"
506+
and self._db_api_integration.connect_module.__name__
507+
== "mysql.connector"
508+
and not self._db_api_integration.commenter_data[
509+
"mysql_client_version"
510+
]
511+
):
512+
self._db_api_integration.commenter_data[
513+
"mysql_client_version"
514+
] = cursor._cnx._cmysql.get_client_info()
515+
516+
commenter_data = dict(
517+
self._db_api_integration.commenter_data
518+
)
519+
if self._commenter_options.get(
520+
"opentelemetry_values", True
521+
):
522+
commenter_data.update(
523+
**_get_opentelemetry_values()
524+
)
525+
526+
# Filter down to just the requested attributes.
527+
commenter_data = {
528+
k: v
529+
for k, v in commenter_data.items()
530+
if self._commenter_options.get(k, True)
531+
}
532+
statement = _add_sql_comment(
533+
args_list[0], **commenter_data
534+
)
535+
536+
args_list[0] = statement
537+
args = tuple(args_list)
538+
539+
except Exception as exc: # pylint: disable=broad-except
540+
_logger.exception(
541+
"Exception while generating sql comment: %s", exc
542+
)
543+
544+
self._populate_span(span, cursor, *args)
545+
538546
return query_method(*args, **kwargs)
539547

540548

0 commit comments

Comments
 (0)