> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/powershell-universal/platform/plugins/opentelemetry.md).

# OpenTelemetry

Configure the OpenTelemetry plugin to export PowerShell Universal metrics and traces, including custom API endpoint telemetry.

**Identifier:** `PowerShellUniversal.Plugins.OpenTelemetry`

The OpenTelemetry plugin exports PowerShell Universal metrics and ASP.NET Core traces through OTLP. Use an OpenTelemetry-compatible collector, dashboard, or metrics backend to inspect platform activity and custom API endpoint requests.

## Enable the plugin

Add the exact, fully qualified plugin identifier to the `Plugins` array in `appsettings.json`. The default persistence provider is SQLite.

```json
{
  "Plugins": [
    "PowerShellUniversal.SQLite",
    "PowerShellUniversal.Plugins.OpenTelemetry"
  ]
}
```

{% hint style="warning" %}
The short name `OpenTelemetry` and the assembly name `PowerShellUniversal.Plugin.OpenTelemetry` do not enable the plugin. Use `PowerShellUniversal.Plugins.OpenTelemetry` exactly as shown above.
{% endhint %}

Configure the OTLP endpoint and restart PowerShell Universal after changing plugin or telemetry settings.

## Configure OTLP export

Set `OpenTelemetry:Otlp:Endpoint` to use one endpoint for both metrics and traces. If the fallback endpoint ends in `/v1/metrics`, PowerShell Universal uses that URL for metrics and automatically uses the corresponding `/v1/traces` URL for traces.

```json
{
  "OpenTelemetry": {
    "Otlp": {
      "Endpoint": "http://localhost:4318/v1/metrics"
    }
  }
}
```

To use separate collectors or endpoints, configure the signal-specific settings. These settings override the fallback endpoint for their respective signals.

```json
{
  "OpenTelemetry": {
    "ServiceName": "PowerShellUniversal-Production",
    "Otlp": {
      "MetricsEndpoint": "http://metrics-collector:4318/v1/metrics",
      "TracesEndpoint": "http://traces-collector:4318/v1/traces"
    }
  }
}
```

The default service name is `PowerShellUniversal`. OTLP uses HTTP/protobuf by default. To set the protocol explicitly, set `OTEL_EXPORTER_OTLP_PROTOCOL` to the .NET enum name `HttpProtobuf` or `Grpc`.

{% hint style="warning" %}
Do not use the OpenTelemetry specification value `http/protobuf` for `OTEL_EXPORTER_OTLP_PROTOCOL`. PowerShell Universal binds this setting directly to the .NET `OtlpExportProtocol` enum, so `http/protobuf` causes a startup configuration error. Use `HttpProtobuf` instead.
{% endhint %}

## Custom API endpoint telemetry

The plugin instruments custom API endpoint requests, including conventional and regular-expression endpoints. Each request produces an ASP.NET Core trace span named with the HTTP method and endpoint definition, such as `GET /users/{id}`.

Endpoint spans include these attributes:

| Attribute                   | Description                                    |
| --------------------------- | ---------------------------------------------- |
| `http.route`                | The configured endpoint URL or pattern.        |
| `psu.endpoint.id`           | The PowerShell Universal endpoint ID.          |
| `psu.endpoint.url`          | The configured endpoint URL or pattern.        |
| `http.response.status_code` | The HTTP status code returned by the endpoint. |

Use these attributes to filter traces for a particular endpoint or response status in your telemetry backend.

The plugin also exports endpoint metrics through the `PSU.Endpoints` meter:

* `PSU.Endpoint.Execution.Count`
* `PSU.Endpoint.Execution.Duration` in milliseconds
* `PSU.Endpoint.Execution.IncomingContentLength` in bytes
* `PSU.Endpoint.Execution.OutgoingContentLength` in bytes

## Prometheus metrics

Prometheus can receive OTLP metrics when its OTLP receiver is enabled.

```powershell
.\prometheus.exe --web.enable-otlp-receiver
```

Configure the metrics endpoint with Prometheus's OTLP metrics URL. Prometheus is a metrics backend; configure a trace-capable collector or backend separately when you also want to export traces.

```json
{
  "OpenTelemetry": {
    "Otlp": {
      "MetricsEndpoint": "http://localhost:9090/api/v1/otlp/v1/metrics"
    }
  }
}
```

## Environment variables

Use double underscores for nested configuration keys and zero-based indexes for the `Plugins` array. This Docker Compose example enables the plugin and exports metrics and traces over HTTP/protobuf:

```yaml
environment:
  Plugins__1: PowerShellUniversal.Plugins.OpenTelemetry
  OpenTelemetry__Otlp__Endpoint: http://collector:4318/v1/metrics
  OTEL_EXPORTER_OTLP_PROTOCOL: HttpProtobuf
```

You can also configure signal-specific endpoints:

```
OpenTelemetry__Otlp__MetricsEndpoint=http://metrics-collector:4318/v1/metrics
OpenTelemetry__Otlp__TracesEndpoint=http://traces-collector:4318/v1/traces
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.devolutions.net/powershell-universal/platform/plugins/opentelemetry.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
