API

After you’ve installed Apex Logs to your Google Cloud account you will receive a unique URL for your installation, similar to https://logs-a7iho5vpb2-ew.a.run.app/. This URL hosts the user interface and the API for your logs, and can be shared with your teammates.

Access to the user interface and API are restricted to members of your Apex Software team, and API tokens you have created.

Authentication

To authenticate your requests you’ll need to create an API token for accessing the API programmatically. To create one click the “API tokens” menu item, then “Add token”.

Give your token a description to help your team understand where or how it is being used, and select the appropriate permissions. Keep in mind that API tokens are not scoped to a project, so you may want to be more descriptive if you have many products.

It’s a good practice to give each logging source its own API token, for example creating separate write tokens for the browser web application and backend servers, or read tokens if you’re writing a dasboard. Clicking a token will provide more information such as the scopes granted.

You may want to quickly test the API token by sending an event on the command-line with curl, substituting <TOKEN>, <PROJECT_ID>, and <ENDPOINT> with your own values.

curl \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "project_id": "<PROJECT_ID>", "events": [{ "level": "info", "message": "Sign in", "fields": { "email": "tobi@example.com" } }] }' \
  https://<ENDPOINT>/add_events

Tokens cannot be edited, only removed.

Language clients

The following API clients are currently supported:

Visit github.com/apex/rpc if you would like to contribute a language client.

Integrations

Higher level language and framework integrations provide additional features on top of the low-level API clients, such as providing a nicer logging interface, batching of events to improve efficiency and more. The following integrations are currently available:

Golang:

  • apex/log — Structured logging for Go

Node.js:

Platforms:

If your company requires an integration feel free to contact us and we’ll prioritize it.

Making requests

Apex Logs uses an RPC style API, which mimics how you would call regular functions locally in a program. All requests are made using a POST request with a JSON body, and the function name is placed in the URL’s path.

Here’s an example HTTP/1.1 request made to get_projects to list existing projects. Note that the get_projects RPC method does not take any input parameters, so an empty object is provided.

POST /get_projects HTTP/1.1
Content-Type: application/json
Content-Length: 2
Authorization: Bearer <token>

{}

HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
Date: Mon, 25 May 2020 12:21:48 GMT
Content-Length: 867

{
  "projects": [
    {
      "id": "apex_production",
      "name": "Apex Production",
      "retention": 365,
      "location": "europe-west2",
      "description": "Apex production logs",
      "updated_at": "2019-10-30T11:44:26.005127Z",
      "created_at": "0001-01-01T00:00:00Z"
    },
    {
      "id": "binaries_production",
      "name": "Binaries Production",
      "retention": 365,
      "location": "europe-west2",
      "description": "Go binaries",
      "updated_at": "2020-01-29T15:46:05.337092Z",
      "created_at": "2020-01-29T15:46:05.337092Z"
    },
    {
      "id": "ping_production",
      "name": "Ping Production",
      "retention": 365,
      "location": "europe-west2",
      "description": "Ping production logs.",
      "updated_at": "2020-05-20T12:41:46.29772+01:00",
      "created_at": "2020-05-20T12:41:46.29772+01:00"
    }
  ]
}

Here’s an example using curl to list all of the alerts defined for a project. The get_alerts RPC method expects a project_id, which is defined in the POST body with -d.

$ curl \
  -d '{ "project_id": "ping_production" }' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  https://<endpoint>/get_alerts

{
  "alerts": [
    {
      "id": "1RHyOWJ8cIlvDb1bcKZHdiISnX6",
      "project_id": "ping_production",
      "name": "Errors",
      "description": "All production errors via Email",
      "severity": "error",
      "query": "level > warning or message contains \"panic\"",
      "operator": ">=",
      "threshold": 1,
      "limit": 100,
      "interval": 5,
      "notification_id": "1Q3bUUxSUZVlreTTwVzdK5z37iX",
      "triggered": false,
      "muted": false,
      "updated_at": "2020-05-21T11:04:07.340935+01:00",
      "created_at": "0001-01-01T00:00:00Z"
    }
  ]
}

All response bodies from the API itself are JSON, however, you should check for a Content-Type of “application/json”, as the load balancer can potentially fail with non-JSON errors.

Project ids are available on the project’s edit page, see Editing projects for more information.

Handling errors

Error responses set an appropriate HTTP status code, such as 400 “Bad Request”, and details are provided in the response body as JSON with type and message properties. Here’s an example request which omits the required project_id property for listing alerts.

POST /get_alerts HTTP/1.1
Content-Type: application/json
Content-Length: 2
Authorization: Bearer <token>

{}

HTTP/1.1 400 Bad Request
Content-Type: application/json
Vary: Origin
Date: Mon, 25 May 2020 12:43:56 GMT
Content-Length: 64

{
  "type": "invalid",
  "message": "project_id: is required"
}

Client requirements

The following should be considered when sending API requests or creating a language client:

  • All requests MUST be a POST request
  • All requests MUST have the Content-Type set to “application/json”
  • All responses set an appropriate HTTP status code, which can be used to detect errors
  • Requests use the Authorization header field with a “Bearer” token for authentication
  • Most requests respond with JSON, or a 204 “No Content” when there’s no result
  • Clients should check the response Content-Type before parsing JSON
  • Client integrations should batch events for calls to add_events