This release is a pre-release and may not be stable for production use.
wazuhtester
wazuhtester is a Python library and command-line tool for interacting with the
Wazuh wazuh-logtest daemon. It handles the Unix-socket
wire protocol, daemon sessions, and response parsing so rule and decoder tests do
not need to reimplement the framing and JSON envelope.
It was extracted from wazuh-devenv,
which consumes the package instead of carrying its own protocol client. See
ROADMAP.md for the release and migration sequence.
Status
Release candidate (0.1.0rc1). The package is awaiting live Wazuh corpus qualification before its first PyPI release.
Installation
Install the package into a Python environment for library use:
python -m pip install wazuhtester
For command-line-only use, pipx is the preferred installation model once the
package is published:
pipx install wazuhtester
A local checkout can be installed with:
pipx install --editable .
The package requires Python 3.10+, Linux, and a reachable wazuh-logtest Unix
socket from a running Wazuh manager. It does not install or run Wazuh itself.
Importing wazuhtester on a non-Linux platform fails immediately with an
explicit unsupported-platform error. WSL is supported because Python reports the
WSL environment as Linux.
Python API
For a single independent event:
from wazuhtester import LogtestStatus, send_log
response = send_log(
"Oct 10 10:00:00 host sshd[1234]: "
"Failed password for root from 1.2.3.4 port 22 ssh2"
)
assert response.status == LogtestStatus.RuleMatch
print(response.rule_id)
print(response.rule_description)
A one-shot send_log() call owns the daemon session it creates and removes it
before returning. Supplying an explicit token means the caller owns that
existing session, so send_log() does not remove it.
For stateful, frequency, or composite rules, send the sequence in one session:
from wazuhtester import LogtestStatus, send_multiple_logs
logs = [
"sshd: Failed password for invalid user admin from 1.2.3.4 port 22 ssh2",
"sshd: Failed password for invalid user admin from 1.2.3.4 port 22 ssh2",
"sshd: Failed password for invalid user admin from 1.2.3.4 port 22 ssh2",
]
responses = send_multiple_logs(logs)
assert responses[-1].status == LogtestStatus.RuleMatch
For explicit session control, LogtestSession automatically reuses the token
returned by the daemon:
from wazuhtester import LogtestResponse, LogtestSession
with LogtestSession() as session:
first = LogtestResponse(session.process_log("event one"))
second = LogtestResponse(session.process_log("event two"))
The second request uses the token returned by the first. Exiting the context removes the active daemon session.
CLI
Installing the package exposes the wazuhtester console command. The executable
name deliberately does not use wazuh-logtest, which is the name of Wazuh's
native tool.
The console-script and module entry points are equivalent:
wazuhtester
python -m wazuhtester
The CLI reads one log record per line from stdin. All records in one invocation share one daemon session, preserving correlation and frequency semantics:
printf '%s\n' \
'sshd: Failed password for invalid user admin from 1.2.3.4 port 22 ssh2' \
'sshd: Failed password for invalid user admin from 1.2.3.4 port 22 ssh2' |
wazuhtester
Useful options:
-l, --location TEXT
-f, --log-format FORMAT
-s, --socket PATH
--json
--version
-h, --help
--json emits one JSON object per input record (NDJSON), suitable for shell
pipelines:
cat samples.log | wazuhtester --json | jq 'select(.rule_id == "5710")'
A valid event that produces no rule match is still a successful CLI operation. Runtime communication or protocol failures return exit code 1, argparse usage errors return 2, and Ctrl+C returns 130.
Configuring the socket path
By default the client uses:
/var/ossec/queue/sockets/logtest
Override it through the environment:
export WAZUH_LOGTEST_SOCKET=/path/to/logtest.sock
or per call:
from wazuhtester import send_log
send_log("...", socket_path="/path/to/logtest.sock")
Check reachability without sending a log:
from wazuhtester import is_logtest_available
if not is_logtest_available():
raise SystemExit("wazuh-logtest is not reachable")
pytest plugin
Installing wazuhtester also registers a pytest plugin through the pytest11
entry point. It is deliberately opt-in for daemon availability checks.
@pytest.mark.wazuh_logtestmarks a test as requiring a live daemon. Marked tests are skipped if the daemon is unavailable.--wazuh-require-logtest, or thewazuh_require_logtestini option, makes an unavailable daemon fatal for the test session.--wazuh-socket PATHoverrides the socket path for the test run.logtest_sessionprovides aLogtestSessionand removes its active session during teardown.send_logexposes the high-level one-shot API as a fixture.
import pytest
@pytest.mark.wazuh_logtest
def test_custom_rule(send_log):
response = send_log("...")
assert response.rule_id == "100100"
API surface
| Name | Purpose |
|---|---|
send_log(...) |
Send one event and return a LogtestResponse. A newly created daemon session is cleaned up automatically. |
send_multiple_logs(...) |
Send an ordered sequence in one daemon session and return one response per event. |
LogtestSession |
Lower-level session API. Automatically reuses the current daemon token and supports context-manager cleanup. |
LogtestResponse |
Parsed daemon response with status, decoder, rule, static and dynamic fields. to_dict() returns deterministic JSON-compatible data. |
LogtestStatus |
RuleMatch, Error, NoDecoder, or NoRule. |
is_logtest_available(...) |
Probe the configured Unix socket without sending an event. |
get_socket_path() |
Resolve the socket path, including WAZUH_LOGTEST_SOCKET. |
LogtestError hierarchy |
Distinguish connection, daemon, and protocol failures while preserving compatible builtin base classes. |
Development
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
.venv/bin/mypy src/wazuhtester
The test suite uses a fake AF_UNIX server that implements the Wazuh logtest
framing, so a Wazuh installation is not required for normal package CI.
License
GNU General Public License version 2 only — see LICENSE.
Release files for wazuhtester 0.1.0rc1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wazuhtester-0.1.0rc1.tar.gz | 34.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wazuhtester-0.1.0rc1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.7 kB
Release files / wazuhtester-0.1.0rc1.tar.gz
| Download URL | wazuhtester-0.1.0rc1.tar.gz |
|---|---|
| Size | 34.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e66f0d9e7722c0e6cbcdbf4ca73cefc67e8691b1fb1f099ef78cde9ad8b8acd0
|
|
BLAKE2b-256 checksum How to use checksums |
ad8c1f65461ddd4787abda50f8d2718a2d82601b9fbaf687b9bc24d369081a65
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / wazuhtester-0.1.0rc1-py3-none-any.whl
| Download URL | wazuhtester-0.1.0rc1-py3-none-any.whl |
|---|---|
| Size | 31.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
29ebebb835f1103da7b25611e0fc690e106c8d4db63f5b316d7b913ca27ad67e
|
|
BLAKE2b-256 checksum How to use checksums |
aa733ffeb7f9f07895f8fcfcc47c98af84b5cdfa8a96f71875e5c72b7ba1a433
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|