Skip to content

Commit 2e67a1b

Browse files
Otel tutorials (#208)
* Refocus docs on on-prem and link to OpsPilot for cloud features - Restructured nav to remove cloud/OpsPilot features (alerts, incidents, OTel, log monitoring, k8s) - Renamed FEATURES to FR AGENT FEATURES, removed cloud-only feature cards from index - Updated index journey steps: removed Obs Agent step, added OpsPilot card - Updated intro-to-fr: removed cloud features, added OpsPilot admonition - Updated Trial page to reference OpsPilot instead of FusionReactor Cloud - Updated OTel getting-started to remove cloud references, link to OpsPilot docs - Removed em dashes from updated pages Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Restructure nav to topic-based on-premise focused layout and clean up index page Remove cloud/OpsPilot features (Deep, OTel section, Popular Docs) from index and replace old section-based nav with topic-based structure: GETTING STARTED, INSTALLATION, MONITORING, DIAGNOSTICS, PERFORMANCE, LOGS & DATA, SYSTEM HEALTH, DASHBOARDS, CONFIGURATION, FAQs, INTEGRATIONS, ADMIN & DATA. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove New UI FAQ page and nav entry Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix YAML indentation in mkdocs.yml after new-ui-faq removal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove cloud-focused tutorial pages and update remaining pages for on-premise focus Remove: alerts-slow-requests, cpu-spikes, RCA-in-Services, create-dashboard, know-the-ui, troubleshoot-crash overview, Releases overview. Update: best-ways-to-monitor, scalability, capacity-planning, memory-leaks, Tutorials Overview - strip cloud UI refs and add OpsPilot tip admonitions where relevant. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix YAML indentation in mkdocs.yml after cpu-spikes removal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Clean up Common support issues pages - remove cloud refs and cloud-only pages Remove billing-usage.md and endpoints.md (cloud-only). Update find-license-key, move-license-key, increase-SQL-query, onprem-login to remove cloud UI references. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove (On-Premise) suffix from common support issue page titles Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Improve tutorial readability, remove cloud refs, eliminate duplicates - Remove crash-troubleshoot-cloud.md (cloud-only) - Remove reports.md (duplicate - merged troubleshooting section into set-email-reports.md) - Fix resolve-slow-queries: remove cloud UI refs and Russian word bug - Rewrite identify-slow-requests: remove cloud-only steps, add on-premise metrics step - Fix increase-SQL-query, TLS-deprecation-guide: remove remaining cloud mentions - Update Overview.md: remove CPU spikes and Application observability references - Simplify memory-leaks, scalability, capacity-planning, UEM: reduce verbosity, remove redundant steps, standardise bullet style to hyphens Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Merge three license pages into single managing-license-keys.md Combines find-license-key, move-license-key, and check-license-seat into one consolidated page with clear sections. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add redirects for merged license key pages Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove cloud-only feature pages, rewrite four pages with OpsPilot links Rewrites: - ADoverview.md: stripped cloud setup, kept explanation + OpsPilot tip - Alerts-overview.md: replaced Grafana alerting docs with on-premise/OpsPilot summary - Cloud-Status.md: updated to reference OpsPilot instead of FusionReactor Cloud - Cloud-State-Log.md: removed cloud-license-only restriction note Deleted cloud-only content: - Anomaly Detection user guide - All Alerting sub-pages (Alert-Rules, Contact-points, Silences, etc.) - OpsPilot feature docs and images - Admin-and-data: Cloud account, Cloud billing, api-keys, org-settings, usage-and-details - Monitor-your-data: Deep, MCP, Log-monitoring (all cloud integrations) - Troubleshooting: Cloud-*.md pages, Optimize-data.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Revert "Remove cloud-only feature pages, rewrite four pages with OpsPilot links" This reverts commit 041916a. * Convert cloud-only pages to OpsPilot holding pages Replace detailed cloud content across 38 pages with brief summaries and links to docs.opspilot.com / app.opspilot.com. Covers: Anomaly Detection, Alerting, OpsPilot features, Admin cloud pages, Log monitoring, Deep, MCP, Cloud troubleshooting pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update holding pages with specific OpsPilot doc URLs Each page now links directly to its equivalent on docs.opspilot.com using the mirrored URL structure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Restructure nav, redesign home page, add OpsPilot holding pages and billing info - Restructure nav: flatten Getting Started, add Tutorials & Walkthroughs section, rename Installation to Installation Guides, consolidate features into single FEATURES section with OpsPilot UI subfolder at bottom - Restore tutorial pages: new-ui-faq, know-the-ui, create-dashboard, RCA-in-Services, alerts-slow-requests, set-up-integrations from main branch - Add OpsPilot holding pages for OpenTelemetry, Kubernetes monitoring; convert Log monitoring, Deep, MCP to single-page nav entries - Remove Observability Agent from nav; collapse OTel, K8s, Log monitoring, Deep, MCP Interfaces to single overview pages pointing to OpsPilot docs - Redesign index page: show nav, compact 3-step cards, OpsPilot card in orange, FR summary box and OpsPilot call-out below - Replace em dashes with hyphens across 43 files - Add OpsPilot billing section to on-prem billing page with Metric Shipping info - Update Cloud invoice reference to OpsPilot; rename On-Premise users to Users Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add OTel tutorial pages and enable tabbed extension --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1d7c0b5 commit 2e67a1b

3 files changed

Lines changed: 398 additions & 0 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Migrating from a dual OTel + FR agent setup
2+
3+
From version **2025.2.0**, the FusionReactor agent ships OTel data natively. If you were previously running a standalone OTel Java agent alongside the FR agent, you can remove it and let the FR agent handle shipping directly.
4+
5+
This page covers what the FR agent handles, what it does not, and how to migrate your collector configuration.
6+
7+
## What the FR agent handles
8+
9+
The FR agent (2025.2.0+) automatically collects and ships:
10+
11+
- **Traces** - all request traces instrumented by the FR agent
12+
- **Metrics** - JVM metrics, HTTP request metrics, and FR agent instrumentation metrics
13+
- **Logs** - application logs captured by the FR agent
14+
15+
These are shipped via the built-in OTel exporter to whichever endpoint you configure (OpsPilot by default).
16+
17+
## What the FR agent does not handle
18+
19+
### Custom metrics via `GlobalOpenTelemetry`
20+
21+
The FR agent does not register itself as the global OTel SDK instance. If your application code calls `GlobalOpenTelemetry.get()` to record custom metrics or spans, those calls will return a no-op implementation - your custom instrumentation will not be collected.
22+
23+
If you rely on custom metrics or spans created via `GlobalOpenTelemetry`, you have two options:
24+
25+
- **Keep a standalone OTel agent** for custom instrumentation alongside the FR agent (point both at the same collector)
26+
- **Initialise the OTel SDK explicitly** in your application code so it does not depend on the global instance
27+
28+
Example of explicit SDK initialisation (Java):
29+
30+
```java
31+
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
32+
.registerMetricReader(
33+
PeriodicMetricReader.builder(
34+
OtlpGrpcMetricExporter.builder()
35+
.setEndpoint("http://localhost:4317")
36+
.build()
37+
).build()
38+
)
39+
.build();
40+
41+
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder()
42+
.setMeterProvider(meterProvider)
43+
.build();
44+
45+
Meter meter = openTelemetry.getMeter("your-instrumentation-name");
46+
```
47+
48+
This creates an independent OTel instance that ships to the same collector as the FR agent, without depending on the global singleton.
49+
50+
### FRAPI metrics
51+
52+
Metrics recorded via the FusionReactor FRAPI are captured locally and visible in the FR UI. They are not currently included in OTel shipping.
53+
54+
## Migration steps
55+
56+
### Step 1: Remove the standalone OTel agent
57+
58+
Remove the `-javaagent:/path/to/opentelemetry-javaagent.jar` JVM argument from your startup configuration. The FR agent now handles OTel shipping, so the standalone agent is no longer needed for standard instrumentation.
59+
60+
If you have custom metrics via `GlobalOpenTelemetry`, see the section above before removing the standalone agent.
61+
62+
### Step 2: Update your collector configuration
63+
64+
If you were previously sending OTel data from a standalone agent to a collector, and that collector was already forwarding to OpsPilot, you need to update the metrics pipeline to use Prometheus Remote Write format. OpsPilot does not accept raw OTLP metrics.
65+
66+
=== "OTel Collector (before)"
67+
68+
```yaml
69+
exporters:
70+
otlp/opspilot:
71+
endpoint: https://api.fusionreactor.io
72+
headers:
73+
authorization: "${env:FR_API_KEY}"
74+
75+
service:
76+
pipelines:
77+
metrics:
78+
receivers: [otlp]
79+
processors: [batch]
80+
exporters: [otlp/opspilot]
81+
```
82+
83+
=== "OTel Collector (after)"
84+
85+
```yaml
86+
exporters:
87+
prometheusremotewrite/opspilot:
88+
endpoint: https://api.fusionreactor.io/v1/metrics
89+
headers:
90+
authorization: "${env:FR_API_KEY}"
91+
92+
otlphttp/opspilot:
93+
endpoint: https://api.fusionreactor.io
94+
headers:
95+
authorization: "${env:FR_API_KEY}"
96+
97+
service:
98+
pipelines:
99+
traces:
100+
receivers: [otlp]
101+
processors: [batch]
102+
exporters: [otlphttp/opspilot]
103+
metrics:
104+
receivers: [otlp]
105+
processors: [batch]
106+
exporters: [prometheusremotewrite/opspilot]
107+
logs:
108+
receivers: [otlp]
109+
processors: [batch]
110+
exporters: [otlphttp/opspilot]
111+
```
112+
113+
!!! warning
114+
Use the `otel/opentelemetry-collector-contrib` image. The standard `otel/opentelemetry-collector` image does not include the `prometheusremotewrite` exporter.
115+
116+
=== "Alloy (before)"
117+
118+
```hcl
119+
otelcol.exporter.otlphttp "opspilot" {
120+
client {
121+
endpoint = "https://api.fusionreactor.io"
122+
headers = {
123+
"authorization" = env("FR_API_KEY"),
124+
}
125+
}
126+
}
127+
128+
otelcol.processor.batch "default" {
129+
output {
130+
metrics = [otelcol.exporter.otlphttp.opspilot.input]
131+
logs = [otelcol.exporter.otlphttp.opspilot.input]
132+
traces = [otelcol.exporter.otlphttp.opspilot.input]
133+
}
134+
}
135+
```
136+
137+
=== "Alloy (after)"
138+
139+
```hcl
140+
// Traces and logs via OTLP HTTP
141+
otelcol.exporter.otlphttp "opspilot" {
142+
client {
143+
endpoint = "https://api.fusionreactor.io"
144+
headers = {
145+
"authorization" = env("FR_API_KEY"),
146+
}
147+
}
148+
}
149+
150+
// Metrics via Prometheus Remote Write
151+
otelcol.exporter.prometheus "opspilot" {
152+
forward_to = [prometheus.remote_write.opspilot.receiver]
153+
}
154+
155+
prometheus.remote_write "opspilot" {
156+
endpoint {
157+
url = "https://api.fusionreactor.io/v1/metrics"
158+
headers = {
159+
"authorization" = env("FR_API_KEY"),
160+
}
161+
}
162+
}
163+
164+
otelcol.processor.batch "default" {
165+
output {
166+
metrics = [otelcol.exporter.prometheus.opspilot.input]
167+
logs = [otelcol.exporter.otlphttp.opspilot.input]
168+
traces = [otelcol.exporter.otlphttp.opspilot.input]
169+
}
170+
}
171+
```
172+
173+
!!! warning
174+
OpsPilot requires the raw API key in the `Authorization` header without a `Bearer ` prefix. Do not use `otelcol.auth.bearer` - it adds the prefix automatically.
175+
176+
### Step 3: Verify data is arriving
177+
178+
1. Open the **Cloud Status** page in the local FusionReactor UI (`localhost:8088` by default) and confirm shipping is active.
179+
2. Check OpsPilot to verify metrics, traces, and logs are appearing.
180+
3. If you have custom instrumentation, confirm those metrics are still being recorded (either via the standalone agent you kept, or via the explicitly initialised SDK).
181+
182+
## Summary
183+
184+
| | Standalone OTel agent | FR agent 2025.2.0+ |
185+
|---|---|---|
186+
| Standard JVM metrics | Yes | Yes |
187+
| Request traces | Yes | Yes |
188+
| Logs | Yes | Yes |
189+
| Custom `GlobalOpenTelemetry` metrics | Yes | No |
190+
| FRAPI metrics | No | Local only |
191+
192+
For the full shipping configuration reference, see [OTel shipping with FusionReactor](otel-shipping.md).
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# OTel shipping with FusionReactor
2+
3+
From version **2025.2.0**, the FusionReactor agent includes built-in OpenTelemetry (OTel) support and ships metrics, traces, and logs directly to any OTel-compatible destination. You no longer need to run a separate OTel agent alongside FusionReactor.
4+
5+
## Shipping modes
6+
7+
There are three shipping modes depending on your setup:
8+
9+
| Mode | When it applies | Config required |
10+
|---|---|---|
11+
| **Default (OpsPilot)** | No existing OTel endpoint configured | None |
12+
| **Single endpoint** | You configure one external OTel endpoint | Set `otel.exporter.otlp.endpoint` |
13+
| **Multiple destinations** | You need to ship to more than one destination | Collector required |
14+
15+
## Default: shipping to OpsPilot
16+
17+
Without any OTel endpoint configured, the FR agent automatically ships all metrics, traces, and logs to OpsPilot. No configuration is needed.
18+
19+
If you upgrade from a pre-2025.2.0 agent with no existing OTel configuration, your data will appear in OpsPilot automatically.
20+
21+
## Single endpoint shipping
22+
23+
To override the OpsPilot default and ship to a single external provider (Datadog, New Relic, Dash0, Grafana, etc.), configure the endpoint via system property or environment variable:
24+
25+
```properties
26+
otel.exporter.otlp.endpoint=https://your-endpoint:4317
27+
```
28+
29+
```bash
30+
export OTEL_EXPORTER_OTLP_ENDPOINT=https://your-endpoint:4317
31+
```
32+
33+
!!! warning
34+
When you configure an external endpoint, shipping to OpsPilot stops. To keep sending data to OpsPilot alongside another destination, use a collector instead.
35+
36+
If you had an existing OTel configuration before upgrading to 2025.2.0, the FR agent picks up your configured endpoint automatically - your data will go to that endpoint rather than OpsPilot.
37+
38+
## Multiple destinations via a collector
39+
40+
To ship to more than one destination simultaneously, point the FR agent at a local collector, then configure the collector to fan out to multiple destinations.
41+
42+
The FR agent configuration is the same regardless of which collector you use:
43+
44+
```properties
45+
otel.exporter.otlp.endpoint=http://localhost:4317
46+
```
47+
48+
Then configure your collector:
49+
50+
=== "OTel Collector"
51+
52+
The OpenTelemetry Collector uses YAML configuration. Create or edit your `collector.yaml`:
53+
54+
```yaml
55+
receivers:
56+
otlp:
57+
protocols:
58+
grpc:
59+
endpoint: 0.0.0.0:4317
60+
http:
61+
endpoint: 0.0.0.0:4318
62+
63+
processors:
64+
batch:
65+
timeout: 5s
66+
send_batch_size: 1000
67+
68+
exporters:
69+
otlp/grafana:
70+
endpoint: https://<your-stack>.grafana.net/otlp
71+
headers:
72+
authorization: "Basic <base64(instanceID:apiToken)>"
73+
74+
prometheusremotewrite/opspilot:
75+
endpoint: https://api.fusionreactor.io/v1/metrics
76+
headers:
77+
authorization: "${env:FR_API_KEY}"
78+
79+
otlphttp/opspilot:
80+
endpoint: https://api.fusionreactor.io
81+
headers:
82+
authorization: "${env:FR_API_KEY}"
83+
84+
service:
85+
pipelines:
86+
traces:
87+
receivers: [otlp]
88+
processors: [batch]
89+
exporters: [otlp/grafana, otlphttp/opspilot]
90+
metrics:
91+
receivers: [otlp]
92+
processors: [batch]
93+
exporters: [otlp/grafana, prometheusremotewrite/opspilot]
94+
logs:
95+
receivers: [otlp]
96+
processors: [batch]
97+
exporters: [otlp/grafana, otlphttp/opspilot]
98+
```
99+
100+
!!! info "OpsPilot metrics format"
101+
OpsPilot ingests metrics in **Prometheus Remote Write format**, not raw OTLP. The metrics pipeline must use the `prometheusremotewrite` exporter targeting `https://api.fusionreactor.io/v1/metrics`. Use the `otel/opentelemetry-collector-contrib` image - the standard `otel/opentelemetry-collector` image does not include this exporter.
102+
103+
=== "Alloy"
104+
105+
Grafana Alloy uses HCL syntax. Create or edit your `collector.alloy`:
106+
107+
```hcl
108+
otelcol.receiver.otlp "default" {
109+
grpc {
110+
endpoint = "0.0.0.0:4317"
111+
}
112+
http {
113+
endpoint = "0.0.0.0:4318"
114+
}
115+
116+
output {
117+
metrics = [otelcol.processor.batch.default.input]
118+
logs = [otelcol.processor.batch.default.input]
119+
traces = [otelcol.processor.batch.default.input]
120+
}
121+
}
122+
123+
otelcol.processor.batch "default" {
124+
timeout = "5s"
125+
send_batch_size = 1000
126+
127+
output {
128+
metrics = [otelcol.exporter.otlp.grafana.input, otelcol.exporter.prometheus.opspilot.input]
129+
logs = [otelcol.exporter.otlp.grafana.input, otelcol.exporter.otlphttp.opspilot.input]
130+
traces = [otelcol.exporter.otlp.grafana.input, otelcol.exporter.otlphttp.opspilot.input]
131+
}
132+
}
133+
134+
otelcol.exporter.otlp "grafana" {
135+
client {
136+
endpoint = "https://<your-stack>.grafana.net/otlp"
137+
auth = otelcol.auth.basic.grafana.handler
138+
}
139+
}
140+
141+
otelcol.auth.basic "grafana" {
142+
username = env("GRAFANA_INSTANCE_ID")
143+
password = env("GRAFANA_API_TOKEN")
144+
}
145+
146+
// OpsPilot traces and logs
147+
otelcol.exporter.otlphttp "opspilot" {
148+
client {
149+
endpoint = "https://api.fusionreactor.io"
150+
headers = {
151+
"authorization" = env("FR_API_KEY"),
152+
}
153+
}
154+
}
155+
156+
// OpsPilot metrics - convert to Prometheus Remote Write format
157+
otelcol.exporter.prometheus "opspilot" {
158+
forward_to = [prometheus.remote_write.opspilot.receiver]
159+
}
160+
161+
prometheus.remote_write "opspilot" {
162+
endpoint {
163+
url = "https://api.fusionreactor.io/v1/metrics"
164+
headers = {
165+
"authorization" = env("FR_API_KEY"),
166+
}
167+
}
168+
}
169+
```
170+
171+
!!! warning
172+
OpsPilot requires the raw API key in the `Authorization` header **without** a `Bearer ` prefix. Use a plain `headers` map rather than `otelcol.auth.bearer`, which adds the prefix automatically.
173+
174+
`FR_API_KEY` is your OpsPilot API key from **Account Settings > API Keys** in the OpsPilot UI. This is different from your FR licence key.
175+
176+
## Troubleshooting
177+
178+
### Verifying your configuration
179+
180+
Check the **Cloud Status** page in the local FusionReactor UI (`localhost:8088` by default) to confirm that OTel shipping settings have been applied and shipping is active. Also review the agent startup logs for any configuration errors or warnings.
181+
182+
### Data not appearing in OpsPilot
183+
184+
- Verify your endpoint URL is correct
185+
- Check that authentication credentials are set via environment variables
186+
- Ensure the protocol matches the endpoint (gRPC uses port `4317`, HTTP uses `4318`)
187+
- Check collector logs if using a collector
188+
189+
### Connection errors
190+
191+
- Verify network connectivity to the endpoint
192+
- Check that firewall rules allow outbound connections on the required ports
193+
- Ensure the endpoint supports the protocol you have configured
194+
195+
### Authentication failures
196+
197+
- Verify that API keys/tokens are valid and not expired
198+
- Check the header format matches the provider's requirements
199+
- Ensure environment variables are set and accessible to the process
200+
201+
For further help, see the [OpsPilot OpenTelemetry troubleshooting guide](https://docs.opspilot.com/Monitor-your-data/OpenTelemetry/Troubleshooting) or contact support via the chat bubble on this page.

0 commit comments

Comments
 (0)