more otel
This commit is contained in:
1 parent
9620e3bfa6
commit
21f04d696b
88 files changed
+23419
-192
No files matched your search
@@ -0,0 +1,175 @@
|
||||
# Instrumentation guide
|
||||
|
||||
This document describes the recommended instrumentation contract for this
|
||||
receiver. It is available at `/instrumentation.md` so frontend and backend
|
||||
agents can read it before integrating telemetry.
|
||||
|
||||
## Shared identity
|
||||
|
||||
Use the same values across all signals from one deployed application:
|
||||
|
||||
- `service.name`: stable application name, for example `checkout-web`.
|
||||
- `service.release`: immutable deploy identifier, for example
|
||||
`2026.09.18-a1b2c3`.
|
||||
- `service.environment`: `production`, `staging`, or `development`.
|
||||
|
||||
The release must exactly match the source-map upload release.
|
||||
|
||||
## Browser frontend
|
||||
|
||||
Load the RUM script and initialize it once, before the application starts:
|
||||
|
||||
```html
|
||||
<script src="https://otel.example.com/static/otel-rum.js"></script>
|
||||
<script>
|
||||
const rum = OtelRUM.init({
|
||||
serviceName: "checkout-web",
|
||||
release: "2026.09.18-a1b2c3",
|
||||
environment: "production",
|
||||
baseUrl: "https://otel.example.com"
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
The collector captures uncaught errors, unhandled promise rejections, failed
|
||||
HTTP requests, breadcrumbs, Web Vitals, and optional trace context. Correlate
|
||||
frontend requests with backend spans when possible:
|
||||
|
||||
```js
|
||||
fetch("/api/orders", { headers: rum.traceHeaders() });
|
||||
```
|
||||
|
||||
For manually handled errors:
|
||||
|
||||
```js
|
||||
try {
|
||||
riskyOperation();
|
||||
} catch (error) {
|
||||
rum.captureException(error, { "feature.name": "checkout" });
|
||||
}
|
||||
```
|
||||
|
||||
Do not put secrets, tokens, or sensitive customer data in breadcrumbs or
|
||||
custom attributes.
|
||||
|
||||
## React error boundaries
|
||||
|
||||
Rendering errors are not reliably caught by global `window.onerror` handlers.
|
||||
Report them from an error boundary and render a recovery screen:
|
||||
|
||||
```tsx
|
||||
import React from "react";
|
||||
|
||||
export class AppErrorBoundary extends React.Component<
|
||||
{ children: React.ReactNode },
|
||||
{ error: Error | null }
|
||||
> {
|
||||
state = { error: null as Error | null };
|
||||
|
||||
static getDerivedStateFromError(error: Error) {
|
||||
return { error };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: React.ErrorInfo) {
|
||||
window.OtelRUM?.last?.captureException(error, {
|
||||
"exception.type": "ReactErrorBoundary",
|
||||
"react.component_stack": info.componentStack,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.error) {
|
||||
return <button onClick={() => this.setState({ error: null })}>Retry</button>;
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use the same pattern in your application, including a user-visible fallback
|
||||
for individual views and the application root.
|
||||
|
||||
## Backend instrumentation
|
||||
|
||||
Instrument backend services with an OpenTelemetry SDK or auto-instrumentation
|
||||
and export OTLP to this receiver:
|
||||
|
||||
- OTLP/gRPC: `otel.example.com:4317`
|
||||
- OTLP/HTTP traces: `https://otel.example.com/v1/traces`
|
||||
- OTLP/HTTP metrics: `https://otel.example.com/v1/metrics`
|
||||
- OTLP/HTTP logs: `https://otel.example.com/v1/logs`
|
||||
|
||||
Set the resource attributes on every provider/exporter:
|
||||
|
||||
```text
|
||||
service.name=checkout-api
|
||||
service.release=2026.09.18-a1b2c3
|
||||
service.environment=production
|
||||
```
|
||||
|
||||
Create spans around inbound requests, database calls, external HTTP calls,
|
||||
queue operations, and important business operations. Record HTTP status,
|
||||
route, method, and exception details. Mark failed spans with an error status.
|
||||
The receiver derives backend issues from error spans and ERROR/FATAL logs.
|
||||
|
||||
If HTTP ingest authentication is enabled, provide `OTEL_INGEST_KEY` as the
|
||||
`X-Otel-Ingest-Key` header or `key` query parameter. Keep that key server-side;
|
||||
browser clients should not receive it.
|
||||
|
||||
For non-interactive agents that need to query protected debug endpoints, use a
|
||||
separate `OTEL_AGENT_TOKEN` service token. Send it as
|
||||
`X-Otel-Agent-Token: $OTEL_AGENT_TOKEN`; do not put it in browser code or
|
||||
telemetry payloads.
|
||||
|
||||
## Source maps
|
||||
|
||||
Build the frontend with the same immutable release used by RUM. The command
|
||||
and output directory depend on your build tool; the example below assumes a
|
||||
standard `dist/` output:
|
||||
|
||||
```sh
|
||||
export RELEASE="2026.09.18-a1b2c3"
|
||||
VITE_APP_RELEASE="$RELEASE" npm run build
|
||||
```
|
||||
|
||||
After deployment, upload the contents of each generated JavaScript map to the
|
||||
public multipart endpoint. No repository checkout or upload script is needed.
|
||||
`source` must match the generated bundle URL/path captured in the browser
|
||||
stack, while `file=@...` reads the local source-map file contents:
|
||||
|
||||
```sh
|
||||
curl --fail-with-body --silent --show-error \
|
||||
-X POST "https://otel.example.com/api/sourcemaps" \
|
||||
-F "release=$RELEASE" \
|
||||
-F "source=/assets/app-HASH.js" \
|
||||
-F "file=@dist/assets/app-HASH.js.map;type=application/json"
|
||||
```
|
||||
|
||||
For example, if the deployed JavaScript is available at
|
||||
`https://app.example.com/assets/main-abc123.js`, upload its matching map with
|
||||
`source=/assets/main-abc123.js`. The source-map filename on the build machine
|
||||
does not need to match the URL, but the `source` field must.
|
||||
|
||||
Maps are parsed and retained server-side. Issue responses include a resolved
|
||||
stack when `service.release` and the generated bundle path match. Original
|
||||
source files and map contents are never returned by the API.
|
||||
|
||||
The Docker build removes `.map` files from production images by default. For
|
||||
development or staging, public maps can be enabled for Chrome DevTools:
|
||||
|
||||
```sh
|
||||
PUBLIC_SOURCEMAPS=true ./build.sh
|
||||
```
|
||||
|
||||
Public maps expose application source code and should not be enabled in
|
||||
production unless that is intentional.
|
||||
|
||||
## Verification checklist
|
||||
|
||||
1. Trigger a controlled frontend exception.
|
||||
2. Trigger a controlled backend error span or ERROR log.
|
||||
3. Confirm both appear under Issues as separate frontend/backend issues.
|
||||
4. Confirm the issue sample contains the expected release.
|
||||
5. Confirm a mapped frontend stack shows original file and line information.
|
||||
6. Confirm trace IDs connect frontend requests to backend traces where headers
|
||||
were propagated.
|
||||
Reference in new issue
Block a user