Skip to content

Commit d87a8c5

Browse files
authored
More intelligent package loading semantics (#155)
* Don't load for all processes; More helpful debug boot msgs * Assure recorder is a singleton * Update Python versions * Add direct execution mode; Add info screen * Update Circle Python version and workflow * Expand DNL list * Update copyright year * Move version to metadata section
1 parent 8178ba0 commit d87a8c5

File tree

5 files changed

+94
-28
lines changed

5 files changed

+94
-28
lines changed

.circleci/config.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
#
55
version: 2
66
jobs:
7-
build:
7+
build-test-python36:
88
docker:
9-
# specify the version you desire here
10-
# use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers`
11-
- image: circleci/python:3.6.1
9+
- image: circleci/python:3.6.8
1210

1311
# Specify service dependencies here if necessary
1412
# CircleCI maintains a library of pre-built images
@@ -33,7 +31,7 @@ jobs:
3331
- run:
3432
name: install dependencies
3533
command: |
36-
python3 -m venv venv
34+
python -m venv venv
3735
. venv/bin/activate
3836
pip install -U pip
3937
python setup.py install_egg_info
@@ -54,3 +52,8 @@ jobs:
5452
- store_artifacts:
5553
path: test-reports
5654
destination: test-reports
55+
workflows:
56+
version: 2
57+
build:
58+
jobs:
59+
- build-test-python36

instana/__init__.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@
2424
from threading import Timer
2525
import pkg_resources
2626

27-
28-
if "INSTANA_MAGIC" in os.environ:
29-
pkg_resources.working_set.add_entry("/tmp/instana/python")
30-
3127
__author__ = 'Instana Inc.'
32-
__copyright__ = 'Copyright 2018 Instana Inc.'
28+
__copyright__ = 'Copyright 2019 Instana Inc.'
3329
__credits__ = ['Pavlo Baron', 'Peter Giacomo Lombardo']
3430
__license__ = 'MIT'
3531
__maintainer__ = 'Peter Giacomo Lombardo'
@@ -47,14 +43,7 @@ def load(_):
4743
environment variable.
4844
"""
4945
if "INSTANA_DEBUG" in os.environ:
50-
print("==========================================================")
51-
print("Instana: Loading...")
52-
print("==========================================================")
53-
54-
55-
# User configurable EUM API key for instana.helpers.eum_snippet()
56-
# pylint: disable=invalid-name
57-
eum_api_key = ''
46+
print("Instana: activated via AUTOWRAPT_BOOTSTRAP")
5847

5948

6049
def boot_agent():
@@ -83,8 +72,36 @@ def boot_agent():
8372

8473

8574
if "INSTANA_MAGIC" in os.environ:
86-
# If we're being loaded into an already running process, then delay agent initialization
87-
t = Timer(3.0, boot_agent)
88-
t.start()
75+
pkg_resources.working_set.add_entry("/tmp/instana/python")
76+
77+
if "INSTANA_DEBUG" in os.environ:
78+
print("Instana: activated via AutoTrace")
79+
else:
80+
if ("INSTANA_DEBUG" in os.environ) and ("AUTOWRAPT_BOOTSTRAP" not in os.environ):
81+
print("Instana: activated via manual import")
82+
83+
# User configurable EUM API key for instana.helpers.eum_snippet()
84+
# pylint: disable=invalid-name
85+
eum_api_key = ''
86+
87+
# This Python package can be loaded into Python processes one of three ways:
88+
# 1. manual import statement
89+
# 2. autowrapt hook
90+
# 3. dynamically injected remotely
91+
#
92+
# With such magic, we may get pulled into Python processes that we have no interest being in.
93+
# As a safety measure, we maintain a "do not load list" and if this process matches something
94+
# in that list, then we go sit in a corner quietly and don't load anything at all.
95+
do_not_load_list = ["pip", "pip2", "pip3", "pipenv", "docker-compose", "easy_install", "easy_install-2.7",
96+
"smtpd.py", "ufw", "unattended-upgrade"]
97+
98+
if os.path.basename(sys.argv[0]) in do_not_load_list:
99+
if "INSTANA_DEBUG" in os.environ:
100+
print("Instana: No use in monitoring this process type (%s). Will go sit in a corner quietly.", sys.argv[0])
89101
else:
90-
boot_agent()
102+
if "INSTANA_MAGIC" in os.environ:
103+
# If we're being loaded into an already running process, then delay agent initialization
104+
t = Timer(3.0, boot_agent)
105+
t.start()
106+
else:
107+
boot_agent()

instana/__main__.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
print("""\
2+
============================================================================
3+
8888888 888b 888 .d8888b. 88888888888 d8888 888b 888 d8888
4+
888 8888b 888 d88P Y88b 888 d88888 8888b 888 d88888
5+
888 88888b 888 Y88b. 888 d88P888 88888b 888 d88P888
6+
888 888Y88b 888 "Y888b. 888 d88P 888 888Y88b 888 d88P 888
7+
888 888 Y88b888 "Y88b. 888 d88P 888 888 Y88b888 d88P 888
8+
888 888 Y88888 "888 888 d88P 888 888 Y88888 d88P 888
9+
888 888 Y8888 Y88b d88P 888 d8888888888 888 Y8888 d8888888888
10+
8888888 888 Y888 "Y8888P" 888 d88P 888 888 Y888 d88P 888
11+
============================================================================
12+
13+
This is an informational screen for Instana.
14+
15+
See the Instana Python documentation for details on using this package with
16+
your Python applications, workers, queues and more.
17+
18+
19+
Related Blog Posts:
20+
============================================================================
21+
22+
Monitoring Python with Instana
23+
https://www.instana.com/blog/monitoring-python-instana/
24+
25+
Zero-Effort, Fully Automatic Distributed Tracing for Python
26+
https://www.instana.com/blog/zero-effort-fully-automatic-distributed-tracing-for-python/
27+
28+
29+
Helpful Links
30+
============================================================================
31+
32+
Monitoring Python Documentation:
33+
https://docs.instana.io/ecosystem/python
34+
35+
Help & Support:
36+
https://support.instana.com/hc/en-us
37+
38+
Python Instrumentation on Github:
39+
https://github.com/instana/python-sensor/
40+
""")

instana/singletons.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import opentracing
33

44
from .agent import Agent
5-
from .tracer import InstanaTracer
5+
from .tracer import InstanaTracer, InstanaRecorder
66

77
from distutils.version import LooseVersion
88

@@ -11,6 +11,8 @@
1111
agent = Agent()
1212

1313

14+
span_recorder = InstanaRecorder()
15+
1416
# The global OpenTracing compatible tracer used internally by
1517
# this package.
1618
#
@@ -19,11 +21,11 @@
1921
# import instana
2022
# instana.tracer.start_span(...)
2123
#
22-
tracer = InstanaTracer()
24+
tracer = InstanaTracer(recorder=span_recorder)
2325

2426
if sys.version_info >= (3,4):
2527
from opentracing.scope_managers.asyncio import AsyncioScopeManager
26-
async_tracer = InstanaTracer(scope_manager=AsyncioScopeManager())
28+
async_tracer = InstanaTracer(scope_manager=AsyncioScopeManager(), recorder=span_recorder)
2729

2830

2931
# Mock the tornado tracer until tornado is detected and instrumented first
@@ -33,7 +35,7 @@
3335
def setup_tornado_tracer():
3436
global tornado_tracer
3537
from opentracing.scope_managers.tornado import TornadoScopeManager
36-
tornado_tracer = InstanaTracer(scope_manager=TornadoScopeManager())
38+
tornado_tracer = InstanaTracer(scope_manager=TornadoScopeManager(), recorder=span_recorder)
3739

3840

3941
# Set ourselves as the tracer.

instana/tracer.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818

1919

2020
class InstanaTracer(BasicTracer):
21-
def __init__(self, options=Options(), scope_manager=None):
21+
def __init__(self, options=Options(), scope_manager=None, recorder=None):
22+
23+
if recorder is None:
24+
recorder = InstanaRecorder()
25+
2226
super(InstanaTracer, self).__init__(
23-
InstanaRecorder(), InstanaSampler(), scope_manager)
27+
recorder, InstanaSampler(), scope_manager)
2428

2529
self._propagators[ot.Format.HTTP_HEADERS] = HTTPPropagator()
2630
self._propagators[ot.Format.TEXT_MAP] = TextPropagator()

0 commit comments

Comments
 (0)