` placeholder with the extra for your framework. The options are:
* `blacksheep`
* `django_ninja`
* `django_rest_framework`
* `fastapi`
* `flask`
* `litestar`
* `starlette`
## Supported frameworks
The Python SDK currently supports the web frameworks listed below. If your framework is not listed, please [let us know](/support) and we'll consider adding support for it.
Click on a framework for a detailed setup guide.
}
href="/setup-guides/blacksheep"
/>
}
href="/setup-guides/django-ninja"
/>
}
href="/setup-guides/django-rest-framework"
/>
}
href="/setup-guides/fastapi"
/>
}
href="/setup-guides/flask"
/>
}
href="/setup-guides/litestar"
/>
}
href="/setup-guides/starlette"
/>
# Tracing instrumentation
Source: https://docs.apitally.io/sdk-reference/python/tracing
Instrument your Python application with OpenTelemetry for tracing in Apitally.
When tracing is enabled, the Apitally SDK captures [OpenTelemetry](https://opentelemetry.io/docs/languages/python/) spans during request handling and attaches them to request logs. This allows you to see exactly what happened during each request, including database queries, HTTP calls to external services, and custom operations.
If you have an existing OpenTelemetry setup, the SDK automatically registers itself as a span processor with the global `TracerProvider`. Otherwise, it creates its own. Any spans created using the standard OpenTelemetry API or by instrumentation libraries will be captured.
## Enable tracing
To enable tracing, set `capture_traces` to `True` in your middleware configuration:
```python FastAPI {9-10} theme={null}
from fastapi import FastAPI
from apitally.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev",
enable_request_logging=True,
capture_traces=True,
)
```
```python Django {4-5} theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev",
"enable_request_logging": True,
"capture_traces": True,
}
```
```python Flask {9-10} theme={null}
from flask import Flask
from apitally.flask import ApitallyMiddleware
app = Flask(__name__)
app.wsgi_app = ApitallyMiddleware(
app,
client_id="your-client-id",
env="dev",
enable_request_logging=True,
capture_traces=True,
)
```
## Instrument libraries
The SDK provides helper functions in `apitally.otel` to instrument popular libraries. These are thin wrappers around the official OpenTelemetry instrumentation packages, which need to be installed separately.
| Library | Function | Required package |
| :--------------------- | :------------------------ | :----------------------------------------- |
| httpx | `instrument_httpx()` | `opentelemetry-instrumentation-httpx` |
| requests | `instrument_requests()` | `opentelemetry-instrumentation-requests` |
| SQLAlchemy | `instrument_sqlalchemy()` | `opentelemetry-instrumentation-sqlalchemy` |
| psycopg 3 | `instrument_psycopg()` | `opentelemetry-instrumentation-psycopg` |
| psycopg2 | `instrument_psycopg2()` | `opentelemetry-instrumentation-psycopg2` |
| asyncpg | `instrument_asyncpg()` | `opentelemetry-instrumentation-asyncpg` |
| mysql-connector-python | `instrument_mysql()` | `opentelemetry-instrumentation-mysql` |
| redis-py | `instrument_redis()` | `opentelemetry-instrumentation-redis` |
| PyMongo | `instrument_pymongo()` | `opentelemetry-instrumentation-pymongo` |
| botocore (AWS SDK) | `instrument_botocore()` | `opentelemetry-instrumentation-botocore` |
To get started, first install the required packages for the libraries you want to instrument. For example, to instrument `httpx` and `sqlalchemy`:
```shell pip theme={null}
pip install opentelemetry-instrumentation-httpx opentelemetry-instrumentation-sqlalchemy
```
```shell uv theme={null}
uv add opentelemetry-instrumentation-httpx opentelemetry-instrumentation-sqlalchemy
```
```shell poetry theme={null}
poetry add opentelemetry-instrumentation-httpx opentelemetry-instrumentation-sqlalchemy
```
Then call the instrumentation functions at application startup. Some functions accept an optional client, connection or engine argument to instrument a specific instance instead of all instances globally.
```python theme={null}
from apitally.otel import instrument_httpx, instrument_sqlalchemy
instrument_httpx()
instrument_sqlalchemy(engine)
```
## Create custom spans
For custom operations that aren't covered by library instrumentation, you can create spans manually using the helpers provided by the SDK. These are thin wrappers around the standard OpenTelemetry API, which you can also use directly.
### `@instrument` decorator
Use the `@instrument` decorator to automatically create a span for a function. It works with both sync and async functions:
```python theme={null}
from apitally.otel import instrument
@instrument
def process_order(order_id: int) -> None:
...
```
### `span()` context manager
Use the `span()` context manager to trace code blocks within a function:
```python theme={null}
from apitally.otel import span
def checkout(cart_id: int) -> None:
with span("validate_cart") as s:
s.set_attribute("cart_id", cart_id)
# Validation logic here
...
with span("process_payment"):
# Payment logic here
...
```
# Overview
Source: https://docs.apitally.io/setup-guides
Get started with Apitally in less than 5 minutes.
Choose your framework from the options below for a detailed setup guide.
}
href="/setup-guides/blacksheep"
/>
}
href="/setup-guides/django-ninja"
/>
}
href="/setup-guides/django-rest-framework"
/>
}
href="/setup-guides/fastapi"
/>
}
href="/setup-guides/flask"
/>
}
href="/setup-guides/litestar"
/>
}
href="/setup-guides/starlette"
/>
}
href="/setup-guides/adonisjs"
/>
}
href="/setup-guides/elysia"
/>
}
href="/setup-guides/express"
/>
}
href="/setup-guides/fastify"
/>
}
href="/setup-guides/h3"
/>
}
href="/setup-guides/hapi"
/>
}
href="/setup-guides/hono"
/>
}
href="/setup-guides/koa"
/>
}
href="/setup-guides/nestjs"
/>
}
href="/setup-guides/chi"
/>
}
href="/setup-guides/echo"
/>
}
href="/setup-guides/fiber"
/>
}
href="/setup-guides/gin"
/>
}
href="/setup-guides/spring-boot"
/>
}
href="/setup-guides/aspnet-core"
/>
}
href="/setup-guides/fastapi-cloudflare-workers"
>
Cloudflare Workers
}
href="/setup-guides/hono-cloudflare-workers"
>
Cloudflare Workers
If your framework is not listed here, please [let us know](/support) and we'll consider adding support for it.
# Setup guide for AdonisJS
Source: https://docs.apitally.io/setup-guides/adonisjs
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [AdonisJS](https://adonisjs.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Install the [Apitally SDK](/sdk-reference/javascript/overview) in your AdonisJS project.
```shell theme={null}
npm install apitally
```
Then configure Apitally by running the below Ace command. You'll be prompted to enter the client ID for your app.
You'll find it on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```shell theme={null}
node ace configure apitally/adonisjs
```
This command will automatically:
* Create a config file at `config/apitally.ts`
* Register the Apitally provider in `adonisrc.ts`
* Add the Apitally middleware to `start/kernel.ts`
* Add environment variables to `.env` and `start/env.ts`
Finally, to capture validation and server errors, modify your exception handler in `app/exceptions/handler.ts`:
```javascript {2,6} theme={null}
import { ExceptionHandler, HttpContext } from '@adonisjs/core/http'
import { captureError } from 'apitally/adonisjs'
export default class HttpExceptionHandler extends ExceptionHandler {
async report(error: unknown, ctx: HttpContext) {
captureError(error, ctx)
return super.report(error, ctx)
}
}
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in a [custom middleware](https://docs.adonisjs.com/guides/basics/middleware#creating-middleware).
```javascript Identifier only theme={null}
import { HttpContext } from '@adonisjs/core/http'
import { NextFn } from '@adonisjs/core/types/http'
import { setConsumer } from 'apitally/adonisjs'
export default class ApitallyConsumerMiddleware {
async handle(ctx: HttpContext, next: NextFn) {
if (ctx.auth.isAuthenticated) {
setConsumer(ctx, ctx.auth.user!.email)
}
await next()
}
}
```
```javascript With name and group theme={null}
import { HttpContext } from '@adonisjs/core/http'
import { NextFn } from '@adonisjs/core/types/http'
import { setConsumer } from 'apitally/adonisjs'
export default class ApitallyConsumerMiddleware {
async handle(ctx: HttpContext, next: NextFn) {
if (ctx.auth.isAuthenticated) {
setConsumer(ctx, {
identifier: String(ctx.auth.user!.id),
name: ctx.auth.user!.fullName, // optional
group: ctx.auth.user!.organization, // optional
})
}
await next()
}
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import { defineConfig } from 'apitally/adonisjs'
const apitallyConfig = defineConfig({
clientId: 'your-client-id',
env: 'dev', // or 'prod' etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
})
export default apitallyConfig;
```
```javascript Advanced example theme={null}
import { defineConfig } from 'apitally/adonisjs'
const apitallyConfig = defineConfig({
clientId: 'your-client-id',
env: 'dev', // or 'prod' etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.url?.startsWith('/admin/') ? null : request.body,
maskResponseBodyCallback: (request, response) => request.url?.startsWith('/admin/') ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === 'some-consumer',
},
})
export default apitallyConfig;
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for ASP.NET Core
Source: https://docs.apitally.io/setup-guides/aspnet-core
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [ASP.NET Core](https://dotnet.microsoft.com/en-us/apps/aspnet) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/dotnet/overview) in your project:
```shell theme={null}
dotnet add package Apitally
```
Register the required services and middleware for Apitally in your `Program.cs` file and provide the `ClientId` for your app.
You'll find the `ClientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
You can also configure Apitally in your `appsettings.json` file, if you prefer.
```csharp Program.cs theme={null}
using Apitally;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApitally(options =>
{
options.ClientId = "your-client-id";
options.Env = "dev"; // or "prod" etc.
});
var app = builder.Build();
app.UseApitally();
// ... rest of your middleware configuration
```
```json appsettings.json theme={null}
{
"Apitally": {
"ClientId": "your-client-id",
"Env": "dev"
}
}
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, set the `ApitallyConsumer` item in the request context. You can do this in middleware, for example:
```csharp Identifier only theme={null}
app.Use(async (context, next) =>
{
if (context.User.Identity.IsAuthenticated)
{
context.Items["ApitallyConsumer"] = context.User.Identity.Name;
}
await next();
});
```
```csharp With name and group theme={null}
using Apitally;
using System.Security.Claims;
app.Use(async (context, next) =>
{
if (context.User.Identity.IsAuthenticated)
{
context.Items["ApitallyConsumer"] = new ApitallyConsumer
{
Identifier = context.User.Identity.Name,
Name = context.User.FindFirst(ClaimTypes.Name)?.Value,
Group = context.User.FindFirst(ClaimTypes.Role)?.Value,
};
}
await next();
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
Check out the SDK reference to learn more about the request logging configuration options.
```json Basic example theme={null}
{
"Apitally": {
"ClientId": "your-client-id",
"Env": "dev",
"RequestLogging": {
"Enabled": true,
"IncludeRequestHeaders": true,
"IncludeRequestBody": true,
"IncludeResponseBody": true,
"CaptureLogs": true,
"CaptureTraces": false // requires instrumentation
}
}
}
```
```json Advanced example theme={null}
{
"Apitally": {
"ClientId": "your-client-id",
"Env": "dev",
"RequestLogging": {
"Enabled": true,
"IncludeQueryParams": true,
"IncludeRequestHeaders": true,
"IncludeRequestBody": true,
"IncludeResponseHeaders": true,
"IncludeResponseBody": true,
"IncludeException": true,
"CaptureLogs": true,
"CaptureTraces": false // requires instrumentation,
// Mask query parameters using regex
"QueryParamMaskPatterns": [
"^card_number$"
],
// Mask headers using regex
"HeaderMaskPatterns": [
"^X-Sensitive-Header$"
],
// Mask request/response body fields using regex
"BodyFieldMaskPatterns": [
"^sensitive_field$"
],
// Exclude paths from request logging using regex (common health check paths are excluded by default)
"PathExcludePatterns": [
"/metrics$"
]
}
}
}
```
```csharp Callbacks example theme={null}
builder.Services.PostConfigure(options =>
{
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
options.RequestLogging.MaskRequestBody = request =>
request.Path.StartsWith("/admin/") ? null : request.Body;
options.RequestLogging.MaskResponseBody = (request, response) =>
request.Path.StartsWith("/admin/") ? null : response.Body;
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
options.RequestLogging.ShouldExclude = (request, response) =>
request.Consumer == "some-consumer";
});
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `CaptureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/dotnet/tracing) for further instructions.
# Setup guide for BlackSheep
Source: https://docs.apitally.io/setup-guides/blacksheep
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [BlackSheep](https://www.neoteroi.dev/blacksheep/) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[blacksheep]"
```
```shell poetry theme={null}
poetry add "apitally[blacksheep]"
```
```shell uv theme={null}
uv add "apitally[blacksheep]"
```
Add the Apitally middleware to your BlackSheep application and provide the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
from blacksheep import Application
from apitally.blacksheep import use_apitally
app = Application()
use_apitally(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
)
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, provide a callback function that takes a [`Request`](https://www.neoteroi.dev/blacksheep/requests/#the-request-class) object as an argument and returns a consumer identifier, an `ApitallyConsumer` object or `None`.
Alternatively, you can set the `apitally_consumer` claim on the `request.identity` object, for example in your authentication handler.
```python Callback theme={null}
from blacksheep import Application, Request
from apitally.blacksheep import use_apitally
def get_consumer(request: Request) -> str | None:
if request.identity.is_authenticated:
return request.identity.sub
return None
app = Application()
use_apitally(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
consumer_callback=get_consumer,
)
```
```python Callback (with name and group) theme={null}
from blacksheep import Application, Request
from apitally.blacksheep import use_apitally, ApitallyConsumer
def get_consumer(request: Request) -> ApitallyConsumer | None:
if request.identity.is_authenticated:
return ApitallyConsumer(
identifier=request.identity.sub,
name=request.identity.get("name"), # optional
group=request.identity.get("role"), # optional
)
return None
app = Application()
use_apitally(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
consumer_callback=get_consumer,
)
```
```python Claim on identity theme={null}
from blacksheep import Request
from guardpost import AuthenticationHandler, Identity
class ExampleAuthHandler(AuthenticationHandler):
async def authenticate(self, context: Request) -> Identity | None:
header_value = context.get_first_header(b"Authorization")
if header_value:
claims = {
"name": "John Doe",
"email": "john.doe@example.com",
"apitally_consumer": "john.doe@example.com",
}
context.identity = Identity(claims, "MOCK")
return context.identity
else:
context.identity = None
return context.identity
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
from blacksheep import Application
from apitally.blacksheep import use_apitally
app = Application()
use_apitally(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_request_headers=True,
log_request_body=True,
log_response_body=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
)
```
```python Advanced example theme={null}
from blacksheep import Application
from apitally.blacksheep import use_apitally
app = Application()
use_apitally(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_query_params=True,
log_request_headers=True,
log_request_body=True,
log_response_headers=True,
log_response_body=True,
log_exception=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
# Mask query parameters using regex
mask_query_params=[r"^card_number$"],
# Mask headers using regex
mask_headers=[r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
mask_body_fields=[r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
mask_request_body_callback=lambda request: None if request["path"].startswith("/admin/") else request["body"],
mask_response_body_callback=lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
exclude_paths=[r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
exclude_callback=lambda request, response: request["consumer"] == "some-consumer",
)
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
# Setup guide for Chi
Source: https://docs.apitally.io/setup-guides/chi
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Chi](https://go-chi.io) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Add the [Apitally SDK](/sdk-reference/go/overview) to the dependencies in your Chi project.
```shell theme={null}
go get github.com/apitally/apitally-go/chi-v5
```
Add the Apitally middleware to your Chi application and provide the `ClientId` for your app.
You'll find the `ClientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```go theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/chi-v5"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
r.Use(apitally.Middleware(r, config))
// ... rest of your code ...
}
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, use the `SetConsumerIdentifier` or `SetConsumer` function, for example in a middleware.
```go {8} Identifier only theme={null}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
// Use the authenticated identity as consumer identifier
apitally.SetConsumerIdentifier(r, user.Identifier)
}
next.ServeHTTP(w, r)
})
}
```
```go {7-11} With name and group theme={null}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
apitally.SetConsumer(r, apitally.Consumer{
Identifier: user.Email,
Name: user.Name, // optional
Group: user.Group, // optional
})
}
next.ServeHTTP(w, r)
})
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Capture validation errors
If you're using the `go-playground/validator/v10` package to validate incoming data, you can use the `CaptureValidationError` function to record validation errors.
This gives you visibility into the validation errors returned by your API endpoints.
```go {29} theme={null}
package main
import (
"encoding/json"
"net/http"
apitally "github.com/apitally/apitally-go/chi-v5"
"github.com/go-chi/chi/v5"
"github.com/go-playground/validator/v10"
)
type HelloRequest struct {
Name string `json:"name" validate:"required"`
}
func main() {
r := chi.NewRouter()
validate := validator.New()
// ...
r.Post("/hello", func(w http.ResponseWriter, r *http.Request) {
var req HelloRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := validate.Struct(req); err != nil {
apitally.CaptureValidationError(r, err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
json.NewEncoder(w).Encode(map[string]string{"message": "Hello, " + req.Name + "!"})
})
// ...
}
```
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```go Basic example theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/chi-v5"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
r.Use(apitally.Middleware(r, config))
// ... rest of your code ...
}
```
```go Advanced example theme={null}
package main
import (
"regexp"
"strings"
apitally "github.com/apitally/apitally-go/chi-v5"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogQueryParams = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseHeaders = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.LogPanic = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
// Mask query parameters using regex
config.RequestLogging.MaskQueryParams = []*regexp.Regexp{regexp.MustCompile(`^card_number$`)}
// Mask headers using regex
config.RequestLogging.MaskHeaders = []*regexp.Regexp{regexp.MustCompile(`^X-Sensitive-Header$`)}
// Mask request/response body fields using regex
config.RequestLogging.MaskBodyFields = []*regexp.Regexp{regexp.MustCompile(`^sensitive_field$`)}
// Exclude paths from request logging using regex (common health check paths are excluded by default)
config.RequestLogging.ExcludePaths = []*regexp.Regexp{regexp.MustCompile(`/metrics$`)}
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return nil to mask the whole body, or return the (modified) raw body
config.RequestLogging.MaskRequestBodyCallback = func(request *apitally.Request) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return request.Body
}
config.RequestLogging.MaskResponseBodyCallback = func(request *apitally.Request, response *apitally.Response) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return response.Body
}
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
config.RequestLogging.ExcludeCallback = func(request *apitally.Request, response *apitally.Response) bool {
return request.Consumer == "some-consumer"
}
r.Use(apitally.Middleware(r, config))
// ... rest of your code ...
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `CaptureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/go/tracing) for further instructions.
# Setup guide for Django Ninja
Source: https://docs.apitally.io/setup-guides/django-ninja
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Django Ninja](https://django-ninja.dev) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[django_ninja]"
```
```shell poetry theme={null}
poetry add "apitally[django_ninja]"
```
```shell uv theme={null}
uv add "apitally[django_ninja]"
```
Activate the Apitally middleware in your Django application by appending it to the end of the [`MIDDLEWARE`](https://docs.djangoproject.com/en/4.2/topics/http/middleware/#activating-middleware) list in your Django settings.
Then configure the Apitally middleware by adding `APITALLY_MIDDLEWARE` to your settings file and including the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
MIDDLEWARE = [
"apitally.django.ApitallyMiddleware",
# Other middleware ...
]
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"include_django_views": False, # Set to True to include regular Django views
}
```
If you're using Gunicorn or uWSGI to serve your app in production, please review the [known issues](#known-issues) section below.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, provide a callback function in the middleware settings that takes a [`HttpRequest`](https://docs.djangoproject.com/en/4.2/ref/request-response/#httprequest-objects) object as an argument and returns a consumer identifier, an `ApitallyConsumer` object or `None`.
```python Callback theme={null}
from django.http import HttpRequest
def identify_consumer(request: HttpRequest) -> str | None:
if request.user.is_authenticated:
return request.user.username
return None
```
```python Callback (with name and group) theme={null}
from django.http import HttpRequest
from apitally.django import ApitallyConsumer
def identify_consumer(request: HttpRequest) -> ApitallyConsumer | None:
if request.user.is_authenticated:
return ApitallyConsumer(
identifier=request.user.username,
name=f"{request.user.first_name} {request.user.last_name}",
group=request.user.groups.first().name,
)
return None
```
```python Middleware settings theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"consumer_callback": "your_project.api.utils.identify_consumer",
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"enable_request_logging": True,
"log_request_headers": True,
"log_request_body": True,
"log_response_body": True,
"capture_logs": True,
"capture_traces": False, # requires instrumentation
}
```
```python Advanced example theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"enable_request_logging": True,
"log_query_params": True,
"log_request_headers": True,
"log_request_body": True,
"log_response_headers": True,
"log_response_body": True,
"log_exception": True,
"capture_logs": True,
"capture_traces": False, # requires instrumentation
# Mask query parameters using regex
"mask_query_params": [r"^card_number$"],
# Mask headers using regex
"mask_headers": [r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
"mask_body_fields": [r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
"mask_request_body_callback": lambda request: None if request["path"].startswith("/admin/") else request["body"],
"mask_response_body_callback": lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
"exclude_paths": [r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
"exclude_callback": lambda request, response: request["consumer"] == "some-consumer",
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
## Known issues
* When running Django with Gunicorn, the option `preload_app` must be set to `False`. Otherwise, the Apitally client will not work correctly.
* When running Django with uWSGI, the options `--enable-threads` and `--lazy-apps` must be set. Otherwise, the Apitally client will not work correctly.
# Setup guide for Django REST Framework
Source: https://docs.apitally.io/setup-guides/django-rest-framework
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Django REST Framework](https://www.django-rest-framework.org) (DRF) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[django_rest_framework]"
```
```shell poetry theme={null}
poetry add "apitally[django_rest_framework]"
```
```shell uv theme={null}
uv add "apitally[django_rest_framework]"
```
Activate the Apitally middleware in your Django application by appending it to the end of the [`MIDDLEWARE`](https://docs.djangoproject.com/en/4.2/topics/http/middleware/#activating-middleware) list in your Django settings.
Then configure the Apitally middleware by adding `APITALLY_MIDDLEWARE` to your settings file and including the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
MIDDLEWARE = [
"apitally.django.ApitallyMiddleware",
# Other middleware ...
]
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"include_django_views": False, # Set to True to include regular Django views
}
```
If you're using Gunicorn or uWSGI to serve your app in production, please review the [known issues](#known-issues) section below.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, provide a callback function in the middleware settings that takes a [`HttpRequest`](https://docs.djangoproject.com/en/4.2/ref/request-response/#httprequest-objects) object as an argument and returns a consumer identifier, an `ApitallyConsumer` object or `None`.
```python Callback theme={null}
from django.http import HttpRequest
def identify_consumer(request: HttpRequest) -> str | None:
if request.user.is_authenticated:
return request.user.username
return None
```
```python Callback (with name and group) theme={null}
from django.http import HttpRequest
from apitally.django import ApitallyConsumer
def identify_consumer(request: HttpRequest) -> ApitallyConsumer | None:
if request.user.is_authenticated:
return ApitallyConsumer(
identifier=request.user.username,
name=f"{request.user.first_name} {request.user.last_name}",
group=request.user.groups.first().name,
)
return None
```
```python Middleware settings theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"consumer_callback": "your_project.api.utils.identify_consumer",
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"enable_request_logging": True,
"log_request_headers": True,
"log_request_body": True,
"log_response_body": True,
"capture_logs": True,
"capture_traces": False, # requires instrumentation
}
```
```python Advanced example theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"enable_request_logging": True,
"log_query_params": True,
"log_request_headers": True,
"log_request_body": True,
"log_response_headers": True,
"log_response_body": True,
"log_exception": True,
"capture_logs": True,
"capture_traces": False, # requires instrumentation
# Mask query parameters using regex
"mask_query_params": [r"^card_number$"],
# Mask headers using regex
"mask_headers": [r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
"mask_body_fields": [r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
"mask_request_body_callback": lambda request: None if request["path"].startswith("/admin/") else request["body"],
"mask_response_body_callback": lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
"exclude_paths": [r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
"exclude_callback": lambda request, response: request["consumer"] == "some-consumer",
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Advanced settings
* By default, only DRF endpoints are included in Apitally. To also include regular Django views you can set `include_django_views` to `True`. Useful if your API includes endpoints not implemented using DRF.
* To limit Apitally to specific parts of a large monolithic application, set the `urlconfs` parameter to a list of Django URL configuration modules you'd like to include.
```python theme={null}
APITALLY_MIDDLEWARE = {
"client_id": "your-client-id",
"env": "dev", # or "prod" etc.
"include_django_views": True,
"urlconfs": ["your_project.api.urls"],
}
```
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
## Known issues
* When running Django with Gunicorn, the option `preload_app` must be set to `False`. Otherwise, the Apitally client will not work correctly.
* When running Django with uWSGI, the options `--enable-threads` and `--lazy-apps` must be set. Otherwise, the Apitally client will not work correctly.
# Setup guide for Echo
Source: https://docs.apitally.io/setup-guides/echo
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Echo](https://echo.labstack.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Add the [Apitally SDK](/sdk-reference/go/overview) to the dependencies in your Echo project.
```shell v5 theme={null}
go get github.com/apitally/apitally-go/echo-v5
```
```shell v4 theme={null}
go get github.com/apitally/apitally-go/echo-v4
```
Add the Apitally middleware to your Echo application and provide the `ClientId` for your app.
You'll find the `ClientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```go v5 theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/echo-v5"
"github.com/labstack/echo/v5"
)
func main() {
e := echo.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
e.Use(apitally.Middleware(e, config))
// ... rest of your code ...
}
```
```go v4 theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/echo-v4"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
e.Use(apitally.Middleware(e, config))
// ... rest of your code ...
}
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, use the `SetConsumerIdentifier` or `SetConsumer` function, for example in a middleware.
```go {8} Identifier only theme={null}
func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c *echo.Context) error {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
// Use the authenticated identity as consumer identifier
apitally.SetConsumerIdentifier(c, user.Identifier)
}
return next(c)
}
}
```
```go {7-11} With name and group theme={null}
func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c *echo.Context) error {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
apitally.SetConsumer(c, apitally.Consumer{
Identifier: user.Email,
Name: user.Name, // optional
Group: user.Group, // optional
})
}
return next(c)
}
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Capture validation errors
If you're using the `go-playground/validator/v10` package to validate incoming data, you can use the `CaptureValidationError` function to record validation errors.
This gives you visibility into the validation errors returned by your API endpoints.
```go {25} theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/echo-v5"
"github.com/labstack/echo/v5"
"github.com/go-playground/validator/v10"
)
type HelloRequest struct {
Name string `json:"name" validate:"required"`
}
func main() {
e := echo.New()
validate := validator.New()
// ...
e.POST("/hello", func(c *echo.Context) error {
var req HelloRequest
if err := c.Bind(&req); err != nil {
return c.JSON(400, map[string]string{"error": err.Error()})
}
if err := validate.Struct(req); err != nil {
apitally.CaptureValidationError(c, err)
return c.JSON(400, map[string]string{"error": err.Error()})
}
return c.JSON(200, map[string]string{"message": "Hello, " + req.Name + "!"})
})
// ...
}
```
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```go Basic example theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/echo-v5"
"github.com/labstack/echo/v5"
)
func main() {
e := echo.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
e.Use(apitally.Middleware(e, config))
// ... rest of your code ...
}
```
```go Advanced example theme={null}
package main
import (
"regexp"
"strings"
apitally "github.com/apitally/apitally-go/echo-v5"
"github.com/labstack/echo/v5"
)
func main() {
e := echo.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogQueryParams = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseHeaders = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.LogPanic = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
// Mask query parameters using regex
config.RequestLogging.MaskQueryParams = []*regexp.Regexp{regexp.MustCompile(`^card_number$`)}
// Mask headers using regex
config.RequestLogging.MaskHeaders = []*regexp.Regexp{regexp.MustCompile(`^X-Sensitive-Header$`)}
// Mask request/response body fields using regex
config.RequestLogging.MaskBodyFields = []*regexp.Regexp{regexp.MustCompile(`^sensitive_field$`)}
// Exclude paths from request logging using regex (common health check paths are excluded by default)
config.RequestLogging.ExcludePaths = []*regexp.Regexp{regexp.MustCompile(`/metrics$`)}
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return nil to mask the whole body, or return the (modified) raw body
config.RequestLogging.MaskRequestBodyCallback = func(request *apitally.Request) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return request.Body
}
config.RequestLogging.MaskResponseBodyCallback = func(request *apitally.Request, response *apitally.Response) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return response.Body
}
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
config.RequestLogging.ExcludeCallback = func(request *apitally.Request, response *apitally.Response) bool {
return request.Consumer == "some-consumer"
}
e.Use(apitally.Middleware(e, config))
// ... rest of your code ...
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `CaptureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/go/tracing) for further instructions.
# Setup guide for Elysia
Source: https://docs.apitally.io/setup-guides/elysia
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Elysia](https://elysiajs.com/) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your Elysia project.
```shell theme={null}
bun add apitally
```
Add the Apitally plugin to your Elysia application and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript theme={null}
import { Elysia } from "elysia";
import { apitallyPlugin } from "apitally/elysia";
const app = new Elysia()
.use(
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
}),
)
.get("/", () => "hello");
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Set the `apitally.consumer` property to associate requests with consumers, for example in a `derive` lifecycle function.
```javascript Identifier only theme={null}
app.derive(async ({ apitally, jwt, cookie: { auth } }) => {
const profile = await jwt.verify(auth);
apitally.consumer = profile.name;
});
```
```javascript With name and group theme={null}
app.derive(async ({ apitally, jwt, cookie: { auth } }) => {
const profile = await jwt.verify(auth);
apitally.consumer = {
identifier: profile.id,
name: profile.name,
group: profile.role,
};
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import { Elysia } from "elysia";
import { apitallyPlugin } from "apitally/elysia";
const app = new Elysia()
.use(
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
}),
)
.get("/", () => "hello");
```
```javascript Advanced example theme={null}
import { Elysia } from "elysia";
import { apitallyPlugin } from "apitally/elysia";
const app = new Elysia()
.use(
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
}),
)
.get("/", () => "hello");
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for Express
Source: https://docs.apitally.io/setup-guides/express
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Express](https://expressjs.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your Express project.
```shell npm theme={null}
npm install apitally
```
```shell yarn theme={null}
yarn add apitally
```
Add the Apitally middleware to your Express application using the `useApitally` function and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript ESM theme={null}
import express from "express";
import { useApitally } from "apitally/express";
const app = express();
app.use(express.json());
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
```
```javascript CommonJS theme={null}
const express = require("express");
const { useApitally } = require("apitally/express");
const app = express();
app.use(express.json());
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in a middleware.
```javascript Identifier only theme={null}
import { setConsumer } from "apitally/express";
app.use(function (req, res, next) {
if (req.user) {
setConsumer(req, req.user.username);
}
next()
})
```
```javascript With name and group theme={null}
import { setConsumer } from "apitally/express";
app.use(function (req, res, next) {
if (req.user) {
setConsumer(req, {
identifier: req.user.username,
name: `${req.user.first_name} ${req.user.last_name}`, // optional
group: req.user.group, // optional
});
}
next()
})
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Capture server errors
The Apitally SDK installs an error handler that captures server error details automatically.
It is added to the bottom of the middleware stack.
However, if your application already has custom error handlers that return a response and don't call `next(err)`, you need to add the following line of code for Apitally to capture server error details.
```javascript {2} theme={null}
app.use(function (err, req, res, next) {
res.locals.serverError = err;
// Your custom error handling logic ...
});
```
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import express from "express";
import { useApitally } from "apitally/express";
const app = express();
app.use(express.json());
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
});
```
```javascript Advanced example theme={null}
import express from "express";
import { useApitally } from "apitally/express";
const app = express();
app.use(express.json());
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
});
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
## Known issues
* `@sentry/node` v7 is incompatible with Apitally. It's instrumentation logic erases metadata on Express routers that Apitally requires. To resolve this, please upgrade `@sentry/node` to v8.
# Setup guide for FastAPI
Source: https://docs.apitally.io/setup-guides/fastapi
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [FastAPI](https://fastapi.tiangolo.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
Running FastAPI on Cloudflare Workers? Follow [this setup guide](/setup-guides/fastapi-cloudflare-workers) instead.
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[fastapi]"
```
```shell poetry theme={null}
poetry add "apitally[fastapi]"
```
```shell uv theme={null}
uv add "apitally[fastapi]"
```
Add the Apitally middleware to your FastAPI application and provide the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
from fastapi import FastAPI
from apitally.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
)
```
If you're also using other middlewares, add the `ApitallyMiddleware` last, so
that it wraps the existing stack of middlewares.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `set_consumer` function to associate requests with consumers, for example in a dependency, middleware or directly in your endpoint functions.
```python Dependency theme={null}
from typing import Annotated
from fastapi import FastAPI, Depends, Request
from apitally.fastapi import set_consumer
def identify_consumer(request: Request, current_user: Annotated[User, Depends(get_current_user)]) -> None:
set_consumer(
request,
identifier=current_user.user_id,
name=current_user.name, # optional
group=current_user.group, # optional
)
app = FastAPI(dependencies=[Depends(identify_consumer)])
```
```python Endpoint function theme={null}
from typing import Annotated
from fastapi import FastAPI, Depends, Request
from apitally.fastapi import set_consumer
app = FastAPI()
@app.get("/items")
async def list_items(request: Request, current_user: Annotated[User, Depends(get_current_user)]) -> list[str]:
set_consumer(
request,
identifier=current_user.user_id,
name=current_user.name, # optional
group=current_user.group, # optional
)
return ["item1"]
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
from fastapi import FastAPI
from apitally.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_request_headers=True,
log_request_body=True,
log_response_body=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
)
```
```python Advanced example theme={null}
from fastapi import FastAPI
from apitally.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_query_params=True,
log_request_headers=True,
log_request_body=True,
log_response_headers=True,
log_response_body=True,
log_exception=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
# Mask query parameters using regex
mask_query_params=[r"^card_number$"],
# Mask headers using regex
mask_headers=[r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
mask_body_fields=[r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
mask_request_body_callback=lambda request: None if request["path"].startswith("/admin/") else request["body"],
mask_response_body_callback=lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
exclude_paths=[r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
exclude_callback=lambda request, response: request["consumer"] == "some-consumer",
)
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
# Setup guide for FastAPI on Cloudflare Workers
Source: https://docs.apitally.io/setup-guides/fastapi-cloudflare-workers
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [FastAPI](https://fastapi.tiangolo.com) application running on [Cloudflare Workers](https://developers.cloudflare.com/workers/languages/python/) to work with Apitally.
If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Create Logpush job
Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and navigate to *Analytics & Logs > Logpush*. Create a [Logpush](https://developers.cloudflare.com/workers/observability/logs/logpush/) job with the following settings:
| Setting | Value |
| ---------------------------- | ------------------------------------------------------------------------------------------------ |
| Destination | HTTP destination |
| HTTP endpoint | `https://hub.apitally.io/v2/{client-id}/{env}/logpush` |
| Dataset | Workers trace events |
| If logs match... | Filtered logs:
EventType equals `fetch` and
ScriptName equals `{your-worker-name}` |
| Send the following fields... | General:
Event, EventTimestampMs, Logs |
In the HTTP endpoint, replace `{client-id}` with your app's client ID and `{env}` with the environment (e.g. `prod` or `dev`). In the filter criteria, replace `{your-worker-name}` with the name of your Worker, as specified in your Wrangler config.
## Add middleware
Next, install the [Apitally Serverless SDK](/sdk-reference/python-serverless/overview) in your project.
```shell theme={null}
uv add apitally-serverless
```
Add the Apitally middleware to your FastAPI application.
```python theme={null}
from fastapi import FastAPI
from apitally_serverless.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(ApitallyMiddleware)
```
If you're also using other middlewares, add the `ApitallyMiddleware` last, so
that it wraps the existing stack of middlewares.
## Configure Worker
Enable [Workers Logs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/) and [Logpush](https://developers.cloudflare.com/workers/observability/logs/logpush/) in your Wrangler configuration file.
```toml wrangler.toml theme={null}
logpush = true
[observability]
enabled = true
head_sampling_rate = 1
[observability.logs]
invocation_logs = true
```
```json wrangler.json theme={null}
{
"logpush": true,
"observability": {
"enabled": true,
"head_sampling_rate": 1,
"logs": {
"invocation_logs": true
}
}
}
```
Then, deploy your application to Cloudflare Workers.
```shell theme={null}
uv run pywrangler deploy
```
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard after the first request is handled.
It can take 2-3 minutes for requests to show up in Apitally due to how Cloudflare Logpush batches log data before sending it.
Also note that Cloudflare Logpush doesn't include requests from local development environments, so you won't see them in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `set_consumer` function to associate requests with consumers, for example in a dependency, middleware or directly in your endpoint functions.
```python Dependency theme={null}
from typing import Annotated
from fastapi import FastAPI, Depends, Request
from apitally_serverless.fastapi import set_consumer
def identify_consumer(request: Request, current_user: Annotated[User, Depends(get_current_user)]) -> None:
set_consumer(
request,
identifier=current_user.user_id,
name=current_user.name, # optional
group=current_user.group, # optional
)
app = FastAPI(dependencies=[Depends(identify_consumer)])
```
```python Endpoint function theme={null}
from typing import Annotated
from fastapi import FastAPI, Depends, Request
from apitally_serverless.fastapi import set_consumer
app = FastAPI()
@app.get("/items")
async def list_items(request: Request, current_user: Annotated[User, Depends(get_current_user)]) -> list[str]:
set_consumer(
request,
identifier=current_user.user_id,
name=current_user.name, # optional
group=current_user.group, # optional
)
return ["item1"]
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
With the serverless SDK, request logging is enabled by default, however request headers and request/response bodies are not included unless explicitly enabled.
The SDK automatically applies [default masking rules](/data-privacy#data-masking) for common sensitive headers and request/response body fields. You can configure additional masking rules and exclude certain requests from logging.
```python Basic example theme={null}
from fastapi import FastAPI
from apitally_serverless.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(
ApitallyMiddleware,
log_request_headers=True,
log_request_body=True,
log_response_body=True,
)
```
```python Advanced example theme={null}
from fastapi import FastAPI
from apitally_serverless.fastapi import ApitallyMiddleware
app = FastAPI()
app.add_middleware(
ApitallyMiddleware,
log_request_headers=True,
log_request_body=True,
log_response_headers=True,
log_response_body=True,
# Mask headers using regex
mask_headers=[r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
mask_body_fields=[r"^sensitive_field$"],
# Exclude paths from request logging using regex
exclude_paths=[r"/health$", r"/metrics$"],
)
```
The *Request logs* dashboard now shows individual requests handled by your application, including headers and payloads, if enabled. You can filter, search, and inspect them in detail.
# Setup guide for Fastify
Source: https://docs.apitally.io/setup-guides/fastify
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Fastify](https://fastify.dev) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add plugin
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) and the [fastify-plugin](https://www.npmjs.com/package/fastify-plugin) package in your Fastify project.
```shell npm theme={null}
npm install apitally fastify-plugin
```
```shell yarn theme={null}
yarn add apitally fastify-plugin
```
Register the Apitally plugin with your Fastify application and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript ESM theme={null}
import Fastify from "fastify";
import { apitallyPlugin } from "apitally/fastify";
const fastify = Fastify({ logger: true });
await fastify.register(apitallyPlugin, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
```
```javascript CommonJS theme={null}
const fastify = require("fastify")({ logger: true });
const { apitallyPlugin } = require("apitally/fastify");
fastify.register(apitallyPlugin, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
// Wrap your routes in a plugin, so Apitally can detect them
fastify.register((instance, opts, done) => {
instance.get("/", (request, reply) => {
reply.send("hello");
});
done();
});
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in an `onRequest` hook.
```javascript Identifier only theme={null}
import { setConsumer } from "apitally/fastify";
fastify.addHook("onRequest", async (request, reply) => {
try {
await request.jwtVerify(); // Assuming @fastify/jwt is used for authentication
setConsumer(request, request.user.name);
} catch (err) {
reply.send(err);
}
});
```
```javascript With name and group theme={null}
import { setConsumer } from "apitally/fastify";
fastify.addHook("onRequest", async (request, reply) => {
try {
await request.jwtVerify(); // Assuming @fastify/jwt is used for authentication
setConsumer(request, {
identifier: request.user.id.toString(),
name: request.user.name, // optional
group: request.user.group, // optional
});
} catch (err) {
reply.send(err);
}
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import Fastify from "fastify";
import { apitallyPlugin } from "apitally/fastify";
const fastify = Fastify({ logger: true });
await fastify.register(apitallyPlugin, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
});
```
```javascript Advanced example theme={null}
import Fastify from "fastify";
import { apitallyPlugin } from "apitally/fastify";
const fastify = Fastify({ logger: true });
await fastify.register(apitallyPlugin, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
});
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for Fiber
Source: https://docs.apitally.io/setup-guides/fiber
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Fiber](https://gofiber.io) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Add the [Apitally SDK](/sdk-reference/go/overview) to the dependencies in your Fiber project.
```shell v3 theme={null}
go get github.com/apitally/apitally-go/fiber-v3
```
```shell v2 theme={null}
go get github.com/apitally/apitally-go/fiber-v2
```
Add the Apitally middleware to your Fiber application and provide the `ClientId` for your app.
You'll find the `ClientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```go v3 theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/fiber-v3"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
app.Use(apitally.Middleware(app, config))
// ... rest of your code ...
}
```
```go v2 theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/fiber-v2"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
app.Use(apitally.Middleware(app, config))
// ... rest of your code ...
}
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, use the `SetConsumerIdentifier` or `SetConsumer` function, for example in a middleware.
```go {7} Identifier only theme={null}
func authMiddleware(c fiber.Ctx) error {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
// Use the authenticated identity as consumer identifier
apitally.SetConsumerIdentifier(c, user.Identifier)
}
return c.Next()
}
```
```go {6-10} With name and group theme={null}
func authMiddleware(c fiber.Ctx) error {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
apitally.SetConsumer(c, apitally.Consumer{
Identifier: user.Email,
Name: user.Name, // optional
Group: user.Group, // optional
})
}
return c.Next()
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Capture validation errors
If you're using the `go-playground/validator/v10` package to validate incoming data, you can use the `CaptureValidationError` function to record validation errors.
This gives you visibility into the validation errors returned by your API endpoints.
```go {23} theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/fiber-v3"
"github.com/gofiber/fiber/v3"
"github.com/go-playground/validator/v10"
)
type HelloRequest struct {
Name string `json:"name" validate:"required"`
}
func main() {
app := fiber.New()
validate := validator.New()
app.Post("/hello", func(c fiber.Ctx) error {
var req HelloRequest
if err := c.Bind().Body(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
if err := validate.Struct(req); err != nil {
apitally.CaptureValidationError(c, err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"message": "Hello, " + req.Name + "!",
})
})
// ...
}
```
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```go Basic example theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/fiber-v3"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
app.Use(apitally.Middleware(app, config))
// ... rest of your code ...
}
```
```go Advanced example theme={null}
package main
import (
"regexp"
"strings"
apitally "github.com/apitally/apitally-go/fiber-v3"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogQueryParams = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseHeaders = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.LogPanic = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
// Mask query parameters using regex
config.RequestLogging.MaskQueryParams = []*regexp.Regexp{regexp.MustCompile(`^card_number$`)}
// Mask headers using regex
config.RequestLogging.MaskHeaders = []*regexp.Regexp{regexp.MustCompile(`^X-Sensitive-Header$`)}
// Mask request/response body fields using regex
config.RequestLogging.MaskBodyFields = []*regexp.Regexp{regexp.MustCompile(`^sensitive_field$`)}
// Exclude paths from request logging using regex (common health check paths are excluded by default)
config.RequestLogging.ExcludePaths = []*regexp.Regexp{regexp.MustCompile(`/metrics$`)}
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return nil to mask the whole body, or return the (modified) raw body
config.RequestLogging.MaskRequestBodyCallback = func(request *apitally.Request) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return request.Body
}
config.RequestLogging.MaskResponseBodyCallback = func(request *apitally.Request, response *apitally.Response) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return response.Body
}
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
config.RequestLogging.ExcludeCallback = func(request *apitally.Request, response *apitally.Response) bool {
return request.Consumer == "some-consumer"
}
app.Use(apitally.Middleware(app, config))
// ... rest of your code ...
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `CaptureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/go/tracing) for further instructions.
# Setup guide for Flask
Source: https://docs.apitally.io/setup-guides/flask
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Flask](https://flask.palletsprojects.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[flask]"
```
```shell poetry theme={null}
poetry add "apitally[flask]"
```
```shell uv theme={null}
uv add "apitally[flask]"
```
Add the Apitally middleware to your Flask application and provide the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
from flask import Flask
from apitally.flask import ApitallyMiddleware
app = Flask(__name__)
app.wsgi_app = ApitallyMiddleware(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
)
```
If you're also using other middlewares, add the `ApitallyMiddleware` last, so
that it wraps the existing stack of middlewares.
If you're using Gunicorn or uWSGI to serve your app in production, please review the [known issues](#known-issues) section below.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `set_consumer` function to associate requests with consumers, for example within a [`before_request`](https://flask.palletsprojects.com/en/2.2.x/api/#flask.Flask.before_request) function or directly in your endpoint functions.
```python Before request theme={null}
from flask import g
from apitally.flask import set_consumer
@app.before_request
def identify_consumer():
if g.current_user:
set_consumer(
identifier=g.current_user["email"],
name=g.current_user["name"], # optional
group=g.current_user["role"], # optional
)
```
```python Endpoint function theme={null}
from flask import g
from apitally.flask import set_consumer
@app.route("/items")
def list_items():
if g.current_user:
set_consumer(
identifier=g.current_user["email"],
name=g.current_user["name"], # optional
group=g.current_user["role"], # optional
)
return ["item1"]
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
from flask import Flask
from apitally.flask import ApitallyMiddleware
app = Flask(__name__)
app.wsgi_app = ApitallyMiddleware(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_request_headers=True,
log_request_body=True,
log_response_body=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
)
```
```python Advanced example theme={null}
from flask import Flask
from apitally.flask import ApitallyMiddleware
app = Flask(__name__)
app.wsgi_app = ApitallyMiddleware(
app,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_query_params=True,
log_request_headers=True,
log_request_body=True,
log_response_headers=True,
log_response_body=True,
log_exception=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
# Mask query parameters using regex
mask_query_params=[r"^card_number$"],
# Mask headers using regex
mask_headers=[r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
mask_body_fields=[r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
mask_request_body_callback=lambda request: None if request["path"].startswith("/admin/") else request["body"],
mask_response_body_callback=lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
exclude_paths=[r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
exclude_callback=lambda request, response: request["consumer"] == "some-consumer",
)
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
## Known issues
* When running Flask with Gunicorn, the option `preload_app` must be set to `False`. Otherwise, the Apitally client will not work correctly.
* When running Flask with uWSGI, the options `--enable-threads` and `--lazy-apps` must be set. Otherwise, the Apitally client will not work correctly.
# Setup guide for Gin
Source: https://docs.apitally.io/setup-guides/gin
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Gin](https://gin-gonic.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Add the [Apitally SDK](/sdk-reference/go/overview) to the dependencies in your Gin project.
```shell theme={null}
go get github.com/apitally/apitally-go/gin
```
Add the Apitally middleware to your Gin application and provide the `ClientId` for your app.
You'll find the `ClientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```go theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/gin"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
r.Use(apitally.Middleware(r, config))
// ... rest of your code ...
}
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, use the `SetConsumerIdentifier` or `SetConsumer` function, for example in a middleware.
```go {8} Identifier only theme={null}
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
// Use the authenticated identity as consumer identifier
apitally.SetConsumerIdentifier(c, user.Identifier)
}
c.Next()
}
}
```
```go {7-11} With name and group theme={null}
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Your authentication logic here
// ...
if user.IsAuthenticated() {
apitally.SetConsumer(c, apitally.Consumer{
Identifier: user.Email,
Name: user.Name, // optional
Group: user.Group, // optional
})
}
c.Next()
}
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Capture validation errors
In order to get insights into validation errors returned by your API endpoints, you can capture them using the `CaptureValidationError` function.
```go {18} theme={null}
package main
import (
"net/http"
apitally "github.com/apitally/apitally-go/gin"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// ...
r.POST("/hello", func(c *gin.Context) {
var req struct {
Name string `json:"name" binding:"required"`
}
if err := c.BindJSON(&req); err != nil {
apitally.CaptureValidationError(c, err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "Hello, " + req.Name + "!",
})
})
// ...
}
```
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```go Basic example theme={null}
package main
import (
apitally "github.com/apitally/apitally-go/gin"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
r.Use(apitally.Middleware(r, config))
// ... rest of your code ...
}
```
```go Advanced example theme={null}
package main
import (
"regexp"
"strings"
apitally "github.com/apitally/apitally-go/gin"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
config := apitally.NewConfig("your-client-id")
config.Env = "dev" // or "prod" etc.
config.RequestLogging.Enabled = true
config.RequestLogging.LogQueryParams = true
config.RequestLogging.LogRequestHeaders = true
config.RequestLogging.LogRequestBody = true
config.RequestLogging.LogResponseHeaders = true
config.RequestLogging.LogResponseBody = true
config.RequestLogging.LogPanic = true
config.RequestLogging.CaptureLogs = true
config.RequestLogging.CaptureTraces = false // requires instrumentation
// Mask query parameters using regex
config.RequestLogging.MaskQueryParams = []*regexp.Regexp{regexp.MustCompile(`^card_number$`)}
// Mask headers using regex
config.RequestLogging.MaskHeaders = []*regexp.Regexp{regexp.MustCompile(`^X-Sensitive-Header$`)}
// Mask request/response body fields using regex
config.RequestLogging.MaskBodyFields = []*regexp.Regexp{regexp.MustCompile(`^sensitive_field$`)}
// Exclude paths from request logging using regex (common health check paths are excluded by default)
config.RequestLogging.ExcludePaths = []*regexp.Regexp{regexp.MustCompile(`/metrics$`)}
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return nil to mask the whole body, or return the (modified) raw body
config.RequestLogging.MaskRequestBodyCallback = func(request *apitally.Request) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return request.Body
}
config.RequestLogging.MaskResponseBodyCallback = func(request *apitally.Request, response *apitally.Response) []byte {
if strings.HasPrefix(request.Path, "/admin/") {
return nil // Mask the whole body for admin endpoints
}
return response.Body
}
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
config.RequestLogging.ExcludeCallback = func(request *apitally.Request, response *apitally.Response) bool {
return request.Consumer == "some-consumer"
}
r.Use(apitally.Middleware(r, config))
// ... rest of your code ...
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `CaptureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/go/tracing) for further instructions.
# Setup guide for H3 v2
Source: https://docs.apitally.io/setup-guides/h3
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [H3](https://h3.dev) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
Apitally only works with H3 v2 (currently in beta).
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add plugin
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your H3 project.
```shell npm theme={null}
npm install apitally
```
```shell yarn theme={null}
yarn add apitally
```
Register the Apitally plugin with your H3 application and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript Using instance config theme={null}
import { H3 } from "h3";
import { apitallyPlugin } from "apitally/h3";
const app = new H3({
plugins: [
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
}),
],
});
```
```javascript Register later theme={null}
import { H3 } from "h3";
import { apitallyPlugin } from "apitally/h3";
const app = new H3();
app.register(
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
})
);
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in a middleware.
```javascript Identifier only theme={null}
import { setConsumer } from "apitally/h3";
app.use((event) => {
setConsumer(event, event.context.auth?.username);
});
```
```javascript With name and group theme={null}
import { setConsumer } from "apitally/h3";
app.use((event) => {
setConsumer(event, {
identifier: event.context.auth?.username,
name: event.context.auth?.fullname,
group: event.context.auth?.role,
});
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import { H3 } from "h3";
import { apitallyPlugin } from "apitally/h3";
const app = new H3({
plugins: [
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
}),
],
});
```
```javascript Advanced example theme={null}
import { H3 } from "h3";
import { apitallyPlugin } from "apitally/h3";
const app = new H3({
plugins: [
apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
}),
],
});
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for hapi
Source: https://docs.apitally.io/setup-guides/hapi
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [hapi](https://hapi.dev) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Register plugin
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your hapi project.
```shell npm theme={null}
npm install apitally
```
```shell yarn theme={null}
yarn add apitally
```
Register the Apitally plugin with your hapi application and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript ESM theme={null}
import Hapi from "@hapi/hapi";
import { apitallyPlugin } from "apitally/hapi";
const init = async () => {
const server = Hapi.server({
port: 3000,
host: "localhost",
});
await server.register({
plugin: apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
}),
});
};
init();
```
```javascript CommonJS theme={null}
const Hapi = require("@hapi/hapi");
const { apitallyPlugin } = require("apitally/hapi");
const init = async () => {
const server = Hapi.server({
port: 3000,
host: "localhost",
});
await server.register({
plugin: apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
}),
});
};
init();
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in an `onPostAuth` lifecycle method.
```javascript Identifier only theme={null}
import { setConsumer } from "apitally/hapi";
server.ext("onPostAuth", (request, h) => {
if (request.auth.isAuthenticated) {
setConsumer(request, request.auth.credentials.user);
}
return h.continue;
});
```
```javascript With name and group theme={null}
import { setConsumer } from "apitally/hapi";
server.ext("onPostAuth", (request, h) => {
if (request.auth.isAuthenticated) {
const credentials = request.auth.credentials;
setConsumer(request, {
identifier: credentials.id,
name: credentials.name, // optional
group: credentials.group, // optional
});
}
return h.continue;
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import Hapi from "@hapi/hapi";
import { apitallyPlugin } from "apitally/hapi";
const init = async () => {
const server = Hapi.server({
port: 3000,
host: "localhost",
});
await server.register({
plugin: apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
}),
});
};
init();
```
```javascript Advanced example theme={null}
import Hapi from "@hapi/hapi";
import { apitallyPlugin } from "apitally/hapi";
const init = async () => {
const server = Hapi.server({
port: 3000,
host: "localhost",
});
await server.register({
plugin: apitallyPlugin({
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
}),
});
};
init();
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for Hono
Source: https://docs.apitally.io/setup-guides/hono
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Hono](https://hono.dev) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
Running Hono on Cloudflare Workers? Follow [this setup guide](/setup-guides/hono-cloudflare-workers) instead.
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your Hono project.
```shell npm theme={null}
npm install apitally
```
```shell yarn theme={null}
yarn add apitally
```
Add the Apitally middleware to your Hono application using the `useApitally` function and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript theme={null}
import { Hono } from "hono";
import { useApitally } from "apitally/hono";
const app = new Hono();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in a middleware.
```javascript Identifier only theme={null}
import { setConsumer } from "apitally/hono";
app.use(async (c, next) => {
const consumerIdentifier = c.get("jwtPayload")?.sub;
setConsumer(c, consumerIdentifier);
await next();
});
```
```javascript With name and group theme={null}
import { setConsumer } from "apitally/hono";
app.use(async (c, next) => {
const payload = c.get("jwtPayload");
if (payload) {
setConsumer(c, {
identifier: payload.sub,
name: payload.name, // optional
group: payload.group, // optional
});
}
await next();
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import { Hono } from "hono";
import { useApitally } from "apitally/hono";
const app = new Hono();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
});
```
```javascript Advanced example theme={null}
import { Hono } from "hono";
import { useApitally } from "apitally/hono";
const app = new Hono();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
});
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for Hono on Cloudflare Workers
Source: https://docs.apitally.io/setup-guides/hono-cloudflare-workers
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Hono](https://hono.dev) application running on [Cloudflare Workers](https://developers.cloudflare.com/workers/) to work with Apitally.
If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Create Logpush job
Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and navigate to *Analytics & Logs > Logpush*. Create a [Logpush](https://developers.cloudflare.com/workers/observability/logs/logpush/) job with the following settings:
| Setting | Value |
| ---------------------------- | ------------------------------------------------------------------------------------------------ |
| Destination | HTTP destination |
| HTTP endpoint | `https://hub.apitally.io/v2/{client-id}/{env}/logpush` |
| Dataset | Workers trace events |
| If logs match... | Filtered logs:
EventType equals `fetch` and
ScriptName equals `{your-worker-name}` |
| Send the following fields... | General:
Event, EventTimestampMs, Logs |
In the HTTP endpoint, replace `{client-id}` with your app's client ID and `{env}` with the environment (e.g. `prod` or `dev`). In the filter criteria, replace `{your-worker-name}` with the name of your Worker, as specified in your Wrangler config.
## Add middleware
Next, install the [Apitally Serverless SDK](/sdk-reference/javascript-serverless/overview) in your project.
```shell npm theme={null}
npm install @apitally/serverless
```
```shell yarn theme={null}
yarn add @apitally/serverless
```
Add the Apitally middleware to your Hono application using the `useApitally` function.
```javascript theme={null}
import { Hono } from "hono";
import { useApitally } from "@apitally/serverless/hono";
const app = new Hono();
useApitally(app);
// Ensure route handlers are registered after useApitally()
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
## Configure Worker
Enable [Workers Logs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/) and [Logpush](https://developers.cloudflare.com/workers/observability/logs/logpush/) in your Wrangler configuration file.
```toml wrangler.toml theme={null}
logpush = true
[observability]
enabled = true
head_sampling_rate = 1
[observability.logs]
invocation_logs = true
```
```json wrangler.json theme={null}
{
"logpush": true,
"observability": {
"enabled": true,
"head_sampling_rate": 1,
"logs": {
"invocation_logs": true
}
}
}
```
Then, deploy your application to Cloudflare Workers.
```shell theme={null}
wrangler deploy
```
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard after the first request is handled.
It can take 2-3 minutes for requests to show up in Apitally due to how Cloudflare Logpush batches log data before sending it.
Also note that Cloudflare Logpush doesn't include requests from local development environments, so you won't see them in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in a middleware.
```javascript Identifier only theme={null}
import { setConsumer } from "@apitally/serverless/hono";
app.use(async (c, next) => {
const consumerIdentifier = c.get("jwtPayload")?.sub;
setConsumer(c, consumerIdentifier);
await next();
});
```
```javascript With name and group theme={null}
import { setConsumer } from "@apitally/serverless/hono";
app.use(async (c, next) => {
const payload = c.get("jwtPayload");
if (payload) {
setConsumer(c, {
identifier: payload.sub,
name: payload.name, // optional
group: payload.group, // optional
});
}
await next();
});
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
With the serverless SDK, request logging is enabled by default, however request headers and request/response bodies are not included unless explicitly enabled.
The SDK automatically applies [default masking rules](/data-privacy#data-masking) for common sensitive headers and request/response body fields. You can configure additional masking rules and exclude certain requests from logging.
```javascript Basic example theme={null}
import { Hono } from "hono";
import { useApitally } from "@apitally/serverless/hono";
const app = new Hono();
useApitally(app, {
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
});
```
```javascript Advanced example theme={null}
import { Hono } from "hono";
import { useApitally } from "@apitally/serverless/hono";
const app = new Hono();
useApitally(app, {
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Exclude paths from request logging using regex
excludePaths: [/\/health$/, /\/metrics$/],
});
```
The *Request logs* dashboard now shows individual requests handled by your application, including headers and payloads, if enabled. You can filter, search, and inspect them in detail.
# Setup guide for Koa
Source: https://docs.apitally.io/setup-guides/koa
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Koa](https://koajs.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your Koa project.
```shell npm theme={null}
npm install apitally
```
```shell yarn theme={null}
yarn add apitally
```
Add the Apitally middleware to your Koa application using the `useApitally` function and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript ESM theme={null}
import Koa from "koa";
import { useApitally } from "apitally/koa";
const app = new Koa();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
```
```javascript CommonJS theme={null}
const Koa = require("koa");
const { useApitally } = require("apitally/koa");
const app = new Koa();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in a middleware.
```javascript Identifier only theme={null}
import { setConsumer } from "apitally/koa";
app.use(function (ctx, next) {
if (ctx.isAuthenticated()) {
setConsumer(ctx, ctx.state.user.username);
}
next()
})
```
```javascript With name and group theme={null}
import { setConsumer } from "apitally/koa";
app.use(function (ctx, next) {
if (ctx.isAuthenticated()) {
setConsumer(ctx, {
identifier: ctx.state.user.username,
name: `${ctx.state.user.firstName} ${ctx.state.user.lastName}`, // optional
group: ctx.state.user.group, // optional
});
}
next()
})
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import Koa from "koa";
import { useApitally } from "apitally/koa";
const app = new Koa();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
});
```
```javascript Advanced example theme={null}
import Koa from "koa";
import { useApitally } from "apitally/koa";
const app = new Koa();
useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
});
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for Litestar
Source: https://docs.apitally.io/setup-guides/litestar
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Litestar](https://litestar.dev/) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add plugin
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[litestar]"
```
```shell poetry theme={null}
poetry add "apitally[litestar]"
```
```shell uv theme={null}
uv add "apitally[litestar]"
```
Add the Apitally plugin to your Litestar application and provide the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
from litestar import Litestar
from apitally.litestar import ApitallyPlugin
apitally_plugin = ApitallyPlugin(
client_id="your-client-id",
env="dev", # or "prod" etc.
)
app = Litestar(route_handlers=[...], plugins=[apitally_plugin])
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `set_consumer` function to associate requests with consumers, for example in a `before_request` life cycle hook or directly in your route handler functions.
Alternatively, provide a callback function to the `ApitallyPlugin` that takes a [`Request`](https://docs.litestar.dev/latest/reference/connection.html#litestar.connection.Request) object as an argument and returns a consumer identifier, an `ApitallyConsumer` object or `None`.
```python Life cycle hook theme={null}
from litestar import Litestar
from litestar.connection import Request
from apitally.litestar import set_consumer
async def before_request_handler(request: Request) -> None:
if request.user.is_authenticated:
set_consumer(
request,
identifier=request.user.identity,
name=request.user.name, # optional
group=request.user.role, # optional
)
app = Litestar(
route_handlers=[...],
before_request=before_request_handler,
plugins=[apitally_plugin]
)
```
```python Callback function theme={null}
from litestar.connection import Request
from apitally.litestar import ApitallyPlugin, ApitallyConsumer
def get_consumer(request: Request) -> ApitallyConsumer | None:
if request.user.is_authenticated:
return ApitallyConsumer(
identifier=request.user.identity,
name=request.user.name, # optional
group=request.user.role, # optional
)
return None
apitally_plugin = ApitallyPlugin(
client_id="your-client-id",
env="dev", # or "prod" etc.
consumer_callback=get_consumer,
)
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
from litestar import Litestar
from apitally.litestar import ApitallyPlugin
apitally_plugin = ApitallyPlugin(
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_request_headers=True,
log_request_body=True,
log_response_body=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
)
app = Litestar(route_handlers=[...], plugins=[apitally_plugin])
```
```python Advanced example theme={null}
from litestar import Litestar
from apitally.litestar import ApitallyPlugin
apitally_plugin = ApitallyPlugin(
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_query_params=True,
log_request_headers=True,
log_request_body=True,
log_response_headers=True,
log_response_body=True,
log_exception=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
# Mask query parameters using regex
mask_query_params=[r"^card_number$"],
# Mask headers using regex
mask_headers=[r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
mask_body_fields=[r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
mask_request_body_callback=lambda request: None if request["path"].startswith("/admin/") else request["body"],
mask_response_body_callback=lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
exclude_paths=[r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
exclude_callback=lambda request, response: request["consumer"] == "some-consumer",
)
app = Litestar(route_handlers=[...], plugins=[apitally_plugin])
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
# Setup guide for NestJS
Source: https://docs.apitally.io/setup-guides/nestjs
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [NestJS](https://nestjs.com) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/javascript/overview) in your NestJS project.
```shell npm theme={null}
npm install apitally
```
```shell yarn theme={null}
yarn add apitally
```
Add the Apitally middleware to your NestJS application using the `useApitally` function and provide the `clientId` for your app.
You'll find the `clientId` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```javascript ESM theme={null}
import { NestFactory } from "@nestjs/core";
import { useApitally } from "apitally/nestjs";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
// ...
}
bootstrap();
```
```javascript CommonJS theme={null}
const { NestFactory } = require("@nestjs/core");
const { useApitally } = require("apitally/nestjs");
const { AppModule } = require("./app.module");
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
});
// ...
}
bootstrap();
```
Add the Apitally middleware before any other middleware to ensure it wraps the entire stack.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `setConsumer` function to associate requests with consumers, for example in an authorization guard.
```javascript Identifier only theme={null}
import { Injectable } from '@nestjs/common';
import { setConsumer } from "apitally/nestjs";
@Injectable()
export class AuthGuard {
async canActivate(context) {
const request = context.switchToHttp().getRequest();
const result = authenticateRequest(request); // assuming this sets request.user
if (result && request.user) {
setConsumer(request, request.user.username);
}
return result;
}
}
```
```javascript With name and group theme={null}
import { Injectable } from '@nestjs/common';
import { setConsumer } from "apitally/nestjs";
@Injectable()
export class AuthGuard {
async canActivate(context) {
const request = context.switchToHttp().getRequest();
const result = authenticateRequest(request); // assuming this sets request.user
if (result && request.user) {
setConsumer(request, {
identifier: request.user.username,
name: request.user.fullName, // optional
group: request.user.role, // optional
});
}
return result;
}
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```javascript Basic example theme={null}
import { NestFactory } from "@nestjs/core";
import { useApitally } from "apitally/nestjs";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseBody: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
},
});
// ...
}
bootstrap();
```
```javascript Advanced example theme={null}
import { NestFactory } from "@nestjs/core";
import { useApitally } from "apitally/nestjs";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await useApitally(app, {
clientId: "your-client-id",
env: "dev", // or "prod" etc.
requestLogging: {
enabled: true,
logQueryParams: true,
logRequestHeaders: true,
logRequestBody: true,
logResponseHeaders: true,
logResponseBody: true,
logException: true,
captureLogs: true,
captureTraces: false, // requires instrumentation
// Mask query parameters using regex
maskQueryParams: [/^card_number$/i],
// Mask headers using regex
maskHeaders: [/^X-Sensitive-Header$/i],
// Mask request/response body fields using regex
maskBodyFields: [/^sensitive_field$/i],
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
maskRequestBodyCallback: (request) => request.path?.startsWith("/admin/") ? null : request.body,
maskResponseBodyCallback: (request, response) => request.path?.startsWith("/admin/") ? null : response.body,
// Exclude paths from request logging using regex (common health check paths are excluded by default)
excludePaths: [/\/metrics$/],
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
excludeCallback: (request, response) => request.consumer === "some-consumer",
},
});
// ...
}
bootstrap();
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `captureTraces` to `true` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/javascript/tracing) for further instructions.
# Setup guide for Spring Boot
Source: https://docs.apitally.io/setup-guides/spring-boot
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Spring Boot](https://spring.io/projects/spring-boot) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Enable Apitally
Add the [Apitally SDK](/sdk-reference/java/overview) to your project's dependencies.
```xml Maven theme={null}
io.apitally
apitally
[0.1.0,)
```
```groovy Gradle theme={null}
dependencies {
implementation 'io.apitally:apitally:+'
}
```
Next, add the `@UseApitally` annotation to your Spring Boot application class.
```java Application.java {6} theme={null}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import io.apitally.spring.UseApitally;
@UseApitally
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
```
Then configure Apitally in your `application.yml` file and provide the client ID for your app.
You'll find the client ID on the *Setup instructions* page in the Apitally dashboard, which is displayed immediately after creating the app.
```yaml application.yml theme={null}
apitally:
client-id: "your-client-id"
env: "dev" # or "prod" etc.
```
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
To associate requests with consumers, set the `apitallyConsumer` attribute on the request. You could do this in a filter or interceptor, for example.
```java Identifier only theme={null}
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class ConsumerIdentificationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
request.setAttribute("apitallyConsumer", auth.getName());
}
chain.doFilter(request, response);
}
}
```
```java With name and group theme={null}
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import io.apitally.spring.ApitallyConsumer;
public class ConsumerIdentificationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
User user = (User) auth.getPrincipal();
request.setAttribute("apitallyConsumer", new ApitallyConsumer(
user.getUsername(), // identifier
user.getFullName(), // name
user.getRole() // group
));
}
chain.doFilter(request, response);
}
}
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
Check out the SDK reference to learn more about the request logging configuration options.
```yaml Basic example theme={null}
apitally:
client-id: "your-client-id"
env: "dev" # or "prod" etc.
request-logging:
enabled: true
request-headers-included: true
request-body-included: true
response-body-included: true
log-capture-enabled: true
```
```yaml Advanced example theme={null}
apitally:
client-id: "your-client-id"
env: "dev" # or "prod" etc.
request-logging:
enabled: true
query-params-included: true
request-headers-included: true
request-body-included: true
response-headers-included: true
response-body-included: true
exception-included: true
log-capture-enabled: true
# Mask query parameters using regex
query-param-mask-patterns:
- "^card_number$"
# Mask headers using regex
header-mask-patterns:
- "^X-Sensitive-Header$"
# Mask request/response body fields using regex
body-field-mask-patterns:
- "^sensitive_field$"
# Exclude paths from request logging using regex (common health check paths are excluded by default)
path-exclude-patterns:
- "/metrics$"
# Use callbacks for advanced masking and exclusion logic
callbacks-class: "com.example.MyRequestLoggingCallbacks"
```
```java RequestLoggingCallbacks.java theme={null}
import io.apitally.common.RequestLoggingCallbacks;
import io.apitally.common.dto.Request;
import io.apitally.common.dto.Response;
public class MyRequestLoggingCallbacks implements RequestLoggingCallbacks {
@Override
public byte[] maskRequestBody(Request request) {
// Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
// The callback should return null to mask the whole body, or return the (modified) raw body
if (request.getPath().startsWith("/admin/")) {
return null; // Mask the whole body for admin endpoints
}
return request.getBody();
}
@Override
public byte[] maskResponseBody(Request request, Response response) {
if (request.getPath().startsWith("/admin/")) {
return null; // Mask the whole body for admin endpoints
}
return response.getBody();
}
@Override
public boolean shouldExclude(Request request, Response response) {
// Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
// The callback should return true to exclude the request
return "some-consumer".equals(request.getConsumer());
}
}
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
# Setup guide for Starlette
Source: https://docs.apitally.io/setup-guides/starlette
Just a few simple steps to get started with Apitally.
This page guides you through the steps of configuring your [Starlette](https://www.starlette.io) application to work with Apitally. If you don't have an account yet, now would be a good time to [sign up](https://app.apitally.io/?signup).
Once you're done with this guide, you will be able to:
* Get detailed metrics on API usage, errors, and performance
* Track API adoption and usage by individual consumers
* Log individual API requests, responses, and correlated application logs
* See what's causing slow API requests with traces
* Monitor uptime and set up custom alerts
## Create app
To get started, create a new app in the [Apitally dashboard](https://app.apitally.io/apps) and select as your framework.
You can also configure the environments (e.g. `prod` and `dev`) for your app, or simply accept the defaults.
After submitting, you will see tailored setup instructions for your app. These include code snippets you can copy and paste into your project.
The **client ID** provided in the setup instructions uniquely identifies your app for the purpose of data ingestion only. It does not grant any kind of read access to your data.
## Add middleware
Next, install the [Apitally SDK](/sdk-reference/python/overview) in your project with the extra.
```shell pip theme={null}
pip install "apitally[starlette]"
```
```shell poetry theme={null}
poetry add "apitally[starlette]"
```
```shell uv theme={null}
uv add "apitally[starlette]"
```
Add the Apitally middleware to your Starlette application and provide the `client_id` for your app.
You'll find the `client_id` on the *Setup instructions* page for your app in the Apitally dashboard, which is displayed immediately after creating the app.
```python theme={null}
from starlette.applications import Starlette
from apitally.starlette import ApitallyMiddleware
app = Starlette(routes=[...])
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
)
```
If you're also using other middlewares, add the `ApitallyMiddleware` last, so
that it wraps the existing stack of middlewares.
Deploy your application with these changes, or restart if you're testing locally.
At this point the basic setup for your application is complete and you will start seeing data in the Apitally dashboard.
## Identify consumers
To analyze and filter API traffic by consumers, you can associate requests with consumer identifiers in your application.
In most cases, use the authenticated identity to identify the consumer.
The identifier should be a string, such as a username, email address, or any other unique identifier.
Optionally, you can also provide a display name and group for each consumer.
Use the `set_consumer` function to associate requests with consumers, for example in a middleware or directly in your endpoint functions.
Alternatively, you can provide a callback function to the `ApitallyMiddleware` that takes a [`Request`](https://www.starlette.io/requests/) object as an argument and returns a consumer identifier, an `ApitallyConsumer` object or `None`.
```python Using set_consumer theme={null}
from starlette.requests import Request
from apitally.starlette import set_consumer
def list_items(request: Request):
if request.user.is_authenticated:
set_consumer(
request,
identifier=request.user.identity,
name=request.user.display_name, # optional
group="Customers", # optional
)
return ["item1"]
```
```python Callback function theme={null}
from starlette.requests import Request
from apitally.starlette import ApitallyConsumer
def get_consumer(request: Request) -> ApitallyConsumer | None:
if request.user.is_authenticated:
return ApitallyConsumer(
identifier=request.user.identity,
name=request.user.display_name, # optional
group="Customers", # optional
)
return None
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
consumer_callback=get_consumer,
)
```
The *Consumers* dashboard now shows all consumers that have made requests to your application. You can also filter other dashboards by consumer.
## Configure request logging
Logging of individual requests and responses is disabled by default to protect potentially sensitive data.
If you enable it, you can configure in detail what parts of the request and response should be logged.
You can also mask sensitive information (e.g. in headers) and exclude certain requests from logging.
The SDK applies [default masking rules](/data-privacy#data-masking) for common sensitive headers, query parameters and request/response body fields.
```python Basic example theme={null}
from starlette.applications import Starlette
from apitally.starlette import ApitallyMiddleware
app = Starlette(routes=[...])
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_request_headers=True,
log_request_body=True,
log_response_body=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
)
```
```python Advanced example theme={null}
from starlette.applications import Starlette
from apitally.starlette import ApitallyMiddleware
app = Starlette(routes=[...])
app.add_middleware(
ApitallyMiddleware,
client_id="your-client-id",
env="dev", # or "prod" etc.
enable_request_logging=True,
log_query_params=True,
log_request_headers=True,
log_request_body=True,
log_response_headers=True,
log_response_body=True,
log_exception=True,
capture_logs=True,
capture_traces=False, # requires instrumentation
# Mask query parameters using regex
mask_query_params=[r"^card_number$"],
# Mask headers using regex
mask_headers=[r"^X-Sensitive-Header$"],
# Mask request/response body fields using regex
mask_body_fields=[r"^sensitive_field$"],
# Mask request/response body with custom logic via callbacks (e.g. for admin endpoints)
# The callback should return None to mask the whole body, or return the (modified) raw body
mask_request_body_callback=lambda request: None if request["path"].startswith("/admin/") else request["body"],
mask_response_body_callback=lambda request, response: None if request["path"].startswith("/admin/") else response["body"],
# Exclude paths from request logging using regex (common health check paths are excluded by default)
exclude_paths=[r"/metrics$"],
# Exclude requests from logging with custom logic via callback (e.g. exclude requests from a specific consumer)
# The callback should return True to exclude the request
exclude_callback=lambda request, response: request["consumer"] == "some-consumer",
)
```
The *Request logs* dashboard now shows individual requests handled by your application. You can filter, search, and inspect them in detail.
## Enable tracing
Tracing gives you a detailed breakdown of time spent during the handling of each request, showing the duration of database queries, HTTP calls, and other operations.
To enable tracing, set `capture_traces` to `True` and instrument the libraries you want to trace with OpenTelemetry. See the [tracing guide](/sdk-reference/python/tracing) for further instructions.
# Support
Source: https://docs.apitally.io/support
Where to go for help and sharing feedback.
If you already have access to the Apitally dashboard, the easiest way to reach out for support is to hit the *Get in touch* button in the sidebar. Alternatively, choose one of the options below.
Send us an email.
Create an issue or discussion.
Chat with us and the community.
Regardless of the method you choose, we're here to help you get the most out of Apitally and will respond as soon as we can.
# Usage limits
Source: https://docs.apitally.io/usage-limits
Understand the limits, quotas, and usage-based billing in Apitally.
You can track your current usage against your plan's limits and quotas in the dashboard under *Settings > Usage*.
Apitally has **no limits** on the number of requests processed for API metrics.
## Limits
Depending on your plan, there are hard limits on the number of apps and team members, as well as a usage limit on API consumers.
If you exceed a usage limit, your team will be notified and given a 7-day grace period. If usage remains above the limit after the grace period, Apitally will stop ingesting data for your apps until usage drops below the limit or you upgrade your plan. Your dashboard and historical data remain accessible.
### API consumers
The API consumers limit is based on the number of unique consumers that have made requests to your API within a rolling 24-hour period. This limit only applies if your application provides a consumer identifier for each request. See the [setup guide](/setup-guides) for your framework to learn how.
## Monthly quotas
Monthly quotas apply to request logs, application logs and spans in traces. Quotas are based on calendar months and reset at the start of each month.
If you exceed a monthly quota, Apitally stops ingesting new request logs, application logs or spans (depending on which quota was exceeded) until the start of the next month. Your API metrics are not affected.
You can exclude certain requests from logging using custom exclusion rules to reduce your usage and stay within quotas. Check out the [SDK reference](/sdk-reference) for details.
### Usage-based billing
On the Starter and Premium plans, you can enable usage-based billing under *Settings > Billing* in the dashboard. With usage-based billing enabled, data ingestion continues beyond your monthly quotas, and you are charged for the additional requests, logs or spans.
Usage-based billing is disabled by default.