From f4db799fcf98ba496f9ddc777fa352c0dc0e336f Mon Sep 17 00:00:00 2001
From: Tom Sparrow <793763+sparrowt@users.noreply.github.com>
Date: Tue, 17 Dec 2024 17:17:51 +0000
Subject: [PATCH 1/4] Basics of progress for austin2speedscope
This doesn't tell you how far through you are but at least
you can see that progress is occurring when loading and also
can see which of the 2 stages it is currently in.
---
austin/format/speedscope.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/austin/format/speedscope.py b/austin/format/speedscope.py
index 28a6f5e..33cea65 100644
--- a/austin/format/speedscope.py
+++ b/austin/format/speedscope.py
@@ -22,6 +22,7 @@
# along with this program. If not, see .
import json
+import time
from dataclasses import asdict
from dataclasses import dataclass
from dataclasses import field
@@ -211,7 +212,12 @@ def main() -> None:
with AustinFileReader(args.input) as fin:
mode = fin.metadata["mode"]
speedscope = Speedscope(os.path.basename(args.input), mode, args.indent)
+ print(f"Reading Austin samples from: {args.input} ...")
+ n_processed = 0
for line in fin:
+ n_processed += 1
+ if n_processed % 10000 == 0:
+ print(".", end="", flush=True)
try:
speedscope.add_samples(
Sample.parse(line, MetricType.from_mode(mode))
@@ -223,9 +229,12 @@ def main() -> None:
print(f"No such input file: {args.input}")
exit(1)
+ print(f"Writing Speedscope JSON to: {args.output} ...")
with open(args.output, "w") as fout:
speedscope.dump(fout)
if __name__ == "__main__":
+ start_time = time.monotonic()
main()
+ print("Conversion completed in %.1f seconds" % (time.monotonic() - start_time))
From 9451d1c12683585f019d7cadb59499d8d373cbc2 Mon Sep 17 00:00:00 2001
From: Tom Sparrow <793763+sparrowt@users.noreply.github.com>
Date: Wed, 18 Dec 2024 15:08:19 +0000
Subject: [PATCH 2/4] Proper percentage progress for loading step based on
bytes read
---
austin/format/speedscope.py | 16 +++++++++++-----
austin/stats.py | 4 ++++
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/austin/format/speedscope.py b/austin/format/speedscope.py
index 33cea65..e73beb9 100644
--- a/austin/format/speedscope.py
+++ b/austin/format/speedscope.py
@@ -211,19 +211,25 @@ def main() -> None:
try:
with AustinFileReader(args.input) as fin:
mode = fin.metadata["mode"]
+ size_bytes = fin.file_size_bytes()
speedscope = Speedscope(os.path.basename(args.input), mode, args.indent)
- print(f"Reading Austin samples from: {args.input} ...")
- n_processed = 0
+ print(f"Reading Austin samples from: {args.input} ({size_bytes / 1024 / 1024:,.1f} MB) ...")
+ lines_processed = 0
+ bytes_processed = 0
for line in fin:
- n_processed += 1
- if n_processed % 10000 == 0:
- print(".", end="", flush=True)
+ lines_processed += 1
+ bytes_processed += len(line)
+ if lines_processed % 1000 == 0:
+ # Show some progress because this can take a long time for huge traces
+ progress = bytes_processed / size_bytes * 100.0
+ print(f"{progress:.1f}%\r", end="", flush=True)
try:
speedscope.add_samples(
Sample.parse(line, MetricType.from_mode(mode))
)
except InvalidSample:
continue
+ print("") # newline after the progress dots so that subsequent output is on its own line
except FileNotFoundError:
print(f"No such input file: {args.input}")
diff --git a/austin/stats.py b/austin/stats.py
index 06cf469..0688327 100644
--- a/austin/stats.py
+++ b/austin/stats.py
@@ -22,6 +22,7 @@
# along with this program. If not, see .
import dataclasses
+import os.path
import re
from copy import deepcopy
from dataclasses import dataclass
@@ -411,6 +412,9 @@ def _read_meta(self) -> None:
break
self.metadata.add(line)
+ def file_size_bytes(self) -> int:
+ return os.path.getsize(self.file)
+
def __enter__(self) -> "AustinFileReader":
"""Open the Austin file and read the metadata."""
self._stream = open(self.file, "r")
From cdedf40245a006921df9944ffaf0edc11c8499e3 Mon Sep 17 00:00:00 2001
From: Tom Sparrow <793763+sparrowt@users.noreply.github.com>
Date: Fri, 20 Dec 2024 18:10:10 +0000
Subject: [PATCH 3/4] Show time taken
It wasn't working outside of `main` because the
`austin2speedscope` entrypoint directly calls `main`
---
austin/format/speedscope.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/austin/format/speedscope.py b/austin/format/speedscope.py
index e73beb9..c81595b 100644
--- a/austin/format/speedscope.py
+++ b/austin/format/speedscope.py
@@ -208,6 +208,7 @@ def main() -> None:
args = arg_parser.parse_args()
+ start_time = time.monotonic()
try:
with AustinFileReader(args.input) as fin:
mode = fin.metadata["mode"]
@@ -222,14 +223,14 @@ def main() -> None:
if lines_processed % 1000 == 0:
# Show some progress because this can take a long time for huge traces
progress = bytes_processed / size_bytes * 100.0
- print(f"{progress:.1f}%\r", end="", flush=True)
+ print(f"\r{progress:.1f}%", end="", flush=True)
try:
speedscope.add_samples(
Sample.parse(line, MetricType.from_mode(mode))
)
except InvalidSample:
continue
- print("") # newline after the progress dots so that subsequent output is on its own line
+ print("") # newline after progress so that subsequent output is on its own line
except FileNotFoundError:
print(f"No such input file: {args.input}")
@@ -239,8 +240,8 @@ def main() -> None:
with open(args.output, "w") as fout:
speedscope.dump(fout)
+ print("Conversion complete - total duration: %s" % time.strftime('%Hh %Mm %Ss', time.gmtime(time.monotonic() - start_time)))
+
if __name__ == "__main__":
- start_time = time.monotonic()
main()
- print("Conversion completed in %.1f seconds" % (time.monotonic() - start_time))
From 9be0e96b63d05d93c23965bf094b1ae777f1d0f0 Mon Sep 17 00:00:00 2001
From: Tom Sparrow <793763+sparrowt@users.noreply.github.com>
Date: Thu, 16 Jan 2025 16:52:32 +0000
Subject: [PATCH 4/4] Black
Not sure why mojo.py was flagged in CI seeing as I didn't touch it
but I've fixed anyway
---
austin/format/mojo.py | 8 +++++---
austin/format/speedscope.py | 13 ++++++++++---
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/austin/format/mojo.py b/austin/format/mojo.py
index 01bc3d5..523cbec 100644
--- a/austin/format/mojo.py
+++ b/austin/format/mojo.py
@@ -333,9 +333,11 @@ def read_string(self) -> str:
def _emit_metrics(self) -> t.Generator[t.Union[MojoEvent, int], None, None]:
"""Emit metrics."""
if self._metrics:
- yield MojoFullMetrics(
- self._metrics
- ) if self._full_mode else self._metrics.pop()
+ yield (
+ MojoFullMetrics(self._metrics)
+ if self._full_mode
+ else self._metrics.pop()
+ )
self._metrics.clear()
@handles(MojoEvents.METADATA)
diff --git a/austin/format/speedscope.py b/austin/format/speedscope.py
index c81595b..75944ca 100644
--- a/austin/format/speedscope.py
+++ b/austin/format/speedscope.py
@@ -214,7 +214,9 @@ def main() -> None:
mode = fin.metadata["mode"]
size_bytes = fin.file_size_bytes()
speedscope = Speedscope(os.path.basename(args.input), mode, args.indent)
- print(f"Reading Austin samples from: {args.input} ({size_bytes / 1024 / 1024:,.1f} MB) ...")
+ print(
+ f"Reading Austin samples from: {args.input} ({size_bytes / 1024 / 1024:,.1f} MB) ..."
+ )
lines_processed = 0
bytes_processed = 0
for line in fin:
@@ -230,7 +232,9 @@ def main() -> None:
)
except InvalidSample:
continue
- print("") # newline after progress so that subsequent output is on its own line
+ print(
+ ""
+ ) # newline after progress so that subsequent output is on its own line
except FileNotFoundError:
print(f"No such input file: {args.input}")
@@ -240,7 +244,10 @@ def main() -> None:
with open(args.output, "w") as fout:
speedscope.dump(fout)
- print("Conversion complete - total duration: %s" % time.strftime('%Hh %Mm %Ss', time.gmtime(time.monotonic() - start_time)))
+ print(
+ "Conversion complete - total duration: %s"
+ % time.strftime("%Hh %Mm %Ss", time.gmtime(time.monotonic() - start_time))
+ )
if __name__ == "__main__":