Skip to content

Commit d736308

Browse files
authored
Merge branch 'develop' into feat/results-db-enhancements
2 parents 8ad6283 + 46e7166 commit d736308

File tree

16 files changed

+88656
-59
lines changed

16 files changed

+88656
-59
lines changed

.github/workflows/test-flux.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ jobs:
2828

2929
- name: Install Reframe
3030
run: |
31-
apt-get update && apt-get install -y python3-pip curl
32-
/bin/bash ./bootstrap.sh
31+
apt-get update && apt-get install -y python3-pip
32+
./bootstrap.sh
3333
export PATH=$PWD/bin:$PATH
3434
which reframe
3535

.github/workflows/test-schedulers.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ jobs:
1919
- name: Build Images
2020
run: |
2121
docker compose -f .github/pseudo-cluster/docker-compose.yml build
22-
- name: Run Unittests with ${{ matrix.scheduler }} sceduler
22+
- name: Run Unittests with ${{ matrix.scheduler }} scheduler
2323
run: |
2424
BACKEND=${{ matrix.scheduler }} docker compose -f .github/pseudo-cluster/docker-compose.yml up --abort-on-container-exit --exit-code-from frontend

bootstrap.sh

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,16 @@ py_pkg_prefix=external/$(uname -m)
101101
# Install a fresh pip in the current environment
102102
pyver=$(python3 -c 'import sys; print(".".join(str(s) for s in sys.version_info[:2]))')
103103
if [ "$pyver" == "3.6" ]; then
104-
get_pip_url="https://bootstrap.pypa.io/pip/3.6/get-pip.py"
104+
get_pip="$PWD/tools/python/3.6/get-pip.py"
105105
elif [ "$pyver" == "3.7" ]; then
106-
get_pip_url="https://bootstrap.pypa.io/pip/3.7/get-pip.py"
106+
get_pip="$PWD/tools/python/3.7/get-pip.py"
107107
else
108-
get_pip_url="https://bootstrap.pypa.io/get-pip.py"
108+
get_pip="$PWD/tools/python/get-pip.py"
109109
fi
110110

111-
if ! type "curl" > /dev/null 2>&1; then
112-
echo -e "could not find \`curl': please install curl and try again"
113-
exit 1
114-
fi
115-
116-
INFO "curl -s $get_pip_url | $python"
117-
curl -s $get_pip_url | $python
118-
119-
export PATH=$(pwd)/$py_pkg_prefix/usr/bin:$PATH
120-
export PYTHONPATH=$(pwd)/$py_pkg_prefix:$PYTHONPATH
111+
$python $get_pip
112+
export PATH=$PWD/$py_pkg_prefix/usr/bin:$PATH
113+
export PYTHONPATH=$PWD/$py_pkg_prefix:$PYTHONPATH
121114
if [ -n "$PYGELF" ]; then
122115
tmp_requirements=$(mktemp)
123116
sed -e 's/^#+pygelf%//g' requirements.txt > $tmp_requirements

ci-scripts/dockerfiles/eb-spack-howto.dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
FROM ghcr.io/reframe-hpc/lmod:8.4.12
77

8-
ENV _SPACK_VER=0.16
9-
ENV _EB_VER=4.4.1
8+
ENV _SPACK_VER=0.22.2
9+
ENV _EB_VER=4.9.4
1010

1111

1212
# Install ReFrame unit test requirements
@@ -19,7 +19,7 @@ RUN useradd -ms /bin/bash rfmuser
1919
USER rfmuser
2020

2121
# Install Spack
22-
RUN git clone --branch releases/v${_SPACK_VER} https://github.com/spack/spack ~/spack && \
22+
RUN git clone --branch v${_SPACK_VER} https://github.com/spack/spack ~/spack && \
2323
cd ~/spack
2424

2525
RUN pip3 install easybuild==${_EB_VER}

ci-scripts/dockerfiles/reframe-lmod.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ FROM ghcr.io/reframe-hpc/lmod:8.4.12
77

88
# Install ReFrame unit test requirements
99
RUN apt-get -y update && \
10-
apt-get -y install gcc git make python3 python3-pip curl
10+
apt-get -y install gcc git make python3 python3-pip
1111

1212
# ReFrame user
1313
RUN useradd -ms /bin/bash rfmuser

ci-scripts/dockerfiles/reframe-lmod77.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ FROM ghcr.io/reframe-hpc/lmod:7.7
77

88
# Install ReFrame unit test requirements
99
RUN apt-get -y update && \
10-
apt-get -y install gcc make python3 python3-pip curl
10+
apt-get -y install gcc make python3 python3-pip
1111

1212
# ReFrame user
1313
RUN useradd -ms /bin/bash rfmuser

ci-scripts/dockerfiles/reframe-tmod4.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ FROM ghcr.io/reframe-hpc/tmod:4.6.0
88
# ReFrame requirements
99
RUN \
1010
apt-get -y update && \
11-
apt-get -y install gcc make git python3 python3-pip curl
11+
apt-get -y install gcc make git python3 python3-pip
1212

1313
# ReFrame user
1414
RUN useradd -ms /bin/bash rfmuser

docs/howto.rst

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,3 +1162,63 @@ If you use a Python-based configuration file, you can define your custom launche
11621162
.. note::
11631163

11641164
In versions prior to 4.0, launchers could only be implemented inside the source code tree of ReFrame.
1165+
1166+
1167+
.. _custom-loggers:
1168+
1169+
Implementing a custom log handler
1170+
---------------------------------
1171+
1172+
.. versionadded:: 4.7
1173+
1174+
ReFrame allows you to define custom log handlers and attach them to the framework.
1175+
Here's an example implementation of a custom log handler and how it can be used in a Python-based configuration file.
1176+
1177+
Define a custom log handler class based on :class:`~logging.Handler` which uses a custom logging API:
1178+
1179+
.. code-block:: python
1180+
1181+
import logging
1182+
import mylogger
1183+
1184+
class MyLoggerHandler(logging.Handler):
1185+
def __init__(self, key):
1186+
super().__init__()
1187+
self.key = key
1188+
1189+
def emit(self, record):
1190+
myrecord = {
1191+
'value': record.check_perf_value,
1192+
}
1193+
mylogger.log(self.key, myrecord)
1194+
1195+
Applying the :func:`@register_log_handler <reframe.core.logging.register_log_handler>` decorator to a function returns an instance of the custom log handler:
1196+
1197+
.. code-block:: python
1198+
1199+
from reframe.core.logging import register_log_handler
1200+
1201+
@register_log_handler("mylogger")
1202+
def _create_mylogger_handler(site_config, config_prefix):
1203+
key = site_config.get(f'{config_prefix}/key')
1204+
return MyLoggerHandler(key)
1205+
1206+
1207+
Finally, add a handler entry with type matching the registered name for the custom log handler to the site config:
1208+
1209+
.. code-block:: python
1210+
1211+
site_configuration = {
1212+
'logging': [
1213+
{
1214+
'handlers': [
1215+
{
1216+
'type': 'mylogger',
1217+
'key': 'abc',
1218+
},
1219+
...
1220+
]
1221+
}
1222+
],
1223+
...
1224+
}

reframe/core/decorators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def instantiate_all(self, reset_sysenv=0, external_vars=None):
104104
kwargs['reset_sysenv'] = reset_sysenv
105105
leaf_tests.append(test(*args, **kwargs))
106106
except SkipTestError as e:
107-
getlogger().warning(
107+
getlogger().verbose(
108108
f'skipping test {test.__qualname__!r}: {e}'
109109
)
110110
except Exception:

reframe/core/logging.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,20 @@ def stream_handler_kind(handler):
412412
return logger
413413

414414

415+
# Registry for log handler creation functions
416+
_create_handlers = {}
417+
418+
419+
def register_log_handler(name):
420+
'''Register the decorated log handler creation function'''
421+
def _create_handler_wrapper(fn):
422+
_create_handlers[name] = fn
423+
return fn
424+
425+
return _create_handler_wrapper
426+
427+
428+
@register_log_handler('file')
415429
def _create_file_handler(site_config, config_prefix):
416430
filename = os.path.expandvars(site_config.get(f'{config_prefix}/name'))
417431
if not filename:
@@ -431,6 +445,7 @@ def _create_file_handler(site_config, config_prefix):
431445
mode='a+' if append else 'w+')
432446

433447

448+
@register_log_handler('filelog')
434449
def _create_filelog_handler(site_config, config_prefix):
435450
basedir = os.path.abspath(os.path.join(
436451
site_config.get('systems/0/prefix'),
@@ -447,6 +462,7 @@ def _create_filelog_handler(site_config, config_prefix):
447462
ignore_keys=ignore_keys)
448463

449464

465+
@register_log_handler('syslog')
450466
def _create_syslog_handler(site_config, config_prefix):
451467
address = site_config.get(f'{config_prefix}/address')
452468

@@ -485,6 +501,7 @@ def _create_syslog_handler(site_config, config_prefix):
485501
return logging.handlers.SysLogHandler(address, facility_type, socket_type)
486502

487503

504+
@register_log_handler('stream')
488505
def _create_stream_handler(site_config, config_prefix):
489506
stream = site_config.get(f'{config_prefix}/name')
490507
if stream == 'stdout':
@@ -496,6 +513,7 @@ def _create_stream_handler(site_config, config_prefix):
496513
raise AssertionError(f'unknown stream: {stream}')
497514

498515

516+
@register_log_handler('graylog')
499517
def _create_graylog_handler(site_config, config_prefix):
500518
try:
501519
import pygelf
@@ -528,6 +546,7 @@ def _create_graylog_handler(site_config, config_prefix):
528546
json_default=jsonext.encode)
529547

530548

549+
@register_log_handler('httpjson')
531550
def _create_httpjson_handler(site_config, config_prefix):
532551
url = site_config.get(f'{config_prefix}/url')
533552
extras = site_config.get(f'{config_prefix}/extras')
@@ -684,35 +703,18 @@ def _extract_handlers(site_config, handlers_group):
684703
handlers = []
685704
for i, handler_config in enumerate(handlers_list):
686705
handler_type = handler_config['type']
687-
if handler_type == 'file':
688-
hdlr = _create_file_handler(site_config, f'{handler_prefix}/{i}')
689-
elif handler_type == 'filelog':
690-
hdlr = _create_filelog_handler(
691-
site_config, f'{handler_prefix}/{i}'
692-
)
693-
elif handler_type == 'syslog':
694-
hdlr = _create_syslog_handler(site_config, f'{handler_prefix}/{i}')
695-
elif handler_type == 'stream':
696-
hdlr = _create_stream_handler(site_config, f'{handler_prefix}/{i}')
697-
elif handler_type == 'graylog':
698-
hdlr = _create_graylog_handler(
699-
site_config, f'{handler_prefix}/{i}'
700-
)
701-
if hdlr is None:
702-
getlogger().warning('could not initialize the '
703-
'graylog handler; ignoring ...')
704-
continue
705-
elif handler_type == 'httpjson':
706-
hdlr = _create_httpjson_handler(
707-
site_config, f'{handler_prefix}/{i}'
708-
)
709-
if hdlr is None:
710-
getlogger().warning('could not initialize the '
711-
'httpjson handler; ignoring ...')
712-
continue
713-
else:
714-
# Should not enter here
715-
raise AssertionError(f'unknown handler type: {handler_type}')
706+
707+
try:
708+
create_handler = _create_handlers[handler_type]
709+
except KeyError:
710+
raise ConfigError(
711+
f'unknown handler type: {handler_type}') from None
712+
713+
hdlr = create_handler(site_config, f'{handler_prefix}/{i}')
714+
if hdlr is None:
715+
getlogger().warning('could not initialize the '
716+
f'{handler_type} handler; ignoring ...')
717+
continue
716718

717719
level = site_config.get(f'{handler_prefix}/{i}/level')
718720
fmt = site_config.get(f'{handler_prefix}/{i}/format')

0 commit comments

Comments
 (0)