Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker/Dockerfiles/dev/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ENV RALLY_RUNNING_IN_DOCKER=True
USER root

RUN apk update
RUN apk add curl git gcc pigz bash zstd bzip2 gzip openssh
RUN apk add curl git gcc pigz bash zstd bzip2 gzip openssh procps

# pbzip2 doesn't have a package for wolfi, so we build it from source
RUN apk add bzip2-dev make wget
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfiles/release/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ENV RALLY_RUNNING_IN_DOCKER=True
USER root

RUN apk update
RUN apk add curl git gcc pigz bash zstd bzip2 gzip openssh
RUN apk add curl git gcc pigz bash zstd bzip2 gzip openssh procps

# pbzip2 doesn't have a package for wolfi, so we build it from source
RUN apk add bzip2-dev make wget
Expand Down
48 changes: 48 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,51 @@ Here is an example of a logging configuration that uses ``${LOG_PATH}``::
}
}
}


Example
~~~~~~~

With the following configuration Rally will log to ``~/.rally/logs/rally.log`` and ``~/.rally/logs/rally.json``, the
latter being a JSON file::

{
"version": 1,
"formatters": {
"normal": {
"format": "%(asctime)s,%(msecs)d %(actorAddress)s/PID:%(process)d %(name)s %(levelname)s %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
"()": "esrally.log.configure_utc_formatter"
},
"json": {
"datefmt": "%Y-%m-%d %H:%M:%S",
"class": "pythonjsonlogger.jsonlogger.JsonFormatter"
}
},
"handlers": {
"rally_log_handler": {
"()": "esrally.log.configure_file_handler",
"filename": "${LOG_PATH}/rally.log",
"encoding": "UTF-8",
"formatter": "normal"
},
"rally_json_handler": {
"()": "esrally.log.configure_file_handler",
"filename": "${LOG_PATH}/rally.json",
"encoding": "UTF-8",
"formatter": "json"
}
},
"root": {
"handlers": ["rally_log_handler", "rally_json_handler"],
"level": "INFO"
},
"loggers": {
"elasticsearch": {
"handlers": ["rally_log_handler", "rally_json_handler"],
"level": "WARNING",
"propagate": false
}
}
}

5 changes: 2 additions & 3 deletions esrally/rally.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,10 +1287,9 @@ def _trap(function, path, exc_info):
logger.info("Cleaning track dependency directory [%s]...", paths.libs())

if sys.version_info.major == 3 and sys.version_info.minor <= 11:
# pylint: disable=deprecated-argument
shutil.rmtree(paths.libs(), onerror=_trap)
shutil.rmtree(paths.libs(), onerror=_trap) # pylint: disable=deprecated-argument, disable=useless-suppression
else:
shutil.rmtree(paths.libs(), onexc=_trap_exc)
shutil.rmtree(paths.libs(), onexc=_trap_exc) # pylint: disable=unexpected-keyword-arg, disable=useless-suppression

result = dispatch_sub_command(arg_parser, args, cfg)

Expand Down
14 changes: 12 additions & 2 deletions esrally/rallyd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import argparse
import logging
import os
import sys
import time

Expand All @@ -30,14 +31,23 @@
log,
version,
)
from esrally.utils import console
from esrally.utils import console, process


def start(args):
if actor.actor_system_already_running():
raise exceptions.RallyError("An actor system appears to be already running.")
actor.bootstrap_actor_system(local_ip=args.node_ip, coordinator_ip=args.coordinator_ip)
console.info("Successfully started actor system on node [%s] with coordinator node IP [%s]." % (args.node_ip, args.coordinator_ip))
console.info(f"Successfully started actor system on node [{args.node_ip}] with coordinator node IP [{args.coordinator_ip}].")

if console.RALLY_RUNNING_IN_DOCKER:
console.info(f"Running with PID: {os.getpid()}")
while process.wait_for_child_processes(
callback=lambda process: console.info(f"Actor with PID [{process.pid}] terminated with status [{process.returncode}]."),
list_callback=lambda children: console.info(f"Waiting for child processes ({[p.pid for p in children]}) to terminate..."),
):
pass
console.info("All actors terminated, exiting.")


def stop(raise_errors=True):
Expand Down
27 changes: 26 additions & 1 deletion esrally/utils/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import shlex
import subprocess
import time
from typing import IO, Callable, List, Mapping, Optional, Union
from typing import IO, Callable, Iterable, List, Mapping, Optional, Union

import psutil

Expand Down Expand Up @@ -229,3 +229,28 @@ def rally_process(p: psutil.Process) -> bool:
)

kill_all(rally_process)


def wait_for_child_processes(
timeout: Optional[float] = None,
callback: Optional[Callable[[psutil.Process], None]] = None,
list_callback: Optional[Callable[[Iterable[psutil.Process]], None]] = None,
) -> bool:
"""
Waits for all child processes to terminate.

:param timeout: The maximum time to wait for child processes to terminate (default: None).
:param callback: A callback to call as each child process terminates.
The callback will be passed the PID and the return code of the child process.
:param list_callback: A callback to tell caller about the child processes that are being waited for.

:return: False if no child processes found, True otherwise.
"""
current = psutil.Process()
children = current.children(recursive=True)
if not children:
return False
if list_callback is not None:
list_callback(children)
psutil.wait_procs(children, timeout=timeout, callback=callback)
return True
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ dependencies = [
"zstandard==0.21.0",
# License: Python Software Foundation License
"typing-extensions==4.12.2",
# License: BSD-2-Clause license
"python-json-logger==2.0.7",
Copy link
Copy Markdown
Contributor Author

@favilo favilo Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't used directly, but it allows us to specify JSON logs in our logging.json configuration. Useful if you are using docker, and can't add dependencies in your virtual environment.

See change in configuration.rst for example of how to do this.

]

[project.optional-dependencies]
Expand Down