in skywalking/agent/__init__.py [0:0]
def start(self) -> None:
"""
Start would be called by user or os.register_at_fork() callback
Start will proceed if and only if the agent is not started in the
current process.
When os.fork(), the service instance should be changed to a new one by appending pid.
"""
loggings.init()
if sys.version_info < (3, 7):
# agent may or may not work for Python 3.6 and below
# since 3.6 is EOL, we will not officially support it
logger.warning('SkyWalking Python agent does not support Python 3.6 and below, '
'please upgrade to Python 3.7 or above.')
# Below is required for grpcio to work with fork()
# https://github.com/grpc/grpc/blob/master/doc/fork_support.md
if config.agent_protocol == 'grpc' and config.agent_experimental_fork_support:
python_major_version: tuple = sys.version_info[:2]
if python_major_version == (3, 7):
logger.warning('gRPC fork support may cause hanging on Python 3.7 '
'when used together with gRPC and subprocess lib'
'See: https://github.com/grpc/grpc/issues/18075.'
'Please consider upgrade to Python 3.8+, '
'or use HTTP/Kafka protocol, or disable experimental fork support '
'if your application did not start successfully.')
os.environ['GRPC_ENABLE_FORK_SUPPORT'] = 'true'
os.environ['GRPC_POLL_STRATEGY'] = 'poll'
if not self.__started:
# if not already started, start the agent
config.finalize() # Must be finalized exactly once
self.__started = True
logger.info(f'SkyWalking agent instance {config.agent_instance_name} starting in pid-{os.getpid()}.')
# Install log reporter core
# TODO - Add support for printing traceID/ context in logs
if config.agent_log_reporter_active:
from skywalking import log
log.install()
# Here we install all other lib plugins on first time start (parent process)
plugins.install()
elif self.__started and os.getpid() == self.started_pid:
# if already started, and this is the same process, raise an error
raise RuntimeError('SkyWalking Python agent has already been started in this process, '
'did you call start more than once in your code + sw-python CLI? '
'If you already use sw-python CLI, you should remove the manual start(), vice versa.')
# Else there's a new process (after fork()), we will restart the agent in the new process
self.started_pid = os.getpid()
flag = False
try:
from gevent import monkey
flag = monkey.is_module_patched('socket')
except ModuleNotFoundError:
logger.debug("it was found that no gevent was used, if you don't use, please ignore.")
if flag:
import grpc.experimental.gevent as grpc_gevent
grpc_gevent.init_gevent()
if config.agent_profile_active:
profile.init()
if config.agent_meter_reporter_active:
meter.init(force=True) # force re-init after fork()
self.__bootstrap() # calls init_threading
atexit.register(self.__fini)
if config.agent_experimental_fork_support:
if hasattr(os, 'register_at_fork'):
os.register_at_fork(before=self.__fork_before, after_in_parent=self.__fork_after_in_parent,
after_in_child=self.__fork_after_in_child)