def prefork_handler()

in skywalking/bootstrap/cli/utility/runner.py [0:0]


def prefork_handler(command: List[str]) -> None:
    """
    This handles the cases where pre-forking servers are EXPLICITLY used:
    - gunicorn
    - uwsgi
    This handler only covers many plain usages, there could be cases where
    gunicorn/uwsgi is loaded by other scripts and the envvars used here
    are lost in such flow. (Aka. not covered by this handler)
    """
    os.environ['prefork'] = ''
    if command[0] == 'gunicorn':
        # Maybe should also check 1: since there could be a command before gunicorn
        cli_logger.info('We noticed you are using Gunicorn, '
                        'agent will automatically start the SkyWalking Python Agent'
                        'in all child (worker) processes and the master.')
        os.environ['prefork'] = 'gunicorn'
    elif command[0] == 'uwsgi':
        cli_logger.info('We noticed you are using uWSGI, '
                        'agent will automatically add the following '
                        'environment variables to your uWSGI options (to ensure a functional Python agent): '
                        '--enable-threads --master. \n'
                        'We will also start the SkyWalking Python Agent in all child (worker) '
                        'processes except for the master.')

        if '--master' not in command[1:]:
            cli_logger.warning('No master process is specified, '
                               'agent will not start properly in workers, '
                               'automatically adding --master to your uwsgi command.')
            os.environ['UWSGI_MASTER'] = 'true'

        if '--enable-threads' not in command[1:]:
            ...
            cli_logger.warning('No --enable-threads is specified, '
                               'agent will not start properly in workers, '
                               'automatically adding --enable-threads to your uwsgi command.')
            os.environ['UWSGI_ENABLE_THREADS'] = 'true'

        # this sets the option --import to our custom uwsgidecorator.postfork() function
        # which is in loader/uw.py
        os.environ['prefork'] = 'uwsgi'

        # let's hope no one uses up all 4 env variables, shared-python-import
        # shared-import, shared-pyimport, shared-py-import all imports in all processes no matter lazy/lazy-apps
        def pick_env_var():
            for env_var in ['UWSGI_SHARED_PYTHON_IMPORT',
                            'UWSGI_SHARED_IMPORT',
                            'UWSGI_SHARED_PYIMPORT',
                            'UWSGI_SHARED_PY_IMPORT']:
                if env_var not in os.environ:
                    return env_var
            raise SWRunnerFailure('No available env variable slot for sw-python to inject postfork hook, '
                                  'agent will not start properly in workers, please unset one of your env variables or '
                                  'fall back to manual postfork hook with @postfork.')

        os.environ[pick_env_var()] = 'uwsgi_hook'