Access Logs

How Cloud-IAM ensures monitoring
To ensure your Keycloak deployment runs properly, Cloud-IAM has implemented:
- Continuous monitoring
- Log collection at different system levels
This setup gives you complete visibility into your deployment's health and activities. All logs are securely stored on Cloud-IAM infrastructure for 30 days.
What do Access Logs contain?
Access Logs are collected from the load balancer in front of your Keycloak deployment. They capture all incoming HTTP requests and include key information such as:
Date
— Timestamp of the requestPublic IP
— IP address of the client making the requestStatus Code
— Response status (e.g.,200
,302
,303
,400
,401
,403
, etc.)Request Method
— HTTP method used (e.g.,GET
,POST
, etc.)
This data helps you understand how users or systems are accessing your Keycloak deployment, and whether any issues occurred during requests.
How to view Access Logs
Follow these easy steps to find your Keycloak Logs:
- Open Cloud-IAM console
- Select the Keycloak deployment you want to audit.
- Click on
Observability
- Then select
Access Logs
You will now see all the access logs related to your deployment.

Access Logs ingestion
API description
The API for fetching the logs needs to be polled. The API will return in the response body, an array of lines composed of a timestamp and its message:
[
"2023-03-07T10:00:05.85104771Z 2023-03-07 10:00:05,850 WARN [org.keycloak.authentication.DefaultAuthenticationFlow] (executor-thread-727) REQUIRED and ALTERNATIVE elements at same level! Those alternative executions will be ignored: [auth-cookie, auth-cookie]\n",
...
]
The response come with HTTP headers that will drive the next polling url and delay.
x-stream-polling-url
: the url to call to fetch the next batch of logs. It will contain an additionalsince
parameter to continue just after the last log line that was returned.x-stream-polling-delay
: the delay in seconds to wait before polling the next batch of logs.x-stream-has-more
: an optional header that indicates that additional log lines are already available and can be fetched without waiting. If set,x-stream-polling-delay
value will be 0.
Delay on logs availability
For various performance reasons, the logs are buffered at several layers. It can be in Keycloak or in the load balancer memory, on disk, on our log ingestion pipeline or in the replication process across our nodes.
For this reason, we usually see a delay of a few minutes between the logs generation and its availability through the Logging API.
Load balancer description
Load balancer cluster logs can be integrated into customer's own logging infrastructure when polling Cloud-IAM REST API /deployments/{deploymentId}/logs
endpoint with the source
field to load-balancer
.
$ curl -H "Authorization: Bearer $TOKEN" 'https://api.cloud-iam.com/deployments/00000000-0000-0000-0000-000000000000/logs?source=load-balancer&since=2023-02-26T23:17:06Z' | jq .
[
"2023-03-07T10:00:05.85104771Z 1.2.3.4 - - [07/Mar/2023:10:00:05 +0000] \"GET / HTTP/1.0\" 403 0.000 548 \"Mozilla/5.0 (Linux; Android 9; Nokia 7.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Mobile Safari/537.36\" \"-\" \"-\" \"-\" \"-\" \"h:-\"",
...
]
Fetch with filebeat for Elasticsearch
Filebeat is a lightweight shipper for forwarding and centralizing log data maintained by the Elasticsearch community. It can be used in combination of Logstash to collect / transform / parse and inject logs in your log infrastructure.
Here is a snippet of a filebeat input configuration to fetch the logs from the Cloud-IAM API. You will need to adjust the output section accordingly to your log infrastructure settings.
Make sure to replace the values for {service-account}
, {service-account-password}
and {deployment-id}
. Adjust the source parameter line 8.
filebeat.inputs:
- type: cel
enabled: true
auth.oauth2.client.id: {service-account}
auth.oauth2.client.secret: {service-account-password}
auth.oauth2.token_url: https://iam.cloud-iam.com/auth/realms/cloud-iam/protocol/openid-connect/token
interval: 60s
resource.url: https://api.cloud-iam.com/deployments/{deployment-id}/logs?source=keycloak
program: |
get(state.url)
.as(request,
{
"events": request.Body.decode_json().map(e,
{
"@timestamp": string(e).split_n(" ", 2)[0],
"message": string(e).split_n(" ", 2)[1]
}),
"want_more": request.Header.exists(e, e == 'X-Stream-Has-More'),
"url": request.Header['X-Stream-Polling-Url'][0]
}
)
output.file:
enabled: false
path: "/tmp/"
filename: cloud-iam-keycloak.log
permissions: 0640
codec.format:
string: '%{[message]}'
output.elasticsearch:
enabled: false
hosts: ["http://localhost:9200"]
api_key: "xxxxxxx:yyyyyyy"
index: "cloud-iam-keycloak-%{+yyyy.MM.dd}"
For testing purpose, you can use this configuration file in a docker container:
$ docker run --rm -it -v $PWD/filebeat.yml:/usr/share/filebeat/filebeat.yml \
-v $PWD/output:/tmp \
docker.elastic.co/beats/filebeat:8.17.4