newrelic-python-agent icon indicating copy to clipboard operation
newrelic-python-agent copied to clipboard

Conflict dependencies chroma db and opentelemetry-proto

Open anaclaramatos opened this issue 1 year ago • 2 comments

Conflict dependencies chroma db and opentelemetry-proto.

Description

When trying to run a project with newrelic and chroma db the following error is thrown:

ERROR collecting tests/controllers/test_features_controller.py
(...)
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*opentelemetry/proto/common/v1/common.proto\(...)
TypeError: Couldn't build proto file into descriptor pool: duplicate file name opentelemetry/proto/common/v1/common.proto

The error is thrown because the following files are different:

  • venv/lib/python3.10/site-packages/newrelic/packages/opentelemetry_proto/common_pb2.py
  • venv/lib/python3.10/site-packages/opentelemetry/proto/common/v1/common_pb2.py

newrelic is using opentelemetry-proto==1.0.0 and chromadb uses opentelemetry-proto==1.24.0

Your Environment

newrelic==9.10.0 chromadb==0.4.24 opentelemetry-proto==1.24.0

Additional context

Stack trace:

===================================================================================== ERRORS ======================================================================================
_________________________________________________________ ERROR collecting tests/controllers/test_features_controller.py __________________________________________________________
tests/controllers/test_features_controller.py:8: in <module>
  from api.main import app
api/main.py:12: in <module>
  from api.cc_agent import CCAgentController
api/cc_agent/__init__.py:1: in <module>
  from api.cc_agent.config import (
api/cc_agent/config.py:2: in <module>
  from cc_agent.chat_model import AzureOpenAIEngine
../ai-cc-agent/cc_agent/chat_model.py:4: in <module>
  import chromadb
venv/lib/python3.10/site-packages/chromadb/__init__.py:5: in <module>
  from chromadb.auth.token import TokenTransportHeader
venv/lib/python3.10/site-packages/chromadb/auth/token/__init__.py:26: in <module>
  from chromadb.telemetry.opentelemetry import (
venv/lib/python3.10/site-packages/chromadb/telemetry/opentelemetry/__init__.py:11: in <module>
  from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
venv/lib/python3.10/site-packages/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py:24: in <module>
  from opentelemetry.exporter.otlp.proto.common.trace_encoder import (
venv/lib/python3.10/site-packages/opentelemetry/exporter/otlp/proto/common/trace_encoder.py:16: in <module>
  from opentelemetry.exporter.otlp.proto.common._internal.trace_encoder import (
venv/lib/python3.10/site-packages/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py:31: in <module>
  from opentelemetry.proto.common.v1.common_pb2 import (
venv/lib/python3.10/site-packages/opentelemetry/proto/common/v1/common_pb2.py:17: in <module>
  DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*opentelemetry/proto/common/v1/common.proto\x12\x1dopentelemetry.proto.common.v1\"\x8c\x02\n\x08\x41nyValue\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12@\n\x0b\x61rray_value\x18\x05 \x01(\x0b\x32).opentelemetry.proto.common.v1.ArrayValueH\x00\x12\x43\n\x0ckvlist_value\x18\x06 \x01(\x0b\x32+.opentelemetry.proto.common.v1.KeyValueListH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x42\x07\n\x05value\"E\n\nArrayValue\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\"G\n\x0cKeyValueList\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\"O\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\"\x94\x01\n\x14InstrumentationScope\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12;\n\nattributes\x18\x03 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x04 \x01(\rB{\n io.opentelemetry.proto.common.v1B\x0b\x43ommonProtoP\x01Z(go.opentelemetry.io/proto/otlp/common/v1\xaa\x02\x1dOpenTelemetry.Proto.Common.V1b\x06proto3')
E  TypeError: Couldn't build proto file into descriptor pool: duplicate file name opentelemetry/proto/common/v1/common.proto

anaclaramatos avatar May 29 '24 19:05 anaclaramatos

https://new-relic.atlassian.net/browse/NR-274826

This is going to sound a little weird but try adding the following to the top level file in your program:

import newrelic.agent
settings = newrelic.agent.global_settings()
settings.debug.otlp_content_encoding = "json"

The otlp is only used for instrumenting sklearn right now so as long as you aren't using that/wanting that instrumentation you should be ok to disable the agent from using otlp/using json instead (this should prevent that conflict of building that proto file with the same name).

hmstepanek avatar Jun 10 '24 23:06 hmstepanek

The workaround above doesn't seem to work. Here's a minimal repro:

import newrelic.agent
settings = newrelic.agent.global_settings()
settings.debug.otlp_content_encoding = "json"
import opentelemetry.exporter.otlp.proto.http.metric_exporter
Traceback (most recent call last):
  File "/Users/alex/Library/Application Support/JetBrains/PyCharm2024.2/scratches/scratch_490.py", line 4, in <module>
    import opentelemetry.exporter.otlp.proto.http.metric_exporter
  File "/Users/alex/work/logfire/.venv/lib/python3.12/site-packages/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py", line 25, in <module>
    from opentelemetry.exporter.otlp.proto.common._internal import (
  File "/Users/alex/work/logfire/.venv/lib/python3.12/site-packages/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py", line 31, in <module>
    from opentelemetry.proto.common.v1.common_pb2 import (
  File "/Users/alex/work/logfire/.venv/lib/python3.12/site-packages/opentelemetry/proto/common/v1/common_pb2.py", line 17, in <module>
    DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*opentelemetry/proto/common/v1/common.proto\x12\x1dopentelemetry.proto.common.v1\"\x8c\x02\n\x08\x41nyValue\x12\x16\n\x0cstr...
TypeError: Couldn't build proto file into descriptor pool: duplicate file name opentelemetry/proto/common/v1/common.proto

Does this issue being closed mean that it's fixed somewhere but not released yet?

alexmojaki avatar Sep 12 '24 13:09 alexmojaki

@alexmojaki I ran into the same issue. Were you able to find a fix?

File "/home/USER_NAME/PycharmProjects/PROJECT_NAME_PLACEHOLDER/.venv/lib/python3.10/site-packages/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/init.py", line 24, in from opentelemetry.exporter.otlp.proto.common.trace_encoder import ( File "/home/USER_NAME/PycharmProjects/PROJECT_NAME_PLACEHOLDER/.venv/lib/python3.10/site-packages/opentelemetry/exporter/otlp/proto/common/trace_encoder.py", line 16, in from opentelemetry.exporter.otlp.proto.common._internal.trace_encoder import ( File "/home/USER_NAME/PycharmProjects/PROJECT_NAME_PLACEHOLDER/.venv/lib/python3.10/site-packages/opentelemetry/exporter/otlp/proto/common/_internal/init.py", line 31, in from opentelemetry.proto.common.v1.common_pb2 import ( File "/home/USER_NAME/PycharmProjects/PROJECT_NAME_PLACEHOLDER/.venv/lib/python3.10/site-packages/opentelemetry/proto/common/v1/common_pb2.py", line 17, in DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*opentelemetry/proto/common/v1/common.proto\x12\x1dopentelemetry.proto.common.v1"\x8c\x02\n\x08\x41nyValue\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12@\n\x0b\x61rray_value\x18\x05 \x01(\x0b\x32).opentelemetry.proto.common.v1.ArrayValueH\x00\x12\x43\n\x0ckvlist_value\x18\x06 \x01(\x0b\x32+.opentelemetry.proto.common.v1.KeyValueListH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x42\x07\n\x05value"E\n\nArrayValue\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32'.opentelemetry.proto.common.v1.AnyValue"G\n\x0cKeyValueList\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32'.opentelemetry.proto.common.v1.KeyValue"O\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32'.opentelemetry.proto.common.v1.AnyValue"\x94\x01\n\x14InstrumentationScope\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12;\n\nattributes\x18\x03 \x03(\x0b\x32'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x04 \x01(\rB{\n io.opentelemetry.proto.common.v1B\x0b\x43ommonProtoP\x01Z(go.opentelemetry.io/proto/otlp/common/v1\xaa\x02\x1dOpenTelemetry.Proto.Common.V1b\x06proto3') TypeError: Couldn't build proto file into descriptor pool: duplicate file name opentelemetry/proto/common/v1/common.proto

is there a fix for this

venkata-mi avatar Sep 13 '24 15:09 venkata-mi

@anaclaramatos, @alexmojaki

I found a work around for this. I'm creating a different descriptor pool before initializing or importing chroma

from google.protobuf import descriptor_pool as _descriptor_pool

custom_pool = _descriptor_pool.DescriptorPool()
_descriptor_pool._DEFAULT = custom_pool

This would put the protobuf in a separate pool and resolve the conflict.

this might impact the telemetry of the chromadb. Needs testing.

venkata-mi avatar Sep 13 '24 15:09 venkata-mi

I just ran into this and the workaround to switch to json encoding does work but you need to import global_settings() directly from newrelic.core.config instead of via import newrelic.

import newrelic performs a chain of imports that leads to the common_pb2 protobuf getting imported and loaded, so the damage will already be done before the encoding setting is configured.

This worked for me:

from newrelic.core.config import global_settings
settings = global_settings()
settings.debug.otlp_content_encoding = "json"

ian-lmcb avatar Nov 15 '24 20:11 ian-lmcb

Hey! Any plans on having a proper fix for this? The workaround mentioned works but having to put it in multiple places of my code right now.

williamlac avatar Feb 06 '25 09:02 williamlac

Setting the env var PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python seems to prevent the error, although I don't know what the implications of this are.

alexmojaki avatar Feb 06 '25 12:02 alexmojaki

Any fix for this yet? Disabling NewRelic in Production helped with this, but obviously isn't a solution. Not sure why this was closed - clearly it's still happening on the latest versions. Full list of dependencies for us:

aiohappyeyeballs==2.6.1
aiohttp==3.11.14
aiosignal==1.3.2
amazon-textract-caller==0.2.4
amazon-textract-response-parser==1.0.3
amazon-textract-textractor==1.9.0
amqp==5.3.1
annotated-types==0.7.0
anyio==4.9.0
appdirs==1.4.4
asgiref==3.8.1
asttokens==3.0.0
attrs==25.3.0
auth0-python==4.8.1
backoff==2.2.1
bcrypt==4.3.0
billiard==4.2.1
blinker==1.9.0
boto3==1.37.15
botocore==1.37.15
build==1.2.2.post1
cachetools==5.5.2
celery==5.4.0
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
chroma-hnswlib==0.7.6
chromadb==0.6.3
click==8.1.8
click-didyoumean==0.3.1
click-plugins==1.1.1
click-repl==0.3.0
coloredlogs==15.0.1
crewai==0.108.0
cryptography==44.0.2
CurrencyConverter @ git+https://github.com/alexprengere/currencyconverter.git@932d1316ba4578032896f5156fa91dbb602f6402
dataclasses-json==0.6.7
decorator==5.2.1
Deprecated==1.2.18
distro==1.9.0
dj-database-url==2.3.0
Django==5.1.7
django-anymail==12.0
django-cors-headers==4.7.0
django-filter==25.1
django-storages==1.14.5
djangorestframework==3.15.2
docstring_parser==0.16
durationpy==0.9
editdistance==0.8.1
enum-compat==0.0.3
et_xmlfile==2.0.0
executing==2.2.0
fastapi==0.115.11
filelock==3.18.0
flatbuffers==25.2.10
frozenlist==1.5.0
fsspec==2025.3.0
google-api-core==2.24.2
google-auth==2.38.0
google-cloud-bigquery==3.30.0
google-cloud-core==2.4.3
google-cloud-storage==3.1.0
google-crc32c==1.7.0
google-resumable-media==2.7.2
googleapis-common-protos==1.69.2
greenlet==3.1.1
grpcio==1.71.0
grpcio-status==1.71.0
gunicorn==23.0.0
h11==0.14.0
httpcore==1.0.7
httptools==0.6.4
httpx==0.27.2
httpx-sse==0.4.0
huggingface-hub==0.29.3
humanfriendly==10.0
idna==3.10
importlib_metadata==8.5.0
importlib_resources==6.5.2
instructor==1.7.7
intuit-oauth==1.2.6
ipython==9.0.2
ipython_pygments_lexers==1.1.1
jedi==0.19.2
Jinja2==3.1.6
jiter==0.8.2
jmespath==1.0.1
josepy==2.0.0
json5==0.10.0
json_repair==0.39.1
jsonpatch==1.33
jsonpickle==4.0.2
jsonpointer==3.0.0
jsonref==1.1.0
jsonschema==4.23.0
jsonschema-specifications==2024.10.1
kombu==5.5.0
kubernetes==32.0.1
langchain==0.3.20
langchain-community==0.3.19
langchain-core==0.3.45
langchain-openai==0.3.9
langchain-text-splitters==0.3.7
langfuse==2.60.0
langsmith==0.3.15
Levenshtein==0.27.1
litellm==1.60.2
markdown-it-py==3.0.0
markdown2==2.5.3
MarkupSafe==3.0.2
marshmallow==3.26.1
matplotlib-inline==0.1.7
mdurl==0.1.2
mmh3==5.1.0
monotonic==1.6
mozilla-django-oidc==4.0.1
mpmath==1.3.0
multidict==6.2.0
mypy-extensions==1.0.0
networkx==3.4.2
newrelic==10.7.0
nulltype==2.3.1
numpy==2.2.4
oauthlib==3.2.2
onnxruntime==1.21.0
openai==1.66.3
openpyxl==3.1.5
opentelemetry-api==1.29.0
opentelemetry-exporter-otlp-proto-common==1.29.0
opentelemetry-exporter-otlp-proto-grpc==1.29.0
opentelemetry-exporter-otlp-proto-http==1.29.0
opentelemetry-instrumentation==0.50b0
opentelemetry-instrumentation-asgi==0.50b0
opentelemetry-instrumentation-fastapi==0.50b0
opentelemetry-proto==1.29.0
opentelemetry-sdk==1.29.0
opentelemetry-semantic-conventions==0.50b0
opentelemetry-util-http==0.50b0
orjson==3.10.15
overrides==7.7.0
packaging==24.2
pandas==2.2.3
parso==0.8.4
pdfminer.six==20231228
pdfplumber==0.11.5
pexpect==4.9.0
pillow==11.1.0
plaid-python==29.1.0
posthog==3.21.0
prompt_toolkit==3.0.50
propcache==0.3.0
proto-plus==1.26.1
protobuf==5.29.3
psycopg2==2.9.10
ptyprocess==0.7.0
pure_eval==0.2.3
pyasn1==0.6.1
pyasn1_modules==0.4.1
pycparser==2.22
pydantic==2.10.6
pydantic-settings==2.8.1
pydantic_core==2.27.2
Pygments==2.19.1
PyJWT==2.10.1
pypdfium2==4.30.1
PyPika==0.48.9
pyproject_hooks==1.2.0
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-Levenshtein==0.27.1
python-quickbooks==0.9.11
python-redis-lock==4.0.0
pytz==2025.1
pyvis==0.3.2
PyYAML==6.0.2
RapidFuzz==3.12.2
redis==5.2.1
referencing==0.36.2
regex==2024.11.6
requests==2.32.3
requests-oauthlib==2.0.0
requests-toolbelt==1.0.0
rich==13.9.4
rpds-py==0.23.1
rsa==4.9
s3transfer==0.11.4
sentry-sdk==2.23.1
setuptools==70.3.0
shellingham==1.5.4
six==1.17.0
sniffio==1.3.1
SQLAlchemy==2.0.39
sqlparse==0.5.3
stack-data==0.6.3
starlette==0.46.1
stripe==11.6.0
sympy==1.13.3
tabulate==0.9.0
tenacity==9.0.0
thefuzz==0.22.1
tiktoken==0.9.0
tokenizers==0.21.1
tomli==2.2.1
tomli_w==1.2.0
tqdm==4.67.1
traitlets==5.14.3
typer==0.15.2
typing-inspect==0.9.0
typing_extensions==4.12.2
tzdata==2025.1
urllib3==2.3.0
uv==0.6.8
uvicorn==0.34.0
uvloop==0.21.0
vine==5.1.0
watchdog==6.0.0
watchfiles==1.0.4
wcwidth==0.2.13
websocket-client==1.8.0
websockets==15.0.1
wheel==0.45.1
wrapt==1.17.2
XlsxWriter==3.2.2
yarl==1.18.3
zipp==3.21.0
zstandard==0.23.0

tspecht avatar Mar 19 '25 14:03 tspecht