Skip to content

Commit bb54833

Browse files
authored
improve logging and change output file path and ownership (#26)
1 parent 1dfc3f9 commit bb54833

10 files changed

+114
-133
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build/*
22
dist/*
33
src/libtsc.so
4-
__pycache__
4+
__pycache__
5+
*.log

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ perf-collect: Collects harware events
1919

2020
perf-postprocess: Calculates high level metrics from hardware events
2121

22-
- `perf-postprocess -r results/perfstat.csv`
22+
- `./perf-postprocess`
2323

2424
## Quick start (requires perf installed)
2525

2626
```
2727
wget -qO- https://github.com/intel/PerfSpect/releases/latest/download/perfspect.tgz | tar xvz
2828
cd perfspect
2929
sudo ./perf-collect --timeout 10
30-
sudo ./perf-postprocess -r results/perfstat.csv --html perfstat.html
30+
./perf-postprocess
3131
```
3232

3333
## Deploy in Kubernetes

_version.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2.6
1+
1.2.7

events/spr.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ cpu/event=0x00,umask=0x85,period=10000003,name='PERF_METRICS.BRANCH_MISPREDICTS'
5858
cpu/event=0x00,umask=0x84,period=10000003,name='PERF_METRICS.HEAVY_OPERATIONS'/;
5959

6060
cpu/event=0xad,umask=0x10,period=1000003,name='INT_MISC.UOP_DROPPING'/,
61-
cpu/event=0xad,umask=0x40,frontend=0x7,period=1000003,name='INT_MISC.UNKNOWN_BRANCH_CYCLES'/,
61+
cpu/event=0xad,umask=0x40,period=1000003,name='INT_MISC.UNKNOWN_BRANCH_CYCLES'/,
6262
cpu/event=0xa6,umask=0x21,cmask=0x05,period=2000003,name='EXE_ACTIVITY.BOUND_ON_LOADS'/,
6363
cpu-cycles;
6464

@@ -89,7 +89,7 @@ cpu/event=0x48,umask=0x01,period=1000003,name='L1D_PEND_MISS.PENDING'/,
8989
cpu/event=0x03,umask=0x88,period=100003,name='LD_BLOCKS.NO_SR'/,
9090
cpu-cycles;
9191

92-
cpu/event=0xc2,umask=0x04,frontend=0x8,period=2000003,name='UOPS_RETIRED.MS'/,
92+
cpu/event=0xc2,umask=0x04,period=2000003,name='UOPS_RETIRED.MS'/,
9393
cpu/event=0xec,umask=0x02,period=2000003,name='CPU_CLK_UNHALTED.DISTRIBUTED'/,
9494
cpu-cycles;
9595

perf-collect.py

+37-53
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,18 @@
55
# SPDX-License-Identifier: BSD-3-Clause
66
###########################################################################################################
77

8-
from __future__ import print_function
98
import logging
109
import os
1110
import platform
12-
import re
1311
import sys
1412
import subprocess # nosec
1513
import shlex # nosec
1614
from argparse import ArgumentParser
1715
from src import perf_helpers
1816
from src import prepare_perf_events as prep_events
1917
from src.common import crash
18+
from src import common
2019

21-
logging.basicConfig(
22-
format="%(asctime)s %(levelname)s: %(message)s",
23-
datefmt="%H:%M:%S",
24-
level=logging.NOTSET,
25-
handlers=[logging.FileHandler("debug.log"), logging.StreamHandler(sys.stdout)],
26-
)
27-
log = logging.getLogger(__name__)
2820

2921
SUPPORTED_ARCHITECTURES = [
3022
"Broadwell",
@@ -54,7 +46,9 @@ def write_metadata(
5446
with open(outcsv, "r") as original:
5547
time_stamp = original.readline()
5648
if metadata_only and time_stamp.startswith("### META DATA ###"):
57-
log.warning("Not prepending metadata, already present in %s " % (outcsv))
49+
logging.warning(
50+
"Not prepending metadata, already present in %s " % (outcsv)
51+
)
5852
return
5953
data = original.read()
6054
with open(outcsv, "w") as modified:
@@ -164,22 +158,16 @@ def validate_file(fname):
164158
crash(str(fname) + " not accessible")
165159

166160

167-
def is_safe_file(fname, substr):
168-
"""verify if file name/format is accurate"""
169-
if not fname.endswith(substr):
170-
crash(str(fname) + " isn't appropriate format")
171-
172-
173161
if __name__ == "__main__":
162+
common.configure_logging(".")
174163
if platform.system() != "Linux":
175164
crash("PerfSpect currently supports Linux only")
176165

177166
# fix the pyinstaller path
178167
script_path = os.path.dirname(os.path.realpath(__file__))
179168
if "_MEI" in script_path:
180169
script_path = script_path.rsplit("/", 1)[0]
181-
result_dir = script_path + "/results"
182-
default_output_file = result_dir + "/perfstat.csv"
170+
default_output_file = "perfstat.csv"
183171

184172
parser = ArgumentParser(description="perf-collect: Time series dump of PMUs")
185173
duration = parser.add_mutually_exclusive_group()
@@ -225,7 +213,7 @@ def is_safe_file(fname, substr):
225213
"--outcsv",
226214
type=str,
227215
default=default_output_file,
228-
help="perf stat output in csv format, default=results/perfstat.csv",
216+
help="perf stat output in csv format, default=perfstat.csv",
229217
)
230218
parser.add_argument(
231219
"-v",
@@ -237,7 +225,7 @@ def is_safe_file(fname, substr):
237225

238226
if args.version:
239227
print(perf_helpers.get_tool_version())
240-
sys.exit(0)
228+
sys.exit()
241229

242230
if os.geteuid() != 0:
243231
crash("Must run PerfSpect as root, please re-run")
@@ -249,7 +237,7 @@ def is_safe_file(fname, substr):
249237
nmi_watchdog = f_nmi.read()
250238
if int(nmi_watchdog) != 0:
251239
f_nmi.write("0")
252-
log.info("nmi_watchdog disabled")
240+
logging.info("nmi_watchdog disabled")
253241
except FileNotFoundError:
254242
pass
255243

@@ -278,28 +266,24 @@ def is_safe_file(fname, substr):
278266
elif arch == "sapphirerapids":
279267
eventfile = "spr.txt"
280268

269+
if eventfile is None:
270+
crash(f"failed to match architecture ({arch}) to event file name.")
271+
281272
# Convert path of event file to relative path if being packaged by pyInstaller into a binary
282273
if getattr(sys, "frozen", False):
283274
basepath = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
284275
eventfilename = eventfile
285-
is_safe_file(eventfile, ".txt")
286276
eventfile = os.path.join(basepath, eventfile)
287277
elif __file__:
288278
eventfile = script_path + "/events/" + eventfile
289279
eventfilename = eventfile
290280
else:
291281
crash("Unknown application type")
292282

293-
if args.outcsv == default_output_file:
294-
# create results dir
295-
if not os.path.exists(result_dir):
296-
os.mkdir(result_dir)
297-
perf_helpers.fix_path_ownership(result_dir)
298-
else:
299-
if not perf_helpers.validate_outfile(args.outcsv):
300-
crash(
301-
"Output filename not accepted. Filename should be a .csv without special characters"
302-
)
283+
if not perf_helpers.validate_outfile(args.outcsv):
284+
crash(
285+
"Output filename not accepted. Filename should be a .csv without special characters"
286+
)
303287

304288
mux_intervals = perf_helpers.get_perf_event_mux_interval()
305289
if args.muxinterval > 0:
@@ -311,22 +295,21 @@ def is_safe_file(fname, substr):
311295
cgroups = perf_helpers.get_cgroups_from_cids(args.cid.split(","))
312296
num_cgroups = len(cgroups)
313297

314-
try:
315-
reg = r"^[0-9]*\.[0-9][0-9]*"
316-
kernel = perf_helpers.get_version().split("Linux version")[1].lstrip()
317-
significant_kernel_version = re.match(reg, kernel).group(0)
318-
full_kernel_version = kernel
319-
except Exception as e:
320-
log.exception(e)
321-
crash("Unable to get kernel version")
322-
323298
# get perf events to collect
324299
collection_events = []
325300
imc, cha, upi = perf_helpers.get_imc_cacheagent_count()
326301
have_uncore = True
327302
if imc == 0 and cha == 0 and upi == 0:
328-
log.info("disabling uncore (possibly in a vm?)")
303+
logging.info("disabling uncore (possibly in a vm?)")
329304
have_uncore = False
305+
if arch == "icelake":
306+
logging.warning(
307+
"Due to lack of vPMU support, TMA L1 events will not be collected"
308+
)
309+
if arch == "sapphirerapids":
310+
logging.warning(
311+
"Due to lack of vPMU support, TMA L1 & L2 events will not be collected"
312+
)
330313
events, collection_events = prep_events.prepare_perf_events(
331314
eventfile,
332315
(
@@ -341,7 +324,7 @@ def is_safe_file(fname, substr):
341324
collection_type = "-a" if not args.thread and not args.socket else "-a -A"
342325
# start perf stat
343326
if args.pid and args.timeout:
344-
log.info("Only CPU/core events will be enabled with pid option")
327+
logging.info("Only CPU/core events will be enabled with pid option")
345328
cmd = "perf stat -I %d -x , --pid %s -e %s -o %s sleep %d" % (
346329
interval,
347330
args.pid,
@@ -351,15 +334,15 @@ def is_safe_file(fname, substr):
351334
)
352335

353336
elif args.pid:
354-
log.info("Only CPU/core events will be enabled with pid option")
337+
logging.info("Only CPU/core events will be enabled with pid option")
355338
cmd = "perf stat -I %d -x , --pid %s -e %s -o %s" % (
356339
interval,
357340
args.pid,
358341
events,
359342
args.outcsv,
360343
)
361344
elif args.cid and args.timeout:
362-
log.info("Only CPU/core events will be enabled with cid option")
345+
logging.info("Only CPU/core events will be enabled with cid option")
363346
perf_format = prep_events.get_cgroup_events_format(
364347
cgroups, events, len(collection_events)
365348
)
@@ -370,7 +353,7 @@ def is_safe_file(fname, substr):
370353
args.timeout,
371354
)
372355
elif args.cid:
373-
log.info("Only CPU/core events will be enabled with cid option")
356+
logging.info("Only CPU/core events will be enabled with cid option")
374357
perf_format = prep_events.get_cgroup_events_format(
375358
cgroups, events, len(collection_events)
376359
)
@@ -402,13 +385,13 @@ def is_safe_file(fname, substr):
402385
validate_perfargs(perfargs)
403386
perf_helpers.pmu_contention_detect(msrs=initial_pmus, detect=True)
404387
if args.verbose:
405-
log.info(cmd)
388+
logging.info(cmd)
406389
try:
407-
log.info("Collecting perf stat for events in : %s" % eventfilename)
390+
logging.info("Collecting perf stat for events in : %s" % eventfilename)
408391
subprocess.call(perfargs) # nosec
409-
log.info("Collection complete! Calculating TSC frequency now")
392+
logging.info("Collection complete! Calculating TSC frequency now")
410393
except KeyboardInterrupt:
411-
log.info("Collection stopped! Caculating TSC frequency now")
394+
logging.info("Collection stopped! Caculating TSC frequency now")
412395
except Exception:
413396
crash("perf encountered errors")
414397

@@ -425,13 +408,14 @@ def is_safe_file(fname, substr):
425408
False,
426409
)
427410

411+
os.chmod(args.outcsv, 0o666) # nosec
412+
428413
# reset nmi_watchdog to what it was before running perfspect
429414
with open("/proc/sys/kernel/nmi_watchdog", "w") as f_nmi:
430415
if int(nmi_watchdog) != 0:
431416
f_nmi.write(nmi_watchdog)
432-
log.info("nmi_watchdog re-enabled")
417+
logging.info("nmi_watchdog re-enabled")
433418

434419
perf_helpers.set_perf_event_mux_interval(True, 1, mux_intervals)
435420

436-
log.info("perf stat dumped to %s" % args.outcsv)
437-
perf_helpers.fix_path_ownership(result_dir, True)
421+
logging.info("perf stat dumped to %s" % args.outcsv)

0 commit comments

Comments
 (0)