# Monitoring and alerting

**Use Commerce Integration Layer signals to detect extension errors and set up alerts in your Application Performance Monitoring (APM) tool.**

Because the Commerce Integration Layer runs your extension code in a managed environment, you cannot monitor the performance of the extensions directly. Instead, monitor the [signals](/commerce-integration-layer/development/monitoring-and-alerting.md#signal-sources) the environment emits: outbound calls, execution timeouts, and latency.

Use the signals described in this guide to detect extension errors and performance issues. With this information, optimize the performance of your extensions according to the guidance in [Operations and performance](/commerce-integration-layer/development/operations-and-performance.md).

## Shared responsibilities

While commercetools monitors platform reliability, you are responsible for monitoring your extension code, external dependencies, and your identity provider (IdP).

### commercetools responsibilities

commercetools is responsible for monitoring and resolving platform-internal issues, including:

- Commerce Integration Layer errors (excluding extension runtime errors).
- Control plane availability and latency (project enrollment, bundle publishing, and Merchant Center views).
- Managed extension execution environment failures.
- Platform-driven GraphQL schema errors. (When publishing fails, the router continues serving the last valid schema).

You do not need to set up alerts for these items. Contact [commercetools support](https://support.commercetools.com/) if you observe platform-level issues.

### Your responsibilities

commercetools does not alert on failures originating inside your extensions. You must set up alerts for these issues in your APM tool.
Set up monitoring for the following conditions:

- Slow Managed API Extension handlers and timeouts: see [Recommended deadline alerts](/commerce-integration-layer/development/monitoring-and-alerting.md#recommended-deadline-alerts).
- Failed, slow, or blocked outbound HTTP calls: see [Recommended HTTP alerts](/commerce-integration-layer/development/monitoring-and-alerting.md#recommended-http-alerts).
- Identity provider failures or latency: see [Recommended identity provider alerts](/commerce-integration-layer/development/monitoring-and-alerting.md#recommended-identity-provider-alerts).
- Extension bundle deployment failures: see [Control plane](/commerce-integration-layer/development/monitoring-and-alerting.md#control-plane).

## Signal sources

Signals come from two sources: Platform Insights and the Deployment Logs API or CLI. Some signals are available from both. Before setting up an alert, confirm which source you use. Platform Insights and the Deployment Logs API or CLI expose different fields and have different access methods.

| Signal | Platform Insights (APM tool) | API or CLI |
| --- | --- | --- |
| [Outbound HTTP calls](/commerce-integration-layer/development/monitoring-and-alerting.md#outbound-http-calls) | ✓ | ✓ |
| [Managed API Extension deadlines](/commerce-integration-layer/development/monitoring-and-alerting.md#managed-api-extension-deadlines) | ✓ | ✓ for handlers that declare `timeoutInMs` |
| [Managed API Extension timeouts and latency](/api/platform-insights.md#extension-logs) | ✓ |  |
| [Identity provider errors](/commerce-integration-layer/development/monitoring-and-alerting.md#identity-provider-errors) | ✓ |  |
| [Control plane](/commerce-integration-layer/development/monitoring-and-alerting.md#control-plane) |  | CLI output only, not logs |

### Extension runtime logs

JSON logs from the [Deployment](/connect/deployments.md) running your extension. They cover outbound HTTP calls and Managed API Extension deadlines, which are described in the sections below.

Query the logs using the [Deployment Logs](/connect/deployment-logs.md) endpoints or `commercetools connect deployment logs`. The fields of each log line are in `details`.

To alert on them in your APM tool, use [Platform Insights](/api/platform-insights.md). Alternatively, poll the Deployment Logs API or CLI yourself and feed the result into your own alerting.

Only alert on the log messages and fields listed on this page. Unlisted log lines can change without notice.

### Platform Insights logs and metrics

Platform Insights forwards logs and metrics to your Application Performance Monitoring (APM) tool. These three signals are not available through the Deployment Logs API or CLI. The Platform Insights page documents their log lines and fields:

- **API Extension logs**: one log line for each call to an [API Extension](/api/projects/api-extensions.md), including [Managed API Extensions](/commerce-integration-layer/managed-api-extensions.md). See [Extension logs](/api/platform-insights.md#extension-logs).
- **Identity provider logs**: one log line for each call to your identity provider. The Commerce Integration Layer writes this line outside your extension's Deployment. See [Identity provider logs](/commerce-integration-layer/development/monitoring-and-alerting.md#identity-provider-logs).
- **Metric**: `ct_extension_time_sec`. See [Extension processing time](/api/platform-insights.md#ct_extension_time_sec-extension-processing-time).

1. Set up the integration with your APM tool. See [APM integration](/guides/apm-integration.md).
2. Create alerts in your APM tool, for example on `ct_extension_time_sec`.

### Outbound HTTP calls

Every `fetch` call writes a log with `message: "EXTENSION HTTP REQUEST"` and `event: "extension.http_request"`. Query strings and headers are not logged.

| `level` | Meaning |
| --- | --- |
| `info` | A response was received. Check `http_response_status_code` for the result. |
| `warn` | The request was blocked before sending. See `extension_fetch_refused_reason`. |
| `error` | The request failed without a response, for example because of a network failure or a canceled request. See `error_type`. |

#### Fields

| Field | Description |
| --- | --- |
| `event` | `extension.http_request` |
| `http_request_method` | HTTP method |
| `url_scheme` | `https` or `http` |
| `server_address` | Target host (use to group alerts by dependency) |
| `server_port` | Target port (if non-default) |
| `url_path` | Target path |
| `http_response_status_code` | HTTP status code |
| `http_response_body_size` | Response size in bytes, from `Content-Length`. For a compressed response, this is the compressed size. |
| `http_response_body_encoding` | Response `Content-Encoding`, or `identity` if none |
| `http_client_request_duration` | Request duration in seconds |
| `http_client_queue_ms`, `http_client_connect_ms`, `http_client_dns_ms`, `http_client_tcp_ms`, `http_client_tls_ms`, `http_client_ttfb_ms` | Time in milliseconds spent in each phase of the call. A field is omitted if the phase did not occur, for example no connect time on a reused connection. |
| `extension_fetch_allowed` | `true` if sent, `false` if blocked |
| `extension_fetch_refused_reason` | Reason the call was blocked |
| `extension_fetch_block_reason` | Internal target type when blocked by `blocked_target` |
| `error_type` | Error code for failed calls, for example `ECONNREFUSED` |

```json title="Response received"
{
  "level": "info",
  "message": "EXTENSION HTTP REQUEST",
  "event": "extension.http_request",
  "http_request_method": "GET",
  "url_scheme": "https",
  "server_address": "api.us-central1.gcp.commercetools.com",
  "url_path": "/my-project/orders/order-number=12345",
  "http_response_status_code": 200,
  "http_response_body_encoding": "gzip",
  "http_client_request_duration": 0.42,
  "http_client_queue_ms": 1,
  "http_client_ttfb_ms": 410,
  "extension_fetch_allowed": true,
  "correlation_id": "6c1f0e3a-8d2b-4f57-9a41-2b7e5d0c9f13",
  "extension_source_revision": "6f8e284fd23b",
  "timestamp": "2026-10-02T01:51:15.778Z"
} 
```

#### Blocked and failed request examples

The request was blocked before sending (`warn`):

```json title="Blocked request"
{
  "level": "warn",
  "message": "EXTENSION HTTP REQUEST",
  "event": "extension.http_request",
  "http_request_method": "POST",
  "url_scheme": "https",
  "server_address": "api.example.com",
  "url_path": "/v1/orders",
  "extension_fetch_allowed": false,
  "extension_fetch_refused_reason": "host_not_allowlisted",
  "correlation_id": "6c1f0e3a-8d2b-4f57-9a41-2b7e5d0c9f13",
  "timestamp": "2026-10-02T01:51:15.778Z"
}
```

The request failed without a response (`error`):

```json title="Failed request"
{
  "level": "error",
  "message": "EXTENSION HTTP REQUEST",
  "event": "extension.http_request",
  "http_request_method": "GET",
  "url_scheme": "https",
  "server_address": "api.example.com",
  "url_path": "/v1/orders",
  "http_client_request_duration": 0.03,
  "extension_fetch_allowed": true,
  "error_type": "ECONNREFUSED",
  "correlation_id": "6c1f0e3a-8d2b-4f57-9a41-2b7e5d0c9f13",
  "timestamp": "2026-10-02T01:51:15.778Z"
}
```

#### Refused request reasons

The `extension_fetch_refused_reason` field shows why a request was blocked.

|  | Cause | Action |
| --- | --- | --- |
| `host_not_allowlisted` | Host is not on the allowlist. | Add the host to the [outbound HTTP domain allowlist](/commerce-integration-layer/development/configure-and-deploy.md#outbound-http-domain-allowlist). |
| `host_denied` | Host is on your allowlist but blocked by commercetools. | Call a different host. |
| `blocked_target` | Target is an internal IP or metadata address. Allowlisting the host has no effect. | Use a public endpoint. |
| `bad_protocol` | Protocol is not `http` or `https`. | Use `https`. |
| `invalid_url` | Malformed URL. | Fix the URL. |
| `instance_retired` | Code executed after the request finished. | Ensure async work finishes before returning. |

#### Recommended HTTP alerts

These alerts use extension runtime logs, available in Platform Insights and through the Deployment Logs API or CLI (see [Extension runtime logs](/commerce-integration-layer/development/monitoring-and-alerting.md#extension-runtime-logs)). Create alerts in your APM tool or poll the Deployment Logs API to drive your own alerting.

| Trigger | Typical cause |
| --- | --- |
| `level` is `warn` and `extension_fetch_refused_reason` is `host_not_allowlisted` | A new release is calling an unapproved host. |
| High rate of `level` `error` for a single `server_address` | Target host is unreachable. |
| High rate of `http_response_status_code` 500 or above for a single `server_address` | Target host is failing. |
| More than 5% of calls to a `server_address` exceed your latency budget | Target host is slow. |

### Managed API Extension deadlines

[Managed API Extensions](/commerce-integration-layer/managed-api-extensions.md) can be observed in Platform Insights [extension logs](/api/platform-insights.md#extension-logs) and, in aggregate, in the [`ct_extension_time_sec`](/api/platform-insights.md#ct_extension_time_sec-extension-processing-time) metric.

When a Managed API Extension exceeds its [deadline](/commerce-integration-layer/development/writing-managed-api-extensions.md#handler-deadline), the write fails. The following log is available for this case.

#### Fields

| Field | Value |
| --- | --- |
| `level` | `error` |
| `message` | `api-extension handler exceeded its deadline` |
| `event` | `api_extension.timeout` |
| `handlerKey` | Key of the timed-out handler |
| `deadlineMs` | Deadline that applied to the handler, in milliseconds. |

```json title="Handler deadline exceeded"
{
  "level": "error",
  "message": "api-extension handler exceeded its deadline",
  "event": "api_extension.timeout",
  "handlerKey": "validate-cart",
  "deadlineMs": 1750,
  "correlation_id": "6c1f0e3a-8d2b-4f57-9a41-2b7e5d0c9f13",
  "timestamp": "2026-10-02T01:51:15.778Z"
} 
```

#### Recommended deadline alerts

The first trigger uses an extension runtime log, available in Platform Insights and through the Deployment Logs API or CLI. The other two are Platform Insights signals forwarded to your APM tool.

| Trigger | Typical cause |
| --- | --- |
| Any log with `event` `api_extension.timeout` (Platform Insights, Deployment Logs API, or CLI) | Handler is timing out. Optimize code or increase `timeoutInMs`. |
| Platform Insights: `extension_duration` in the extension logs approaches the handler's `timeoutInMs` | Handler latency is close to failing writes. Group by `extension_key`, which contains the handler's `key`, to find the handler. |
| Platform Insights: `ct_extension_time_sec` rises | Overall extension latency is increasing. The metric isn't broken down by extension, so use the extension logs to find which one. |

### Identity provider errors

Every call to your configured [identity provider](/commerce-integration-layer/development/identity-providers.md) (code exchange at sign-in, token refresh, or revocation at sign-out) writes one log line with `upstream: "idp"` and the IdP's HTTP response status. Platform Insights forwards this line to your APM tool. It isn't available through the Deployment Logs API or CLI.

Use the `upstream` field to distinguish identity provider calls (`"idp"`) from commercetools calls (`"commercetools"`).

An incorrect client secret is typically rejected by the IdP with a 4xx status and logged at `info`. To find rejected requests, alert on `http_status_code` rather than on `level`.

#### Identity provider logs

The log lines are identified by `upstream: "idp"` and `ct_service_name: "integration-layer"`. They don't include the request query, headers, or body, because they carry the client secret and tokens.

The `level` depends on whether the identity provider responded, not on whether it accepted the request:

| IdP outcome | `level` |
| --- | --- |
| Response with a status below 500, including 4xx | `info` |
| Response with a status of 500 or above | `warning` |
| No response (timeout, DNS failure, and so on) | `err` |

In addition to `ctp_project_key`, `duration`, `environment`, `level`, `message`, `severity`, and `timestamp`, each log entry contains the following fields:

| Field | Description |
| --- | --- |
| `upstream` | `idp` |
| `http_method` | HTTP method. |
| `http_host` | Identity provider host. |
| `http_path` | Identity provider endpoint path. |
| `http_status_code` | HTTP status code of the identity provider response. Absent if the request failed without a response. |
| `http_status` | Same value as `http_status_code`, kept for compatibility. |
| `http_response_time_ms` | Request duration in milliseconds. |
| `http_received_bytes` | Size of the response, from its `Content-Length` header. Absent if the response has none. |
| `http_response_content_type` | `Content-Type` of the response. |
| `http_content_encoding` | `Content-Encoding` of the response, or `identity` if none. |

The `message` contains the method, path, status, and duration. If the request fails without a response, the message is `idp POST /oauth2/token failed: {reason}` and the line has no `http_status_code`.

```json title="Example of an identity provider log entry"
{
  "ct_service_name": "integration-layer",
  "ctp_project_key": "my-project",
  "duration": 0.212,
  "environment": "prod",
  "http_content_encoding": "identity",
  "http_host": "idp.example.com",
  "http_method": "POST",
  "http_path": "/oauth2/token",
  "http_received_bytes": 87,
  "http_response_content_type": "application/json",
  "http_response_time_ms": 212,
  "http_status": 503,
  "http_status_code": 503,
  "level": "warning",
  "message": "idp POST /oauth2/token 503 212ms",
  "severity": "warning",
  "timestamp": "2026-10-02T01:51:15.778Z",
  "upstream": "idp"
}
```

#### Recommended identity provider alerts

| Alert trigger | Common cause |
| --- | --- |
| Any log with `upstream: "idp"` and `http_status_code` of `400` or above, or with `level` `err` (no response) | Sign-in, token refresh, or sign-out was rejected or failed, or the IdP didn't respond. |
| High rate of `upstream: "idp"` calls with `http_status_code` `400` or above, for a single Project | Invalid IdP credentials, incorrect endpoint configuration, rate limiting, or an IdP outage. |
| More than 5% of `upstream: "idp"` calls exceed your latency budget (`duration`) | The IdP is slow. |

For detailed troubleshooting steps, see [IdP failures and latency](/commerce-integration-layer/development/identity-providers.md#idp-failures-and-latency).

## Control plane

Control plane tasks (enrolling projects, publishing bundles, configuration) return status directly, so log alerts are not required:

- **CI/CD pipeline**: run `commercetools integration-layer extension push` without `--no-wait`. The command waits for the extension to load the bundle, for up to 180 seconds by default (set it with `--wait-timeout`). If the bundle fails to load, the command prints the failure reason and exits with a non-zero code. The project keeps serving the previous working revision. If the wait times out, the command doesn't fail, so check its output for the result.
- **Status checks**: run `commercetools integration-layer extension status` at any time to see the newest stored revision (version, size, upload time, filename, uploader, and `sourceRevision` when recorded). It doesn't report lifecycle state, a failure reason, or which revision is actually served — for the outcome of a specific push, use its own `--wait` output; to check at any later time, use the Merchant Center extension panel. If nothing has ever been pushed, the command reports that no extension code is stored.

## Related pages

- [Overview](/commerce-integration-layer/overview.md)
- [Operations and performance](/commerce-integration-layer/development/operations-and-performance.md)
- [Best practices](/commerce-integration-layer/development/best-practices.md)

## Related pages

- [Area overview page with navigation](/commerce-integration-layer.md)
- [Previous page: Operations and performance](/commerce-integration-layer/development/operations-and-performance.md)
- [Next page: Best practices](/commerce-integration-layer/development/best-practices.md)
- [Search documentation and API specs](/search.md)