opentelemetry-python icon indicating copy to clipboard operation
opentelemetry-python copied to clipboard

“pkg_resources.DistributionNotFound: The 'opentelemetry-sdk' distribution was not found” error when packed by PyInstaller

Open LronDC opened this issue 2 years ago • 3 comments

Describe your environment Python 3.6.8 | Opentelemery-sdk 1.9.1

Steps to reproduce I create a image through dockerfile, pseudo code:

...
RUN pip install pip==19.0.1 virtualenv==16.1.0 virtualenv-clone==0.4.0 setuptools==39.0.1
RUN pip install --no-use-pep517 pyinstaller
RUN pip install -r requirements.txt
...
RUN pyinstaller  --onefile myprogram.spec

requirements.txt:

...
opentelemetry-api==1.9.1
opentelemetry-sdk==1.9.1
opentelemetry-exporter-otlp==1.9.1
...

myprogram.spec:

path = os.path.dirname('__file__')

def gen_key(length=16):
    from random import choice
    numbers = "0123456789"
    letters = "sgmqwerqwerpoiupoiu"
    chars = "".join(numbers + letters + letters.upper())
    return ''.join(choice(chars) for _ in range(length))

block_cipher = pyi_crypto.PyiBlockCipher(key=gen_key())

a = Analysis(['app/app_runner.py'],
             pathex=[path],
             hiddenimports=['pymysql', 'logging.config', 'app.app_runner','sqlalchemy.ext.baked', 'gunicorn.glogging',
             'gunicorn.workers.sync', 'gunicorn.workers.ggevent'],
             hookspath=None,
             cipher=block_cipher)

pyz = PYZ(a.pure)

exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [

          ],
          name='myprogram',
          debug=False,
          strip=None,
          upx=False,
          console=True )

then when I execute 'myprogram' which pyinstaller gave me, I got image well the program can not run. I just newly added opentelemetry to my program, before this it runs correctly. What is the expected behavior? I want to know why and how to fix it.

LronDC avatar Mar 09 '22 07:03 LronDC

Not sure if this is related to OpenTelemetry. Have you tried adding another package as well? From this issue, it seems like some hooks may be missing to your application.

ocelotl avatar Mar 17 '22 20:03 ocelotl

@LronDC Are you still facing the issue? What is that opentelemetry missing that should be added to fix this? or it's just not really related?

srikanthccv avatar Jun 25 '22 02:06 srikanthccv

That's the issue of missing hooks for PyInstaller which are the way to adapt PyInstaller to different ways of using Python modules. opentelemetry relies on package metadata (entry_points.txt within the *.dist-info folders) of installed opentelemetry component packages (e.g. api, sdk, various exporters and instrumentations) to find different pieces to activate. And in some use cases, those metadata may be needed to lookup components specified via numerous environment variables opentelemetry uses for runtime configuration.
So I ended up with the central hook for api:

# hook-opentelemetry.py
from PyInstaller.utils.hooks import collect_submodules, copy_metadata
hiddenimports = collect_submodules('opentelemetry')
datas = copy_metadata("opentelemetry_api", recursive=True)

and a hook per imported package e.g.:

# hook-opentelemetry.sdk.py
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata("opentelemetry_sdk", recursive=True)
# hook-opentelemetry.exporter.otlp.proto.grpc.py
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata("opentelemetry_exporter_otlp_proto_grpc", recursive=True)

This way you can either import a component directly or specify a corresponding "hiddenimport" if a component is expected to be activated via an environment variable.

mr2dark avatar Aug 12 '22 14:08 mr2dark

Sorry to catch up so late. @ocelotl @srikanthccv You are right it's not really related to OTEL, it's PyInstaller's issue like @mr2dark commented(which is so great). I'll close this issue here. THANK YOU guys.

LronDC avatar Aug 15 '22 09:08 LronDC