Skip to content

Commit be3f0f7

Browse files
authored
Better boot behaviour; Respect load dynamics (#98)
* Better boot behaviour: - Longer delay before attempting host agent discovery - Clean-up and add start methods hooked to a Timer * Function documentation * If being loaded dynamically, delay instrumentation load
1 parent 0855b88 commit be3f0f7

File tree

5 files changed

+41
-18
lines changed

5 files changed

+41
-18
lines changed

instana/__init__.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import pkg_resources
5+
from threading import Timer
56

67

78
"""
@@ -54,9 +55,18 @@ def load(module):
5455

5556
import instana.singletons #noqa
5657

57-
if "INSTANA_DISABLE_AUTO_INSTR" not in os.environ:
58-
# Import & initialize instrumentation
59-
from .instrumentation import urllib3 # noqa
60-
from .instrumentation import sudsjurko # noqa
61-
from .instrumentation import mysqlpython # noqa
62-
from .instrumentation.django import middleware # noqa
58+
def load_instrumentation():
59+
if "INSTANA_DISABLE_AUTO_INSTR" not in os.environ:
60+
# Import & initialize instrumentation
61+
from .instrumentation import urllib3 # noqa
62+
from .instrumentation import sudsjurko # noqa
63+
from .instrumentation import mysqlpython # noqa
64+
from .instrumentation.django import middleware # noqa
65+
66+
if "INSTANA_MAGIC" in os.environ:
67+
# If we're being loaded into an already running process, then delay
68+
# instrumentation load.
69+
t = Timer(2.0, load_instrumentation)
70+
t.start()
71+
else:
72+
load_instrumentation()

instana/agent.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
import threading
66
from datetime import datetime
77

8-
from .log import logger
8+
import instana.singletons
9+
910
from .agent_const import AGENT_DEFAULT_HOST, AGENT_DEFAULT_PORT
1011
from .fsm import Fsm
12+
from .log import logger
1113
from .sensor import Sensor
12-
import instana.singletons
1314

1415
try:
1516
import urllib.request as urllib2
@@ -52,6 +53,12 @@ def __init__(self):
5253
self.sensor = Sensor(self)
5354
self.fsm = Fsm(self)
5455

56+
def start(self, e):
57+
""" Starts the agent and required threads """
58+
logger.debug("Spawning metric & trace reporting threads")
59+
self.sensor.meter.run()
60+
instana.singletons.tracer.recorder.run()
61+
5562
def to_json(self, o):
5663
try:
5764
return json.dumps(o, default=lambda o: {k.lower(): v for k, v in o.__dict__.items()},
@@ -125,6 +132,7 @@ def full_request_response(self, url, method, o, body, header):
125132

126133
if method == "HEAD":
127134
b = True
135+
# logger.warn("%s %s --> response: %s" % (method, url, b))
128136
except Exception as e:
129137
# No need to show the initial 404s or timeouts. The agent
130138
# should handle those correctly.

instana/fsm.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ def __init__(self, agent):
6464
"callbacks": {
6565
"onlookup": self.lookup_agent_host,
6666
"onannounce": self.announce_sensor,
67-
"onready": self.start_metric_reporting,
67+
"onready": self.agent.start,
6868
"onchangestate": self.printstatechange}})
6969

70-
timer = t.Timer(2, self.fsm.lookup)
71-
timer.daemon = True
72-
timer.name = "Startup"
73-
timer.start()
70+
self.timer = t.Timer(5, self.fsm.lookup)
71+
self.timer.daemon = True
72+
self.timer.name = "Startup"
73+
self.timer.start()
7474

7575
def printstatechange(self, e):
7676
logger.debug('========= (%i#%s) FSM event: %s, src: %s, dst: %s ==========' %
@@ -79,9 +79,6 @@ def printstatechange(self, e):
7979
def reset(self):
8080
self.fsm.lookup()
8181

82-
def start_metric_reporting(self, e):
83-
self.agent.sensor.meter.run()
84-
8582
def lookup_agent_host(self, e):
8683
host, port = self.__get_agent_host_port()
8784

instana/meter.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,22 @@ def __init__(self, agent):
123123
pass
124124

125125
def run(self):
126+
""" Spawns the metric reporting thread """
126127
self.thr = threading.Thread(target=self.collect_and_report)
127128
self.thr.daemon = True
128129
self.thr.name = "Instana Metric Collection"
129130
self.thr.start()
130131

131132
def reset(self):
133+
"""" Reset the state as new """
132134
self.last_usage = None
133135
self.last_collect = None
134136
self.last_metrics = None
135137
self.run()
136138

137139
def collect_and_report(self):
138-
log.debug("starting metric reporting thread")
140+
""" Target function for the metric reporting thread """
141+
log.debug("Metric reporting thread is now alive")
139142
while 1:
140143
self.process()
141144
if self.agent.is_timed_out():
@@ -145,6 +148,7 @@ def collect_and_report(self):
145148
time.sleep(1)
146149

147150
def process(self):
151+
""" Collects, processes & reports metrics """
148152
if self.agent.can_send():
149153
self.snapshot_countdown = self.snapshot_countdown - 1
150154
ss = None
@@ -163,6 +167,7 @@ def process(self):
163167
self.last_metrics = cm.__dict__
164168

165169
def collect_snapshot(self):
170+
""" Collects snapshot related information to this process and environment """
166171
try:
167172
if "FLASK_APP" in os.environ:
168173
appname = os.environ["FLASK_APP"]
@@ -200,6 +205,7 @@ def jsonable(self, value):
200205
log.debug(e)
201206

202207
def collect_modules(self):
208+
""" Collect up the list of modules in use """
203209
try:
204210
res = {}
205211
m = sys.modules
@@ -228,6 +234,7 @@ def collect_modules(self):
228234
return res
229235

230236
def collect_metrics(self):
237+
""" Collect up and return various metrics """
231238
u = resource.getrusage(resource.RUSAGE_SELF)
232239
if gc_.isenabled():
233240
c = list(gc_.get_count())

instana/recorder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .agent_const import AGENT_TRACES_URL
1515
from .json_span import (CustomData, Data, HttpData, JsonSpan, MySQLData,
1616
SDKData, SoapData)
17+
from .log import logger
1718

1819
if sys.version_info.major is 2:
1920
import Queue as queue
@@ -31,7 +32,6 @@ class InstanaRecorder(SpanRecorder):
3132

3233
def __init__(self):
3334
super(InstanaRecorder, self).__init__()
34-
self.run()
3535

3636
def run(self):
3737
""" Span a background thread to periodically report queued spans """
@@ -42,6 +42,7 @@ def run(self):
4242

4343
def report_spans(self):
4444
""" Periodically report the queued spans """
45+
logger.debug("Span reporting thread is now alive")
4546
while 1:
4647
if self.queue.qsize() > 0 and instana.singletons.agent.can_send():
4748
url = instana.singletons.agent.make_url(AGENT_TRACES_URL)

0 commit comments

Comments
 (0)