Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9b15b18

Browse files
committed
auto_destroy option
1 parent b32bf14 commit 9b15b18

File tree

14 files changed

+54
-59
lines changed

14 files changed

+54
-59
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,14 @@ Add the agent initialization to the worker code, e.g. wsgi.py, if applicable.
7171
All initialization options:
7272

7373
* `agent_key` (Required) The access key for communication with the StackImpact servers.
74-
* `app_name` (Required) A name to identify and group application data. Typically, a single codebase corresponds to one application.
74+
* `app_name` (Required) A name to identify and group application data. Typically, a single codebase, deployable unit or executable module corresponds to one application.
7575
* `app_version` (Optional) Sets application version, which can be used to associate profiling information with the source code release.
7676
* `app_environment` (Optional) Used to differentiate applications in different environments.
7777
* `host_name` (Optional) By default, host name will be the OS hostname.
7878
* `debug` (Optional) Enables debug logging.
7979
* `cpu_profiler_disabled`, `allocation_profiler_disabled`, `block_profiler_disabled`, `error_profiler_disabled` (Optional) Disables respective profiler when `True`.
8080
* `include_agent_frames`, `include_system_frames` (Optional) Set to `True` to not exclude agent and/or system stack frames from profiles.
81+
* `auto_destroy` (Optional) Set to `False` to disable agent's exit handlers. If necessary, call `destroy()` to gracefully shutdown the agent.
8182

8283

8384

README.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,11 @@ applicable.
9191

9292
All initialization options:
9393

94-
- ``agent_key`` (Required) The access key for communication with
94+
- ``agent_key`` (Required) The access key for communication with the
9595
StackImpact servers.
9696
- ``app_name`` (Required) A name to identify and group application
97-
data. Typically, single codebase corresponds to one application.
97+
data. Typically, a single codebase, deployable unit or executable
98+
module corresponds to one application.
9899
- ``app_version`` (Optional) Sets application version, which can be
99100
used to associate profiling information with the source code release.
100101
- ``app_environment`` (Optional) Used to differentiate applications in
@@ -108,6 +109,9 @@ All initialization options:
108109
- ``include_agent_frames``, ``include_system_frames`` (Optional) Set to
109110
``True`` to not exclude agent and/or system stack frames from
110111
profiles.
112+
- ``auto_destroy`` (Optional) Set to ``False`` to disable agent's exit
113+
handlers. If necessary, call ``destroy()`` to gracefully shutdown the
114+
agent.
111115

112116
Analyzing performance data in the Dashboard
113117
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name = 'stackimpact',
5-
version = '1.0.4',
5+
version = '1.0.5',
66
description = 'StackImpact Python Agent',
77
author = 'StackImpact',
88
author_email = '[email protected]',

stackimpact/agent.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
class Agent:
2828

29-
AGENT_VERSION = "1.0.4"
29+
AGENT_VERSION = "1.0.5"
3030
SAAS_DASHBOARD_ADDRESS = "https://agent-api.stackimpact.com"
3131

3232
def __init__(self, **kwargs):
@@ -61,7 +61,7 @@ def get_option(self, name, default_val = None):
6161

6262
def start(self, **kwargs):
6363
if not min_version(2, 7) and not min_version(3, 4):
64-
raise Exception('Supported Python versions 2.6 or highter and 3.4 or higher')
64+
raise Exception('Supported Python versions 2.6 or higher and 3.4 or higher')
6565

6666
if platform.python_implementation() != 'CPython':
6767
raise Exception('Supported Python interpreter is CPython')
@@ -114,24 +114,26 @@ def _signal_handler(signum, frame):
114114

115115
register_signal(signal.SIGUSR2, _signal_handler)
116116

117-
# destroy agent on exit
118-
def _exit_handler(*arg):
119-
if not self.agent_started or self.agent_destroyed:
120-
return
117+
if self.get_option('auto_destroy') == False:
118+
# destroy agent on exit
119+
def _exit_handler(*arg):
120+
if not self.agent_started or self.agent_destroyed:
121+
return
122+
123+
try:
124+
self.message_queue.flush()
125+
self.destroy()
126+
except Exception:
127+
self.exception()
121128

122-
try:
123-
self.message_queue.flush()
124-
self.destroy()
125-
except Exception:
126-
self.exception()
127129

130+
atexit.register(_exit_handler)
128131

129-
atexit.register(_exit_handler)
132+
register_signal(signal.SIGQUIT, _exit_handler, once = True)
133+
register_signal(signal.SIGINT, _exit_handler, once = True)
134+
register_signal(signal.SIGTERM, _exit_handler, once = True)
135+
register_signal(signal.SIGHUP, _exit_handler, once = True)
130136

131-
register_signal(signal.SIGQUIT, _exit_handler, ignore_default = False)
132-
register_signal(signal.SIGINT, _exit_handler, ignore_default = False)
133-
register_signal(signal.SIGTERM, _exit_handler, ignore_default = False)
134-
register_signal(signal.SIGHUP, _exit_handler, ignore_default = False)
135137

136138
self.agent_started = True
137139
self.log('Agent started')
@@ -178,7 +180,6 @@ def error(self, message):
178180

179181
def exception(self):
180182
if self.get_option('debug'):
181-
self.print_err(sys.exc_info()[0])
182183
traceback.print_exc()
183184

184185

stackimpact/api_request.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ def post(self, endpoint, payload):
3333
'Content-Encoding': 'gzip'
3434
}
3535

36-
host_name = 'host'
36+
host_name = 'undefined'
3737
try:
3838
host_name = socket.gethostname()
3939
except Exception:
40-
pass
40+
self.agent.exception()
4141

4242
req_body = {
4343
'runtime_type': 'python',
@@ -71,6 +71,7 @@ def post(self, endpoint, payload):
7171
headers = headers)
7272

7373
response = urlopen(request, timeout = 20)
74+
7475
result_data = response.read()
7576

7677
if response.info():

stackimpact/metric.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ def normalize(self, factor):
285285
child.normalize(factor)
286286

287287

288+
def floor(self):
289+
self.measurement = int(self.measurement)
290+
291+
for name, child in self.children.items():
292+
child.floor()
293+
294+
288295
def to_dict(self):
289296
children_map = []
290297
for name, child in self.children.items():

stackimpact/reporters/allocation_reporter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ def report(self):
130130
return
131131

132132
self.profile.normalize(self.profile_duration)
133+
self.profile.floor()
133134
self.profile.filter(2, 1000, float("inf"))
134135

135136
metric = Metric(self.agent, Metric.TYPE_PROFILE, Metric.CATEGORY_MEMORY_PROFILE, Metric.NAME_UNCOLLECTED_ALLOCATIONS, Metric.UNIT_BYTE)

stackimpact/reporters/block_reporter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ def report(self):
189189

190190
with self.profile_lock:
191191
self.block_profile.normalize(self.profile_duration)
192+
self.block_profile.floor()
192193
self.block_profile.filter(2, 1, float("inf"))
193194

194195
metric = Metric(self.agent, Metric.TYPE_PROFILE, Metric.CATEGORY_BLOCK_PROFILE, Metric.NAME_BLOCKING_CALL_TIMES, Metric.UNIT_MILLISECOND)

stackimpact/reporters/process_reporter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def __init__(self, agent):
1919

2020

2121
def start(self):
22-
self.report_timer = self.agent.schedule(5, 60, self.report)
22+
self.report_timer = self.agent.schedule(60, 60, self.report)
2323

2424

2525
def destroy(self):

stackimpact/runtime.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,18 @@ def unpatch(obj, func_name):
122122
setattr(obj, func_name, getattr(wrapper, '__stackimpact_orig__'))
123123

124124

125-
def register_signal(signal_number, handler_func, ignore_default = True):
125+
def register_signal(signal_number, handler_func, once = False):
126126
prev_handler = None
127127

128128
def _handler(signum, frame):
129129
skip_prev = handler_func(signum, frame)
130130

131131
if not skip_prev:
132132
if callable(prev_handler):
133+
if once:
134+
signal.signal(signum, prev_handler)
133135
prev_handler(signum, frame)
134-
elif prev_handler == signal.SIG_DFL and not ignore_default:
136+
elif prev_handler == signal.SIG_DFL and once:
135137
signal.signal(signum, signal.SIG_DFL)
136138
os.kill(os.getpid(), signum)
137139

0 commit comments

Comments
 (0)