-
Notifications
You must be signed in to change notification settings - Fork 214
docs: add documentation for experimental browser proxy handler #1742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,26 +7,31 @@ integration: logfire | |
|
|
||
| The `@pydantic/logfire-browser` NPM package wraps [OpenTelemetry browser tracing](https://opentelemetry.io/docs/languages/js/getting-started/browser/) with sensible defaults and provides a simple API for creating spans and reporting exceptions. | ||
|
|
||
| !!! info | ||
| Logfire does not directly expose an endpoint suitable for sending traces from the browser, as this would make your write token publicly accessible. To send traces from the browser, you must create a proxy in your app that **forwards requests from your browser instrumentation to Logfire** while adding the `Authorization` header. Check the [Next.js proxy example implementation](https://github.com/pydantic/logfire-js/blob/main/examples/nextjs-client-side-instrumentation/proxy.ts) for more details. | ||
| !!! info "Securely Sending Traces" | ||
| Logfire does not directly expose an endpoint suitable for sending traces from the browser, as this would make your write token publicly accessible. | ||
|
|
||
| To safely send traces, you must route them through a backend proxy that attaches the `Authorization` header server-side. | ||
| - **Python:** Use the built-in `logfire_proxy` handler for [FastAPI](../web-frameworks/fastapi.md#proxying-browser-telemetry) or [Starlette](../web-frameworks/starlette.md#proxying-browser-telemetry). | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the forward_export_request function is worth mentioning for generic usage. |
||
| - **Next.js:** Check out the [Next.js proxy example implementation](https://github.com/pydantic/logfire-js/blob/main/examples/nextjs-client-side-instrumentation/proxy.ts). | ||
|
|
||
| ## Simple Usage | ||
|
|
||
| ```ts | ||
| import { getWebAutoInstrumentations } from "@opentelemetry/auto-instrumentations-web"; | ||
| import * as logfire from '@pydantic/logfire-browser'; | ||
|
|
||
| // Set the path to your traces proxy endpoint - assuming it's hosted at `/client-traces`, same domain. | ||
| // Set the path to your backend proxy endpoint | ||
| // For example, if using the Python `logfire_proxy` handler hosted on the same domain: | ||
| const url = new URL(window.location.href); | ||
| url.pathname = "/client-traces"; | ||
| url.pathname = "/logfire-proxy/v1/traces"; | ||
|
|
||
| logfire.configure({ | ||
| traceUrl: url.toString(), | ||
| serviceName: 'my-service', | ||
| serviceVersion: '0.1.0', | ||
| // The instrumentations to use | ||
| // https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-web - for more options and configuration | ||
| instrumentations: [ | ||
| instrumentations:[ | ||
| getWebAutoInstrumentations() | ||
| ], | ||
| // This outputs details about the generated spans in the browser console, use only in development and for troubleshooting. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -109,6 +109,52 @@ The main request span will still have the attributes described above, but it wil | |
| This is mostly redundant now and is mainly provided for backwards compatibility. | ||
| It can also be useful for grouping together child logs and spans produced by the request. | ||
|
|
||
|
|
||
| ## Proxying Browser Telemetry | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't think this belongs on this page, same for starlette. it's not about how to instrument fastapi. i think the browser page should get a proper section on the topic with this info, explaining how to do it with fastapi, starlette, or anything else. the fastapi and starlette pages can briefly mention and link to that. |
||
|
|
||
| If you have a frontend application (e.g., React, Vue, or Vanilla JS) that sends telemetry from the browser, you should **never** expose your Logfire Write Token in the frontend code. | ||
|
|
||
| Instead, you can use experimental proxy handler to securely forward OTLP telemetry from the browser through your FastAPI backend to Logfire. | ||
|
|
||
| ```py title="main.py" skip-run="true" skip-reason="server-start" | ||
| from fastapi import FastAPI, Request | ||
|
|
||
| import logfire | ||
| from logfire.experimental.forwarding import logfire_proxy | ||
|
|
||
| logfire.configure() | ||
| app = FastAPI() | ||
|
|
||
|
|
||
| # Mount the proxy handler | ||
| # Note: {path:path} is strictly required to capture the OTLP route (e.g., /v1/traces) | ||
| @app.post('/logfire-proxy/{path:path}') | ||
| async def proxy_browser_telemetry(request: Request): | ||
| return await logfire_proxy(request) | ||
| ``` | ||
|
|
||
| By default, this endpoint is unauthenticated and accepts payloads up to 50MB. In production, you should protect it using FastAPI dependencies to prevent abuse: | ||
|
|
||
| ```py skip-run="true" skip-reason="server-start" | ||
| from fastapi import Depends, FastAPI, Request | ||
|
|
||
| import logfire | ||
| from logfire.experimental.forwarding import logfire_proxy | ||
|
|
||
| logfire.configure() | ||
| app = FastAPI() | ||
|
|
||
|
|
||
| async def verify_user_session(): | ||
| # Implement your authentication/rate-limiting logic here | ||
| pass | ||
|
|
||
|
|
||
| @app.post('/logfire-proxy/{path:path}', dependencies=[Depends(verify_user_session)]) | ||
| async def proxy_browser_telemetry_secure(request: Request): | ||
| return await logfire_proxy(request) | ||
| ``` | ||
AlanPonnachan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| [fastapi]: https://fastapi.tiangolo.com/ | ||
| [opentelemetry-asgi]: https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/asgi/asgi.html | ||
| [opentelemetry-fastapi]: https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/fastapi/fastapi.html | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the deleted "forwards requests from your browser instrumentation to Logfire" was good to have for clarity