Skip to content

Commit 94fa02b

Browse files
GitHKAndrei Neagu
andauthored
using pyinstrument to log traceback of slow callbacks (#2341)
* using pyinstrument to keep track of slow callbacks * using similar logging message a sbefore * no more errors in development mode * fixes issues with testing and development mode on reboots * /slow callback was being resolved in 1.1 seconds causing test_unhealthy_app_with_slow_callbacks to fail * changed assert from 2.0 to 1.0 second * reverting back to 2.0 seconds raising /slow to 2.0 seocnds * fixed indentation * added comment about the indentation * trying to improve performance Co-authored-by: Andrei Neagu <[email protected]>
1 parent 36c96bf commit 94fa02b

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

packages/service-library/requirements/_base.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ sqlalchemy
2222
psycopg2-binary
2323
pyyaml
2424

25+
# used for monitoring of slow callbacks
26+
pyinstrument
2527

2628
# These are limitations introduced by testing libraries
2729

packages/service-library/requirements/_base.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ psycopg2-binary==2.8.6
7373
# sqlalchemy
7474
pydantic==1.8.2
7575
# via -r requirements/_base.in
76+
pyinstrument-cext==0.2.4
77+
# via pyinstrument
78+
pyinstrument==3.4.2
79+
# via -r requirements/_base.in
7680
pyrsistent==0.17.3
7781
# via jsonschema
7882
pyyaml==5.4.1
Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import asyncio.events
22
import time
3-
from asyncio.base_events import _format_handle
3+
import sys
44
from typing import List
55

6+
from pyinstrument import Profiler
7+
68
from .incidents import SlowCallback
79

810

911
def enable(slow_duration_secs: float, incidents: List[SlowCallback]) -> None:
10-
""" Based in from aiodebug
12+
"""Based in from aiodebug
1113
1214
Patches ``asyncio.events.Handle`` to report an incident every time a callback
1315
takes ``slow_duration_secs`` seconds or more to run.
@@ -19,13 +21,26 @@ def enable(slow_duration_secs: float, incidents: List[SlowCallback]) -> None:
1921
_run = asyncio.events.Handle._run
2022

2123
def instrumented(self):
22-
t0 = time.monotonic()
23-
retval = _run(self)
24-
dt = time.monotonic() - t0
24+
# unsetting profiler, helps with development mode and tests
25+
sys.setprofile(None)
26+
27+
with Profiler(interval=slow_duration_secs) as profiler:
28+
t0 = time.monotonic()
29+
30+
retval = _run(self)
31+
32+
dt = time.monotonic() - t0
33+
2534
if dt >= slow_duration_secs:
26-
task_info = _format_handle(self)
27-
incidents.append(SlowCallback(msg=task_info, delay_secs=dt))
28-
logger.warning("Executing %s took %.3f seconds", task_info, dt)
35+
# the indentation is correct, the profiler needs to be stopped when
36+
# printing the output, the profiler is started and stopped by the
37+
# contextmanger
38+
profiler_result = profiler.output_text(
39+
unicode=True, color=False, show_all=True
40+
)
41+
incidents.append(SlowCallback(msg=profiler_result, delay_secs=dt))
42+
logger.warning("Executing took %.3f seconds\n%s", dt, profiler_result)
43+
2944
return retval
3045

3146
asyncio.events.Handle._run = instrumented

services/web/server/tests/unit/isolated/test_healthcheck.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async def _check_entrypoint():
7070

7171
@pytest.fixture
7272
def client(loop, aiohttp_unused_port, aiohttp_client, api_version_prefix):
73-
SLOW_HANDLER_DELAY_SECS = 1.0 # secs
73+
SLOW_HANDLER_DELAY_SECS = 2.0 # secs
7474

7575
# pylint:disable=unused-variable
7676
routes = web.RouteTableDef()

0 commit comments

Comments
 (0)