Cloudscale Logo

News

Back
2025
December
11
2025

Project Audit Logs Available via API

At cloudscale, all changes to your cloud resources are recorded in a log. This means that you can also check retrospectively when exactly, for example, a server was scaled or who the best person in your team is to ask for further details. These audit logs are now also available via API, which allows you to archive them in a location of your choice or include them in monitoring.

One log – numerous advantages

Have you ever wondered which member of your team set up that server called "test"? Or when you last had to perform a hard reboot of a certain system? You will find the answer in the audit log. Any changes to your cloud resources, irrespective of whether they were carried out in the cloud control panel or via API, are neatly listed and traceable.

If you would like not only to look at these logs in the control panel, but also, for example, to save them on your own log server or search them using a specific tool, you can now retrieve the audit log via our API, too. In the process, you have the option of setting a start and/or end time in order to narrow down extensive logs to the relevant period. In addition, a special poll_more URL enables you to access periodically and precisely any logs that have been added since the last retrieval. This also makes it possible for you to evaluate the logs in a monitoring system and, for example, to nominate somebody automatically to perform an additional manual review of certain operations.

Further details

In addition to the exact time stamp for every change, you will find action and message fields in the audit log that you retrieve via API. The action field lists what type of change it is (e.g. "server_volume_attach"), while the message field describes the whole process, i.e. also indicates which volume was attached to which server. You will also see who initiated the change (usually the e-mail address of an account in the control panel or the API token used) and from which IP address. As always, you will find all the details in our API documentation.

Not every change carried out via the control panel or API will take the same amount of time and actions can run in parallel. As soon as the action has been successfully completed, the log entry is prepared, which determines the time stamp of the log. Shortly afterwards (in a matter of milliseconds), the result of the action and the log entry can be seen. In this short period of time, it is possible for log entries to "overtake" each other, i.e. a log with an earlier time stamp only becomes visible later. When accessing subsequent pages and when "polling", the cursor ensures that you do not miss a log entry. Michi has provided a comprehensive insight into this mechanism in our engineering blog.

Preprepared sample code: start right away

In order to enable you to start quickly, we have prepared a ready-to-use, annotated Python script for you. This will allow you to try retrieving the audit log via API and to become familiar with the approach used. Even if you use different tools and languages, this will provide you with a good overview and a basis for your own implementations.

First of all prepare a Python virtual environment with the required dependency:

mkdir project-log-api-client
cd project-log-api-client/
python3 -m venv venv
source venv/bin/activate
pip install aiohttp

Then create the actual api-log-client.py script with the following content:

import asyncio
import json
from collections.abc import AsyncIterator
from datetime import UTC
from datetime import datetime
from datetime import timedelta
from typing import Any
from urllib.parse import quote

from aiohttp import ClientSession

API_TOKEN = "INSERT_PROJECT_API_TOKEN"
POLL_INTERVAL_SECONDS = 120


async def stream_logs(session: ClientSession, start: datetime) -> AsyncIterator[Any]:
    poll_url = f"https://api.cloudscale.ch/v1/project-logs?start={quote(start.isoformat())}"

    # The outer loop fetches all logs available at the time,
    # then waits for a defined interval.
    while True:
        current_page = poll_url

        # The inner loop fetches individual pages of available logs
        # until the `next` field in the response is `null`.
        while current_page is not None:
            async with session.get(current_page) as response:
                if not response.ok:
                    # The API did not return with status code 200.
                    raise Exception(f"Error {response.status} from API: {await response.text()}")

                obj = await response.json()

            # Return all fetched logs to the caller.
            for log in obj["results"]:
                yield log

            current_page = obj["next"]
            poll_url = obj["poll_more"]

        # Wait for a defined interval before polling for new logs.
        await asyncio.sleep(POLL_INTERVAL_SECONDS)


async def main() -> None:
    # Header to authenticate the API access.
    headers = {"Authorization": f"Bearer {API_TOKEN}"}

    # Retrieve logs from the past hour before streaming new logs.
    start = datetime.now(UTC).astimezone() - timedelta(hours=1)

    print(f"Streaming logs, starting from {start:%F %H:%M:%S}. Use ctrl-C to stop.")

    async with ClientSession(headers=headers) as session:
        # Iterate over logs returned by the API and print them to the console.
        async for log in stream_logs(session, start):
            print(json.dumps(log, indent=4))


if __name__ == "__main__":
    asyncio.run(main())

Now start the script. It will provide you with the audit log of the past 60 minutes on the command line and will then periodically add any new log entries that have been created in the interim.

$ python3 api-log-client.py 
Streaming logs, starting from 2025-12-11 12:21:48. Use ctrl-C to stop.
{
    "ip_address": "172.30.244.1",
    "action": "server_create",
    "message": "Server 'hello' has been created",
    "timestamp": "2025-12-11T12:23:17.460366Z",
    "actor": {
        "user": {
            "email": "johanna@example.com"
        }
    }
}
[...]

With the audit logs of your projects at cloudscale you know at all times who did what when, which means that you can quickly establish the correct links or approach the right person for further inquiries. You can now also use these logs via API for maximum flexibility when archiving and evaluating.

Reliably committed,
Your cloudscale team

Back to overview