22# ruff: noqa: RET503
33
44# /// script
5+ # requires-python = ">=3.11"
56# dependencies = [
67# "pygal[png]",
78# ]
1112import os
1213import re
1314import sys
15+ from datetime import datetime
1416
1517import pygal # also need cairosvg for png output
1618
19+ DT_PAT = r"((\d{4}-\d{2}-\d{2} \d{2}:\d{2}):\d{2},\d{3}) "
20+
1721
1822def process (options ):
1923 pie = pygal .Pie ()
2024 dt = None
2125 others = 0.0
26+ end_st = None
27+ end_mod = None
2228 for line in sys .stdin .readlines ():
2329 if dt is None :
24- match = re .match (r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}):\d{2},\d{3} " , line )
30+ match = re .match (DT_PAT , line )
2531 if match :
26- dt = match .group (1 )
32+ dt = match .group (2 )
2733
2834 match = re .search (r"Module ([a-zA-Z0-9_]+) loaded in (\d+\.\d\d)s, \d+ queries" , line )
2935 if match :
@@ -32,6 +38,34 @@ def process(options):
3238 pie .add (match .group (1 ), time )
3339 else :
3440 others += time
41+ continue
42+
43+ match = re .search (r"module ([a-zA-Z0-9_]+): Running migration \[\$" , line )
44+ if match :
45+ mod = match .group (1 )
46+ match = re .match (DT_PAT , line )
47+ if end_mod is None :
48+ end_mod = mod
49+ end_st = match .group (1 )
50+ elif mod != end_mod :
51+ time = (datetime .fromisoformat (match .group (1 )) - datetime .fromisoformat (end_st )).total_seconds ()
52+ if time > options .min_time :
53+ pie .add (f"{ end_mod } [end]" , time )
54+ else :
55+ others += time
56+ end_mod = mod
57+ end_st = match .group (1 )
58+
59+ elif end_st :
60+ if " odoo.modules.loading:" in line or " odoo.addons.base.models.ir_model: Deleting " in line :
61+ # last `end-` script finished.
62+ match = re .match (DT_PAT , line )
63+ time = (datetime .fromisoformat (match .group (1 )) - datetime .fromisoformat (end_st )).total_seconds ()
64+ if time > options .min_time :
65+ pie .add (f"{ end_mod } [end]" , time )
66+ else :
67+ others += time
68+ end_st = None
3569
3670 if options .min_time and others :
3771 pie .add ("Other modules" , others )
0 commit comments