aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fl.fischer@fau.de>2020-07-13 15:49:44 +0200
committerFlorian Fischer <florian.fl.fischer@fau.de>2020-07-13 15:53:02 +0200
commitbbd008e2b0df0dc03db6d8671ed5041c1cdb04de (patch)
treef074827ba053783c1d1a26e586d65994be216535
parentcfc16837f6350844b3f3043118685e4f310f8b0e (diff)
downloadallocbench-bbd008e2b0df0dc03db6d8671ed5041c1cdb04de.tar.gz
allocbench-bbd008e2b0df0dc03db6d8671ed5041c1cdb04de.zip
replace print_* functions from allocbench.util if logging
-rw-r--r--allocbench/allocator.py43
-rw-r--r--allocbench/analyse.py15
-rw-r--r--allocbench/artifact.py27
-rw-r--r--allocbench/benchmark.py90
-rw-r--r--allocbench/benchmarks/mysql.py21
-rw-r--r--allocbench/facter.py13
-rw-r--r--allocbench/plots.py19
-rw-r--r--allocbench/util.py65
-rwxr-xr-xbench.py63
-rwxr-xr-xsummarize.py25
10 files changed, 191 insertions, 190 deletions
diff --git a/allocbench/allocator.py b/allocbench/allocator.py
index 1906a1e..27e137e 100644
--- a/allocbench/allocator.py
+++ b/allocbench/allocator.py
@@ -20,19 +20,21 @@ from datetime import datetime
import fnmatch
import inspect
import importlib
+import logging
import os
from pathlib import Path
import shutil
from subprocess import CalledProcessError
-import sys
from typing import List, Optional
from allocbench.artifact import Artifact, ArchiveArtifact, GitArtifact
-from allocbench.util import print_status, print_debug, print_error, print_info2, run_cmd
+from allocbench.util import print_status, run_cmd
from allocbench.directories import (get_allocbench_build_dir,
get_allocbench_allocator_src_dir,
get_allocbench_allocator_build_dir)
+logger = logging.getLogger(__file__)
+
LIBRARY_PATH = ""
for line in run_cmd(["ldconfig", "-v", "-N"],
capture=True).stdout.splitlines():
@@ -114,8 +116,8 @@ class Allocator:
cwd=cwd,
input=patch_content)
except CalledProcessError as err:
- print_debug(err.stderr, file=sys.stderr)
- print_error(f"Patching of {self.name} failed.")
+ logger.debug("%s", err.stderr)
+ logger.error("Patching of %s failed.", self.name)
raise
if self.prepare_cmds:
@@ -124,8 +126,8 @@ class Allocator:
try:
run_cmd(cmd, shell=True, cwd=self.srcdir)
except CalledProcessError as err:
- print_debug(err.stderr, file=sys.stderr)
- print_error(f"Prepare {self.name} failed")
+ logger.debug("%s", err.stderr)
+ logger.error("Prepare %s failed", self.name)
raise
def build(self):
@@ -135,7 +137,7 @@ class Allocator:
buildtimestamp_path = self.dir / ".buildtime"
if not build_needed:
- print_info2("Old build found. Comparing build time with mtime")
+ logger.info("Old build found. Comparing build time with mtime")
with open(buildtimestamp_path, "r") as buildtimestamp_file:
timestamp = datetime.fromtimestamp(
@@ -146,10 +148,10 @@ class Allocator:
build_needed = timestamp < modtime
- print_debug("Time of last build:", timestamp.isoformat())
- print_debug("Last modification of allocators file:",
- modtime.isoformat())
- print_info2("" if build_needed else "No " + "build needed")
+ logger.debug("Time of last build: %s", timestamp.isoformat())
+ logger.debug("Last modification of allocators file: %s",
+ modtime.isoformat())
+ logger.info("%sbuild needed", "" if build_needed else "No ")
if build_needed:
self.prepare()
@@ -163,16 +165,16 @@ class Allocator:
cwd=get_allocbench_allocator_build_dir(),
shell=True)
except CalledProcessError as err:
- print_debug(err.stderr, file=sys.stderr)
- print_error(f"Builing {self.name} failed")
+ logger.debug("%s", err.stderr)
+ logger.error("Builing %s failed", self.name)
shutil.rmtree(self.dir, ignore_errors=True)
raise
with open(buildtimestamp_path, "w") as buildtimestamp_file:
- print_info2("Save build time to:", buildtimestamp_path)
+ logger.info("Save build time to: %s", buildtimestamp_path)
buildtimestamp_file.write(str(datetime.now().timestamp()))
- print_info2("Create allocator dictionary")
+ logger.info("Create allocator dictionary")
res_dict = {
"cmd_prefix": self.cmd_prefix or "",
"binary_suffix": self.binary_suffix or "",
@@ -187,7 +189,7 @@ class Allocator:
value = value.format(dir=self.dir, srcdir=self.srcdir)
res_dict[attr] = value
- print_debug("Resulting dictionary:", res_dict)
+ logger.debug("Resulting dictionary: %s", res_dict)
return res_dict
@@ -251,7 +253,7 @@ def read_allocators_collection_file(alloc_path):
if "allocators" in exec_globals:
return {a.name: a.build() for a in exec_globals["allocators"]}
- print_error("No global dictionary 'allocators' in", alloc_path)
+ logger.error("No global dictionary 'allocators' in %s", alloc_path)
return {}
@@ -300,8 +302,7 @@ def collect_allocators(allocators):
for a in matched_allocators
})
else:
- print_error(
- name,
- "is neither a python file or a known allocator definition."
- )
+ logger.error(
+ '"%s" is neither a python file or a known allocator definition.',
+ name)
return ret
diff --git a/allocbench/analyse.py b/allocbench/analyse.py
index aff8893..6e7c338 100644
--- a/allocbench/analyse.py
+++ b/allocbench/analyse.py
@@ -17,12 +17,13 @@
"""Analyze benchmarks and allocators"""
import importlib
+import logging
import os
import traceback
-from allocbench.util import find_cmd
-from allocbench.util import print_status, print_warn, print_error
-from allocbench.util import print_info2, print_debug
+from allocbench.util import find_cmd, print_status
+
+logger = logging.getLogger(__file__)
def build_analyze_alloc():
@@ -30,7 +31,7 @@ def build_analyze_alloc():
if find_cmd("malt") is not None:
alloc_name = "malt"
else:
- print_warn("malt not found. Using chattymalloc.")
+ logger.warning("malt not found. Using chattymalloc.")
alloc_name = "chattymalloc"
analyze_alloc_module = importlib.import_module(
@@ -45,7 +46,7 @@ def analyze_bench(bench):
# Create benchmark result directory
if not os.path.isdir(bench.result_dir):
- print_info2("Creating benchmark result dir:", bench.result_dir)
+ logger.info("Creating benchmark result dir: %s", bench.result_dir)
os.makedirs(bench.result_dir, exist_ok=True)
alloc_name, alloc_dict = build_analyze_alloc()
@@ -58,8 +59,8 @@ def analyze_bench(bench):
try:
bench.run(runs=1)
except Exception: #pylint: disable=broad-except
- print_debug(traceback.format_exc())
- print_error("Skipping analysis of", bench, "!")
+ logger.debug("%s", traceback.format_exc())
+ logger.error("Skipping analysis of %s!", bench)
bench.measure_cmd = old_measure_cmd
diff --git a/allocbench/artifact.py b/allocbench/artifact.py
index 06c08f2..084b403 100644
--- a/allocbench/artifact.py
+++ b/allocbench/artifact.py
@@ -22,13 +22,16 @@ Both flavours are version controlled archive with a checksum and git repositorie
with a specific checkout.
"""
+import logging
from subprocess import CalledProcessError
from allocbench.directories import get_allocbench_base_dir
-from allocbench.util import print_status, print_info, print_debug, print_error, run_cmd, sha1sum
+from allocbench.util import print_status, run_cmd, sha1sum
ARTIFACT_STORE_DIR = get_allocbench_base_dir() / "cache"
+logger = logging.getLogger(__file__)
+
class Artifact:
"""Base class for external ressources"""
@@ -41,7 +44,7 @@ class Artifact:
self.basedir.mkdir(exist_ok=True)
print_status(f'Retrieving artifact "{self.name}" ...')
- print_debug(f"By running: {cmd} in {self.basedir}")
+ logger.debug("By running: %s in %s", cmd, self.basedir)
run_cmd(cmd, output_verbosity=1, cwd=self.basedir)
@@ -70,14 +73,14 @@ class GitArtifact(Artifact):
try:
run_cmd(GIT_FETCH_CMD, output_verbosity=1, cwd=location)
except CalledProcessError:
- print_error(f"Failed to update {location}")
+ logger.error("Failed to update %s", location)
raise
try:
run_cmd(["git", "reset", "--hard", checkout],
output_verbosity=1,
cwd=location)
except CalledProcessError:
- print_error(f"Failed to update {location}")
+ logger.error("Failed to update %s", location)
raise
return location
@@ -86,8 +89,8 @@ class GitArtifact(Artifact):
self.retrieve()
worktree_cmd = ["git", "worktree", "add", location, checkout]
- print_debug("create new worktree. By running: ", worktree_cmd,
- f"in {self.repo}")
+ logger.debug("create new worktree. By running: %s in %s", worktree_cmd,
+ self.repo)
try:
run_cmd(worktree_cmd, output_verbosity=1, cwd=self.repo)
except CalledProcessError:
@@ -96,20 +99,20 @@ class GitArtifact(Artifact):
try:
run_cmd(GIT_FETCH_CMD, output_verbosity=1, cwd=self.repo)
except CalledProcessError:
- print_error(f"Failed to update {self.name}")
+ logger.error("Failed to update %s", self.name)
raise
try:
run_cmd(worktree_cmd, output_verbosity=1, cwd=self.repo)
except CalledProcessError:
- print_error(f"Failed to provide {self.name}")
+ logger.error("Failed to provide %s", self.name)
raise
submodule_init_cmd = [
"git", "submodule", "update", "--init", "--recursive"
]
- print_debug("update submodules in worktree. By running: ",
- f"{submodule_init_cmd} in {self.repo}")
+ logger.debug("update submodules in worktree. By running: %s in %s",
+ submodule_init_cmd, self.repo)
run_cmd(submodule_init_cmd, output_verbosity=1, cwd=location)
return location
@@ -141,7 +144,7 @@ class ArchiveArtifact(Artifact):
self.retrieve()
# compare checksums
- print_info("Verify checksum ...")
+ logger.info("Verify checksum ...")
if sha1sum(self.archive) != self.checksum:
raise Exception(
f"Archive {self.archive} does not match provided checksum")
@@ -159,6 +162,6 @@ class ArchiveArtifact(Artifact):
if self.archive_format == "tar":
cmd = ["tar", "Cxf", location, self.archive]
- print_debug(f"extract archive by running: {cmd} in {self.basedir}")
+ logger.debug("extract archive by running: %s in %s", cmd, self.basedir)
run_cmd(cmd, output_verbosity=1, cwd=self.basedir)
return location
diff --git a/allocbench/benchmark.py b/allocbench/benchmark.py
index 75de4f1..0846e42 100644
--- a/allocbench/benchmark.py
+++ b/allocbench/benchmark.py
@@ -24,6 +24,7 @@ import csv
import importlib
import itertools
import json
+import logging
import multiprocessing
import os
import subprocess
@@ -39,10 +40,11 @@ from allocbench.directories import (get_allocbench_benchmark_src_dir,
get_allocbench_build_dir)
import allocbench.facter as facter
import allocbench.globalvars
-from allocbench.util import print_status, print_error, print_warn
-from allocbench.util import print_info0, print_info, print_debug
+from allocbench.util import print_status
from allocbench.util import find_cmd, prefix_cmd_with_abspath, run_cmd
+logger = logging.getLogger(__file__)
+
AVAIL_BENCHMARKS = [
p.stem for p in get_allocbench_benchmark_src_dir().glob('*.py')
if p.name != "__init__.py"
@@ -69,18 +71,18 @@ class Benchmark:
if proc.poll() is not None:
return proc.communicate()
- print_info("Terminating subprocess", proc.args)
+ logger.info("Terminating subprocess %s", proc.args)
proc.terminate()
try:
outs, errs = proc.communicate(timeout=timeout)
- print_info("Subprocess exited with ", proc.returncode)
+ logger.info("Subprocess exited with %s", proc.returncode)
except subprocess.TimeoutExpired:
- print_error("Killing subprocess ", proc.args)
+ logger.error("Killing subprocess %s", proc.args)
proc.kill()
outs, errs = proc.communicate()
- print_debug("Server Out:", outs)
- print_debug("Server Err:", errs)
+ logger.debug("Server Out: %s", outs)
+ logger.debug("Server Err: %s", errs)
return outs, errs
@staticmethod
@@ -110,14 +112,14 @@ class Benchmark:
def is_perf_allowed():
"""raise an exception if perf is not allowed on this system"""
if Benchmark.perf_allowed is None:
- print_info("Check if you are allowed to use perf ...")
+ logger.info("Check if you are allowed to use perf ...")
try:
run_cmd(["perf", "stat", "ls"], capture=True)
Benchmark.perf_allowed = True
except subprocess.CalledProcessError as err:
- print_error(
- f"Test perf run failed with exit status: {err.returncode}")
- print_debug(err.stderr)
+ logger.error("Test perf run failed with exit status: %s",
+ err.returncode)
+ logger.debug("%s", err.stderr)
Benchmark.perf_allowed = False
if not Benchmark.perf_allowed:
@@ -177,9 +179,8 @@ class Benchmark:
value = row[0]
result[datapoint] = value
except IndexError as err:
- print_warn(
- f"Exception {err} occured on {row} for {alloc_name} and {perm}"
- )
+ logger.warning("Exception %s occured on %s for %s and %s", err,
+ row, alloc_name, perm)
def __str__(self):
return self.name
@@ -229,13 +230,13 @@ class Benchmark:
if not hasattr(self, "requirements"):
self.requirements = []
- print_debug("Creating benchmark", self.name)
- print_debug("Cmd:", self.cmd)
- print_debug("Args:", self.args)
- print_debug("Servers:", self.servers)
- print_debug("Requirements:", self.requirements)
- print_debug("Results dictionary:", self.results)
- print_debug("Results directory:", self.result_dir)
+ logger.debug("Creating benchmark %s", self.name)
+ logger.debug("Cmd: %s", self.cmd)
+ logger.debug("Args: %s", self.args)
+ logger.debug("Servers: %s", self.servers)
+ logger.debug("Requirements: %s", self.requirements)
+ logger.debug("Results dictionary: %s", self.results)
+ logger.debug("Results directory: %s", self.result_dir)
def prepare(self):
"""Default prepare function which only checks dependencies"""
@@ -248,7 +249,7 @@ class Benchmark:
elif os.path.isdir(path):
path = os.path.join(path, self.name + ".json")
- print_info(f"Saving results to: {path}")
+ logger.info("Saving results to: %s", path)
# JSON can't handle namedtuples so convert the dicts of namedtuples
# into lists of dicts.
save_data = {}
@@ -291,7 +292,7 @@ class Benchmark:
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
filename)
- print_info(f"Loading results from: {filename}")
+ logger.info("Loading results from: %s", filename)
# Build new named tuples
for allocator in self.results["allocators"]:
@@ -440,10 +441,10 @@ class Benchmark:
for server in self.servers:
server_name = server.get("name", "Server")
- print_info(f"Starting {server_name} for {alloc_name}")
+ logger.info("Starting %s for %s", server_name, alloc_name)
argv = self.prepare_argv(server["cmd"], env, alloc, substitutions)
- print_debug(argv)
+ logger.debug("%s", argv)
proc = subprocess.Popen(argv,
env=env,
@@ -456,8 +457,8 @@ class Benchmark:
ret = proc.poll()
if ret is not None:
- print_debug("Stdout:", proc.stdout.read())
- print_debug("Stderr:", proc.stderr.read())
+ logger.debug("Stdout: %s", proc.stdout.read())
+ logger.debug("Stderr: %s", proc.stderr.read())
raise Exception(
f"Starting {server_name} failed with exit code: {ret}")
server["popen"] = proc
@@ -479,7 +480,7 @@ class Benchmark:
if not "prepare_cmds" in server:
continue
- print_info(f"Preparing {server_name}")
+ logger.info("Preparing %s", server_name)
for prep_cmd in server["prepare_cmds"]:
prep_cmd = prep_cmd.format(**substitutions)
@@ -489,7 +490,7 @@ class Benchmark:
"""Terminate a started server running its shutdown_cmds in advance"""
if server["popen"].poll() is None:
server_name = server.get("name", "Server")
- print_info(f"Shutting down {server_name}")
+ logger.info("Shutting down %s", server_name)
substitutions = {}
substitutions.update(self.__dict__)
@@ -517,7 +518,7 @@ class Benchmark:
def shutdown_servers(self):
"""Terminate all started servers"""
- print_info("Shutting down servers")
+ logger.info("Shutting down servers")
for server in self.servers:
self.shutdown_server(server)
@@ -552,9 +553,9 @@ class Benchmark:
alloc=alloc,
env=os.environ)
except Exception as err: #pylint: disable=broad-except
- print_debug(traceback.format_exc())
- print_error(err)
- print_error("Skipping", alloc_name)
+ logger.debug("%s", traceback.format_exc())
+ logger.error("%s", err)
+ logger.error("Skipping %s", alloc_name)
skip = True
# Preallocator hook
@@ -575,7 +576,8 @@ class Benchmark:
self.results[alloc_name][perm].append({})
continue
- print_info0(i, "of", total_executions, "\r", end='')
+ # TODO: make this silencable
+ print(i, "of", total_executions, "\r", end='')
# Available substitutions in cmd
substitutions = {"run": run, "alloc": alloc_name}
@@ -602,7 +604,7 @@ class Benchmark:
if hasattr(self, "run_dir"):
run_dir = self.run_dir.format(**substitutions) # pylint: disable=no-member
os.chdir(run_dir)
- print_debug("\nChange cwd to:", run_dir)
+ logger.debug("\nChange cwd to: %s", run_dir)
try:
res = run_cmd(argv, capture=True)
@@ -615,18 +617,16 @@ class Benchmark:
or "Segmentation fault" in res.stderr
or "Aborted" in res.stderr):
print()
- print_debug("Stdout:\n" + res.stdout)
- print_debug("Stderr:\n" + res.stderr)
+ logger.debug("Stdout:\n %s", res.stdout)
+ logger.debug("Stderr:\n %s", res.stderr)
if res.returncode != 0:
- print_error(
- f"{argv} failed with exit code {res.returncode} for {alloc_name}"
- )
+ logger.error("%s failed with exit code %s for %s",
+ argv, res.returncode, alloc_name)
elif "ERROR: ld.so" in res.stderr:
- print_error(
- f"Preloading of {alloc['LD_PRELOAD']} failed for {alloc_name}"
- )
+ logger.error("Preloading of %s failed for %s",
+ alloc['LD_PRELOAD'], alloc_name)
else:
- print_error(f"{argv} terminated abnormally")
+ logger.error("%s terminated abnormally", argv)
# parse and store results
else:
@@ -657,7 +657,7 @@ class Benchmark:
if valid_result is None:
valid_result = result
- print_debug(f"Resulting in: {result}")
+ logger.debug("Resulting in: %s", result)
self.results[alloc_name][perm].append(result)
if os.getcwd() != cwd:
diff --git a/allocbench/benchmarks/mysql.py b/allocbench/benchmarks/mysql.py
index be5c435..e2f7c71 100644
--- a/allocbench/benchmarks/mysql.py
+++ b/allocbench/benchmarks/mysql.py
@@ -72,6 +72,7 @@ allocators algorithm, host system and workload is needed.
"""
import multiprocessing
+import logging
import os
import re
import shutil
@@ -80,7 +81,9 @@ import sys
from allocbench.benchmark import Benchmark
import allocbench.facter as facter
-from allocbench.util import print_status, print_debug, print_info2, print_warn, run_cmd
+from allocbench.util import print_status, run_cmd
+
+logger = logging.getLogger(__file__)
MYSQL_USER = "root"
RUN_TIME = 300
@@ -119,7 +122,7 @@ class BenchmarkMYSQL(Benchmark):
def reset_preparations(self):
"""Reset self.build_dir if preparing fails"""
if os.path.exists(self.build_dir):
- print_warn("Reset mysql test directory")
+ logger.warning("Reset mysql test directory")
shutil.rmtree(self.build_dir, ignore_errors=True)
def prepare(self):
@@ -142,18 +145,18 @@ class BenchmarkMYSQL(Benchmark):
"mysql_install_db", "--basedir=/usr",
f"--datadir={self.build_dir}"
]
- print_info2("MariaDB detected")
+ logger.info("MariaDB detected")
else:
init_db_cmd = [
"mysqld", "-h", self.build_dir, "--initialize-insecure"
]
- print_info2("Oracle MySQL detected")
+ logger.info("Oracle MySQL detected")
try:
run_cmd(init_db_cmd, capture=True)
except CalledProcessError as err:
- print_debug("Stdout:", err.stdout, file=sys.stderr)
- print_debug("Stderr:", err.stderr, file=sys.stderr)
+ logger.debug("Stdout: %s", err.stdout)
+ logger.debug("Stderr: %s", err.stderr)
self.reset_preparations()
raise
@@ -167,7 +170,7 @@ class BenchmarkMYSQL(Benchmark):
capture=True,
cwd=self.build_dir)
except CalledProcessError as err:
- print_debug("Stderr:", err.stderr, file=sys.stderr)
+ logger.debug("Stderr: %s", err.stderr)
self.reset_preparations()
raise
@@ -176,8 +179,8 @@ class BenchmarkMYSQL(Benchmark):
try:
run_cmd(prepare_cmd, capture=True)
except CalledProcessError as err:
- print_debug("Stdout:", err.stdout, file=sys.stderr)
- print_debug("Stderr:", err.stderr, file=sys.stderr)
+ logger.debug("Stdout: %s", err.stdout)
+ logger.debug("Stderr: %s", err.stderr)
self.reset_preparations()
raise
diff --git a/allocbench/facter.py b/allocbench/facter.py
index 8aefbd8..e08e1cd 100644
--- a/allocbench/facter.py
+++ b/allocbench/facter.py
@@ -20,13 +20,16 @@ import ctypes
import datetime
import errno
import json
+import logging
import multiprocessing
import os
import platform
from subprocess import CalledProcessError
from allocbench.directories import get_allocbench_build_dir
-from allocbench.util import print_debug, print_info, print_warn, run_cmd
+from allocbench.util import run_cmd
+
+logger = logging.getLogger(__file__)
FACTS = {}
@@ -63,7 +66,7 @@ def store_facts(path=None):
else:
filename = path
- print_info(f"Saving facts to: {filename}")
+ logger.info("Saving facts to: %s", filename)
with open(filename, "w") as facts_file:
json.dump(FACTS, facts_file)
@@ -87,7 +90,7 @@ def load_facts(path=None):
filename)
FACTS.update(loaded_facts)
- print_info(f"Loading facts from: {filename}")
+ logger.info("Loading facts from: %s", filename)
def allocbench_version():
@@ -168,8 +171,8 @@ def exe_version(executable, version_flag="--version"):
try:
proc = run_cmd([executable, version_flag], capture=True)
except CalledProcessError as err:
- print_warn(f"failed to get version of {executable}")
- print_debug(err.stderr)
+ logger.warning("failed to get version of %s", executable)
+ logger.debug("%s", err.stderr)
return ""
return proc.stdout[:-1]
diff --git a/allocbench/plots.py b/allocbench/plots.py
index ef69214..c2a9aa0 100644
--- a/allocbench/plots.py
+++ b/allocbench/plots.py
@@ -19,6 +19,7 @@
import ast
import copy
import itertools
+import logging
import operator
import os
import re
@@ -31,7 +32,8 @@ import numpy as np
import scipy.stats
import allocbench.facter as facter
-from allocbench.util import print_debug, print_warn
+
+logger = logging.getLogger(__file__)
# This is useful when evaluating strings in the plot functions. str(np.NaN) == "nan"
nan = np.NaN # pylint: disable=invalid-name
@@ -129,9 +131,9 @@ def _eval_with_stat(bench, evaluation, alloc, perm, stat):
try:
expr = evaluation.format(**bench.results["stats"][alloc][perm][stat])
except KeyError:
- print_debug(traceback.format_exc())
- print_warn(
- f"KeyError while expanding {evaluation} for {alloc} and {perm}")
+ logger.debug("%s", traceback.format_exc())
+ logger.warning("KeyError while expanding %s for %s and %s", evaluation,
+ alloc, perm)
return nan
node = ast.parse(expr, mode='eval')
@@ -139,8 +141,9 @@ def _eval_with_stat(bench, evaluation, alloc, perm, stat):
try:
return _eval(node.body)
except TypeError:
- print_debug(traceback.format_exc())
- print_warn(f"{expr} could not be evaluated as arithmetic operation")
+ logger.debug("%s", traceback.format_exc())
+ logger.warning("%s could not be evaluated as arithmetic operation",
+ expr)
return nan
@@ -281,7 +284,7 @@ def _plot(bench,
try:
plot_func = getattr(plt, plot_type)
except AttributeError:
- print_debug(f'Unknown plot type: {plot_type}')
+ logger.debug('Unknown plot type: %s', plot_type)
raise
_x_data = x_data
@@ -309,7 +312,7 @@ def _plot(bench,
fig_path = os.path.join(sumdir, f'{fig_options["fig_label"]}.{file_ext}')
if file_ext == 'tex':
- import tikzplotlib
+ import tikzplotlib # pylint: disable=import-outside-toplevel
tikzplotlib.save(fig_path)
else:
fig.savefig(fig_path)
diff --git a/allocbench/util.py b/allocbench/util.py
index 106c4d9..73bdd9a 100644
--- a/allocbench/util.py
+++ b/allocbench/util.py
@@ -17,14 +17,31 @@
"""Helper functions for allocbench"""
import hashlib
+import logging
import os
import subprocess
import sys
-# Verbosity level -1: quiet, 0: status, 1: info, 2: stdout of subcommands, 3: debug info
+# Verbosity level -1: quiet, 0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG
VERBOSITY = 0
+def set_verbosity(verbosity: int):
+ """Set global logging level
+
+ 0 (default): logging.WARNING
+ 1: logging.INFO
+ 2: logging.DEBUG
+ """
+ loglevels = [logging.ERROR, logging.INFO, logging.DEBUG]
+ logging.basicConfig(level=loglevels[verbosity])
+ global VERBOSITY
+ VERBOSITY = verbosity
+
+
+logger = logging.getLogger(__file__)
+
+
def run_cmd(cmd,
output_verbosity=2,
capture=False,
@@ -43,7 +60,7 @@ def run_cmd(cmd,
stdout = None
stderr = stdout
- print_debug(f"Running command {cmd}")
+ logger.debug("Running command %s", cmd)
return subprocess.run(cmd,
stdout=stdout,
@@ -118,51 +135,11 @@ def allocbench_msg(color, *objects, sep=' ', end='\n', file=None):
print("\x1b[0m", end="", file=file, flush=True)
-def print_debug(*objects, sep=' ', end='\n', file=None):
- """Print colorless debug message"""
- if VERBOSITY < 3:
- return
- print(*objects, sep=sep, end=end, file=file)
-
-
-def print_info(*objects, sep=' ', end='\n', file=None):
- """Print colorless info message"""
- if VERBOSITY < 1:
- return
- print(*objects, sep=sep, end=end, file=file)
-
-
-def print_info0(*objects, sep=' ', end='\n', file=None):
- """Print colorless info message at every verbosity level message"""
- if VERBOSITY < 0:
- return
- print(*objects, sep=sep, end=end, file=file)
-
-
-def print_info2(*objects, sep=' ', end='\n', file=None):
- """Print colorless info message at the second verbosity level message"""
- if VERBOSITY < 2:
- return
- print(*objects, sep=sep, end=end, file=file)
-
-
def print_status(*objects, sep=' ', end='\n', file=None):
"""Print green status message"""
allocbench_msg("GREEN", *objects, sep=sep, end=end, file=file)
-def print_warn(*objects, sep=' ', end='\n', file=None):
- """Print yellow warning"""
- if VERBOSITY < 1:
- return
- allocbench_msg("YELLOW", *objects, sep=sep, end=end, file=file)
-
-
-def print_error(*objects, sep=' ', end='\n', file=sys.stderr):
- """Print red error message"""
- allocbench_msg("RED", *objects, sep=sep, end=end, file=file)
-
-
def print_license_and_exit():
"""Print GPL info and Copyright before exit"""
print("Copyright (C) 2018-2020 Florian Fischer")
@@ -177,6 +154,6 @@ def sha1sum(filename):
barray = bytearray(64 * 1024)
view = memoryview(barray)
with open(filename, 'rb', buffering=0) as input_file:
- for n in iter(lambda: input_file.readinto(view), 0):
- sha1.update(view[:n])
+ for bytes_read in iter(lambda: input_file.readinto(view), 0):
+ sha1.update(view[:bytes_read])
return sha1.hexdigest()
diff --git a/bench.py b/bench.py
index 7cb93f8..e43ad1c 100755
--- a/bench.py
+++ b/bench.py
@@ -21,6 +21,7 @@
import argparse
import atexit
import datetime
+import logging
import os
import sys
import traceback
@@ -31,14 +32,12 @@ from allocbench.benchmark import get_benchmark_object
from allocbench.directories import get_current_result_dir, set_current_result_dir
import allocbench.facter as facter
import allocbench.globalvars
-import allocbench.util
-from allocbench.util import run_cmd
-from allocbench.util import print_status, print_warn, print_error
-from allocbench.util import print_info, print_info2, print_debug
-from allocbench.util import print_license_and_exit
+from allocbench.util import run_cmd, print_status, print_license_and_exit
from summarize import summarize
+logger = logging.getLogger(__file__)
+
def epilog():
"""Run tasks on exit"""
@@ -52,7 +51,7 @@ def epilog():
return
if not res_dir.iterdir():
- print_warn("Remove empty resultdir")
+ logger.warning("Remove empty resultdir")
res_dir.rmdir()
else:
endtime = datetime.datetime.now().isoformat()
@@ -65,7 +64,7 @@ def check_dependencies():
"""Check if known requirements of allocbench are met"""
# used python 3.6 features: f-strings
if sys.version_info[0] < 3 or sys.version_info[1] < 6:
- print_error("At least python version 3.6 is required.")
+ logger.critical("At least python version 3.6 is required.")
sys.exit(1)
@@ -84,7 +83,11 @@ def main():
help="how often the benchmarks run",
default=3,
type=int)
- parser.add_argument("-v", "--verbose", help="more output", action='count')
+ parser.add_argument("-v",
+ "--verbose",
+ help="more output",
+ action='count',
+ default=0)
parser.add_argument("-b",
"--benchmarks",
help="benchmarks to run",
@@ -122,31 +125,33 @@ def main():
atexit.register(epilog)
# Set global verbosity
- # quiet | -1: Don't output to stdout
- # default | 0: Only print status and errors
- # 1: Print warnings and some infos
- # 2: Print all infos
- # 3: Print everything
- if args.verbose:
- allocbench.util.VERBOSITY = args.verbose
+ # default | 0: Only print status, errors and warnings
+ # 1: Print above plus infos
+ # 2: Print above plus debug information
+ loglevels = [logging.ERROR, logging.INFO, logging.DEBUG]
+ logging.basicConfig(level=loglevels[args.verbose])
+ allocbench.util.VERBOSITY = args.verbose
- print_info2("Arguments:", args)
+ logger.debug("Arguments: %s", args)
# Prepare allocbench
print_status("Building allocbench ...")
make_cmd = ["make"]
- if allocbench.util.VERBOSITY < 2:
+ if args.verbose < 2:
make_cmd.append("-s")
run_cmd(make_cmd, output_verbosity=1)
# allocators to benchmark
- allocbench.globalvars.ALLOCATORS = collect_allocators(args.allocators)
+ allocators = collect_allocators(args.allocators)
+ allocbench.globalvars.ALLOCATORS = allocators
- print_info("Allocators:", *allocbench.globalvars.ALLOCATORS.keys())
- print_debug("Allocators:", *allocbench.globalvars.ALLOCATORS.items())
+ logger.info(f"Allocators: {'%s, ' * (len(allocators) - 1)}%s",
+ *allocators.keys())
+ logger.debug(f"Allocators: {'%s, ' * (len(allocators) - 1)}%s",
+ *allocators.items())
- if allocbench.globalvars.ALLOCATORS == {}:
- print_error("Abort because there are no allocators to benchmark")
+ if not allocators:
+ logger.critical("Abort because there are no allocators to benchmark")
sys.exit(1)
# collect facts about benchmark environment
@@ -167,7 +172,7 @@ def main():
# warn about unknown benchmarks
for bench in (args.benchmarks or []) + (args.exclude_benchmarks or []):
if bench not in allocbench.benchmark.AVAIL_BENCHMARKS:
- print_error(f'Benchmark "{bench}" unknown!')
+ logger.error('Benchmark "%s" unknown!', bench)
# Run actual benchmarks
for bench in allocbench.benchmark.AVAIL_BENCHMARKS:
@@ -181,16 +186,16 @@ def main():
print_status("Loading", bench, "...")
bench = get_benchmark_object(bench)
except Exception: #pylint: disable=broad-except
- print_error(traceback.format_exc())
- print_error(f"Skipping {bench}! Loading failed.")
+ logger.error(traceback.format_exc())
+ logger.error("Skipping %s! Loading failed.", bench)
continue
try:
print_status("Preparing", bench, "...")
bench.prepare()
except Exception: #pylint: disable=broad-except
- print_error(traceback.format_exc())
- print_error(f"Skipping {bench}! Preparing failed.")
+ logger.error(traceback.format_exc())
+ logger.error("Skipping %s! Preparing failed.", bench)
continue
if args.analyze:
@@ -208,8 +213,8 @@ def main():
except Exception: #pylint: disable=broad-except
# Reset cwd
os.chdir(cwd)
- print_error(traceback.format_exc())
- print_error("Skipping", bench, "!")
+ logger.error(traceback.format_exc())
+ logger.error("Skipping %s!", bench)
continue
end_time = datetime.datetime.now()
diff --git a/summarize.py b/summarize.py
index 7c19cab..2c1a27c 100755
--- a/summarize.py
+++ b/summarize.py
@@ -19,6 +19,7 @@
"""Summarize the results of an allocbench run"""
import argparse
+import logging
import os
import sys
@@ -27,8 +28,9 @@ import allocbench.facter as facter
import allocbench.globalvars
import allocbench.benchmark
import allocbench.util
-from allocbench.util import print_status, print_debug, print_error
-from allocbench.util import print_license_and_exit
+from allocbench.util import print_status, set_verbosity, print_license_and_exit
+
+logger = logging.getLogger(__file__)
def specific_summary(bench, sum_dir, allocators):
@@ -49,13 +51,13 @@ def specific_summary(bench, sum_dir, allocators):
explicit_colors = [
v["color"] for k, v in allocs_in_set.items() if v["color"] is not None
]
- print_debug("Explicit colors:", explicit_colors)
+ logger.debug("Explicit colors: %s", explicit_colors)
cycle_list = ["C" + str(i) for i in range(0, 10)]
avail_colors = [
color for color in cycle_list if color not in explicit_colors
]
- print_debug("available colors:", avail_colors)
+ logger.debug("available colors: %s", avail_colors)
for _, value in allocs_in_set.items():
if value["color"] is None:
@@ -132,7 +134,7 @@ def summarize(benchmarks=None,
try:
bench = allocbench.benchmark.get_benchmark_object(benchmark)
except Exception: #pylint: disable=broad-except
- print_error(f"Skipping {benchmark}. Loading failed")
+ logger.error("Skipping %s. Loading failed", benchmark)
continue
try:
@@ -144,7 +146,7 @@ def summarize(benchmarks=None,
try:
bench_sum(bench, exclude_allocators=exclude_allocators, sets=sets)
except FileExistsError as err:
- print(err)
+ logger.error("%s", err)
os.chdir(cwd)
@@ -165,7 +167,11 @@ def main():
help="print version info and exit",
action='version',
version=f"allocbench {facter.allocbench_version()}")
- parser.add_argument("-v", "--verbose", help="more output", action='count')
+ parser.add_argument("-v",
+ "--verbose",
+ help="more output",
+ action='count',
+ default=0)
parser.add_argument("-b",
"--benchmarks",
help="benchmarks to summarize",
@@ -193,8 +199,7 @@ def main():
args = parser.parse_args()
- if args.verbose:
- allocbench.util.VERBOSITY = args.verbose
+ set_verbosity(args.verbose)
if args.file_ext:
allocbench.plots.summary_file_ext = args.file_ext
@@ -203,7 +208,7 @@ def main():
allocbench.plots.latex_custom_preamble = args.latex_preamble
if not os.path.isdir(args.results):
- print_error(f"{args.results} is no directory")
+ logger.critical(f"%s is no directory", args.results)
sys.exit(1)
set_current_result_dir(args.results)