Logging
Your APD project holds the logging configuration of both the tests and ADS. The ADS configuration is the same one that your ADS uses in production: APD adds it to the deployment that you build the container image from. This page describes where logging is configured, how to change the level, and how to use the logs to debug.
:::tip Debugging ALFA policies To find out why a policy returns an unexpected decision, use the visual trace instead of the logs. It shows the path the policy engine took through the policies, rules, and conditions to reach the decision. See Visual tracing. :::
Where logging is configured
The tests and ADS run in different processes, and you configure their logging in different files:
| Process | Configuration |
|---|---|
Tests on the embedded policy engine (./gradlew test) | src/test/resources/logback-test.xml |
ADS: started locally with runAds, or in production from the image built from stageDeployment | deployment.yaml and src/extra/logback-custom.xml |
ADS logging
ADS logs with Logback, through Spring Boot. Two files in your project configure it, and runAds and stageDeployment copy both to ADS, so a local ADS logs the same way as ADS in production:
-
deployment.yaml: theloggingsection sets the log levels and points to the Logback configuration file:deployment.yamllogging:level:root: ${ADS_LOGGER_ROOT_LEVEL:INFO}com.axiomatics.audit: ${ADS_LOGGER_AUDIT_LEVEL:INFO}config: logback-custom.xml -
src/extra/logback-custom.xml: the appenders, which decide where the log goes and in which format, see Log format below.
All files in src/extra/, such as startService.sh and keystores, are copied next to ADS. See Project structure.
Log format
By default, ADS writes each log entry as one line of JSON to the console (standard output). A container platform collects the console output, and log tools such as Elasticsearch, Splunk, or Datadog can search the JSON fields without parsing text. logback-custom.xml builds the JSON with the Logstash Logback encoder, from these fields:
| Field | Content |
|---|---|
timestamp | The time of the log entry. |
level | The log level, such as INFO or ERROR. |
logger | The name of the logger, usually the Java class that wrote the entry. |
message | The log message. |
exception | The stack trace, when the entry is about an error. |
| MDC fields | Mapped Diagnostic Context (MDC) values that apply to an entire request rather than a single log entry (such as trace and span IDs in a distributed trace). To capture them, instrument ADS with your OpenTelemetry Java agent. ADS will then attach these fields to every log entry generated during request processing, allowing you to trace requests across your services. |
The audit log, with one entry for each evaluated access request, has its own appender. It writes the evaluation event as a JSON object in message, instead of as text, and adds the static field "audit": {"objecttype": "abac-audit"}, so you can filter the audit entries from the rest of the log. Each audit entry has the identity of the domain that made the decision in DomainId, see Traceability. This only works with a JSON audit.mode in deployment.yaml: concise_json (the default of ADS) or verbose_json (set in the deployment.yaml of APD). For concise or verbose (XML), follow the comment in the file to log the message as text.
You can change logback-custom.xml, for example to add static fields such as the name of your environment, to write to a file, or to use another format. See the Logback documentationOpens in a new tab and the Logstash Logback encoderOpens in a new tab.
Log levels
Set the log levels of ADS with these environment variables, in the environment where ADS runs:
| Environment variable | Default | Controls |
|---|---|---|
ADS_LOGGER_ROOT_LEVEL | INFO | The log level of ADS. |
ADS_LOGGER_AUDIT_LEVEL | INFO | The audit log: one entry for each access request that ADS evaluates, in the format set by audit.mode in deployment.yaml. Logged when the level is INFO or lower. |
For example, to run a local ADS with debug logs, add to build.gradle:
runAds {
environment "ADS_LOGGER_ROOT_LEVEL", "DEBUG"
}
Or set the variable in the shell before you run ./gradlew runAds. In production, set it in the environment of the container, for example in the env file or Kubernetes ConfigMap. See Environment variables.
Test logging
The tests log with Logback, configured in src/test/resources/logback-test.xml. ADS does not read this file. To see more details, change the level of the Axiomatics loggers from INFO to DEBUG:
<logger name="com.axiomatics" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="io.axiomatics" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
</logger>
The log is in the output of ./gradlew test, and in the standard output of the test report in build/reports/tests/.
Debug with the logs
Use the logs to debug:
- The tests themselves, for example when a test fails with an error instead of a wrong decision, or an attribute connector cannot connect to its source.
- A local ADS started with
runAds, for example when it does not start, or does not load the authorization domain. - The Java code of a custom attribute connector, see Custom attribute connectors. You can also run its tests in debug mode from your IDE.
Requests and responses
For each test on the embedded policy engine, APD writes the JSON request sent to the policy engine and the JSON response it returned to build/alfa/tests/trace/:
<test method>_request.json<test method>_response.json
Use them to check the attribute values a test sends, or to send the same request to an ADS, see PEPs and requests.
Visual trace
In the same directory, APD writes a visual trace of each evaluation, <test method>_visualize.html. The test output prints its location as Visualization report at file:///….
APD writes the requests, responses, and visual traces only when visual tracing is turned on (the default), and not for tests against a running ADS. See Visual tracing.