Skip to content

Logging

E2Engine records operational logs for CLI commands and test execution infrastructure.

Logs are useful when diagnosing execution problems, inspecting runtime behavior, or understanding what happened while an Environment was being prepared and a Test was executed.

Logging works without any explicit configuration.

By default, E2Engine creates two log sinks:

stderr
file

The file sink records debug-level diagnostic information in:

e2engine.log

The log file is appended across CLI invocations.

When no explicit file path is configured, e2engine.log is stored in the E2Engine application data directory.

Typical locations are:

Platform Default log file
macOS ~/Library/Application Support/e2engine/e2engine.log
Linux ~/.local/share/e2engine/e2engine.log
Linux with XDG_DATA_HOME $XDG_DATA_HOME/e2engine/e2engine.log
Windows %APPDATA%\e2engine\e2engine.log

The default SQLite database uses the same application data directory.

For example, on macOS:

~/Library/Application Support/e2engine/
├── config.yml
├── e2engine.sqlite
└── e2engine.log

On Linux, configuration and application data normally use different directories:

~/.config/e2engine/
└── config.yml
~/.local/share/e2engine/
├── e2engine.sqlite
└── e2engine.log

Logs describe operational activity rather than Test results.

For example, a Test execution may produce entries for:

CLI command starts
│
▼
Test execution scheduled
│
▼
Runner starts
│
▼
Environment services mounted
│
▼
Routes registered
│
▼
Environment router mounted
│
▼
HTTP / gRPC requests routed
│
▼
CLI command finishes

A typical command is recorded with its arguments and duration:

debug start executing command command="e2engine run test" args="successful-payment payment-demo"
...
debug end executing command command="e2engine run test" args="successful-payment payment-demo" duration="33.646458ms" err=""

Execution scheduling includes the identifiers needed to correlate related activity:

debug Scheduled test execution component="execution_launcher" execution.id="..." environment.id="..." test.id="..."

Runtime Environment setup is also recorded:

debug Mounted service environment.service.id="fraud" environment.service.kind="http" environment.service.mode="mocked" environment.service.runtime.address="127.0.0.1:58688"

and:

debug Registered route component="environment_http_router" environment.service.id="fraud" environment.service.listen.address="127.0.0.1:8081" environment.service.runtime.address="127.0.0.1:58688"

Requests routed through an Environment can also be observed:

debug Routing environment request environment.service.id="fraud" request.method="POST" request.url.path="/check"

and for gRPC:

debug Routing environment gRPC request environment.service.id="account" grpc.method="/account.v1.AccountService/Debit"

These records provide an operational trace of how E2Engine prepared and exercised the test environment.

Logs and TestExecution results serve different purposes.

TestExecution
│
├── request
├── response
├── expectations
├── observed calls
├── deviations
└── execution error
Log
│
├── CLI activity
├── scheduling
├── runner activity
├── environment lifecycle
├── routing
└── diagnostic context

Use the TestExecution result to determine whether a Test passed, failed, or ended with an execution error.

Use logs when you need additional operational information about how the execution reached that result.

See Inspecting results for TestExecution and TestSuiteExecution result inspection.

Logging is configured under the logger section of config.yml.

For example:

logger:
app_name: e2engine
sinks:
- kind: stderr
format: text
level: 0
- kind: file
format: text
level: -4

A logger can contain multiple sinks, allowing the same log records to be sent to different destinations.

E2Engine supports three sink kinds:

stdout
stderr
file

Send logs to standard error:

logger:
sinks:
- kind: stderr

This is useful for interactive CLI use and environments where standard streams are collected by the surrounding runtime.

Send logs to standard output:

logger:
sinks:
- kind: stdout

Write logs to a file:

logger:
app_name: e2engine
sinks:
- kind: file

When no path is specified, the file sink uses the default application log directory and creates:

e2engine.log

A file sink can use an explicit path:

logger:
sinks:
- kind: file
path: ./logs/e2engine.log

E2Engine creates the parent directory when necessary.

An explicit path allows logs to be placed somewhere other than the default application data directory.

This can be useful in CI/CD pipelines or containerized environments where logs are collected from a specific mounted directory.

Two formats are supported:

text
json

Text is the default:

logger:
sinks:
- kind: stderr
format: text

For machine processing or ingestion into log systems, use JSON:

logger:
sinks:
- kind: stdout
format: json

Different sinks can use different formats.

For example:

logger:
app_name: e2engine
sinks:
- kind: stderr
format: text
- kind: file
format: json

Each sink has its own log level.

For example, the default logger uses a debug-level file sink so that detailed diagnostic information is available in e2engine.log.

A custom sink can specify its level:

logger:
sinks:
- kind: stderr
level: 0

or:

logger:
app_name: e2engine
sinks:
- kind: file
level: -4

This allows interactive output and persistent diagnostic logs to use different levels of detail.

Each sink also supports queue and buffering configuration:

logger:
sinks:
- kind: file
path: ./logs/e2engine.log
queue_size: 1024
buffer_size: 65536
flush_interval: 1s

The defaults are:

Setting Default Description
queue_size 1024 Number of log records that can be queued
buffer_size 65536 Output buffer size
flush_interval 1s Interval between buffer flushes

queue_size and buffer_size must be at least 1.

flush_interval must be greater than zero.

For normal CLI use, these defaults usually do not need to be changed.

A custom configuration retaining the general behavior of the default logger could look like:

logger:
app_name: e2engine
sinks:
- kind: stderr
format: text
level: 0
- kind: file
format: text
level: -4
queue_size: 1024
buffer_size: 65536
flush_interval: 1s

If you do not need to customize logging, omit the logger section entirely and E2Engine will use its default logger configuration.

When a Test does not behave as expected, start with its TestExecution:

Terminal window
e2engine get testexecution <execution-id> -o yaml

For a failed execution, inspect its deviations and observed calls.

For an execution error, inspect the execution error recorded in the summary.

If additional operational context is needed, inspect e2engine.log.

The execution ID can be used to locate related log entries. Execution logs also include Environment and Test identifiers where relevant.

For example:

execution.id="4f5267cb79a65b45b848ef8772a82261d6352594fc93e65d5606ba43de7160cf"

Related entries can then show how the Environment was mounted and which requests passed through its service boundaries.

A useful diagnostic flow is:

TestExecution
│
├── status
├── deviations
├── observed calls
└── error
│
▼
need more context?
│
▼
e2engine.log
│
├── scheduling
├── environment setup
├── routing
└── command errors

This keeps persisted execution results as the primary source for Test behavior while using logs for lower-level operational diagnosis.

See Configuration for the rest of the CLI configuration and Inspecting results for interpreting execution results.