Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions distributed-frontend-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
images
1 change: 1 addition & 0 deletions distributed-frontend-example/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.17.0
3 changes: 3 additions & 0 deletions distributed-frontend-example/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"makefile.configureOnOpen": false
}
12 changes: 12 additions & 0 deletions distributed-frontend-example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: install
install:
cd frontend && npm install
uv sync

.PHONY: frontend-dev
frontend-dev:
cd frontend && npm run dev

.PHONY: backend-dev
backend-dev:
uv run main.py
53 changes: 53 additions & 0 deletions distributed-frontend-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Distributed tracing demo

This project demonstrates distributed Logfire tracing from the browser (React
app) to the backend (FastAPI Python app using PydanticAI).

# Key concepts

The React application (`frontend/`) is instrumented using the
`@pydantic/logfire-browser` NPM package. Details about the instrumentation
specifics can be found in the `ClientInstrumentationProvider.tsx` file.

The browser instrumentation does not send traces to Logfire directly, but
instead sends them to the backend. The backend then proxies the traces to
Logfire - the `/client-traces` FastAPI endpoint in `main.py`.

# Running the demo

To run the demo, you need to have Python 3.10+ and Node.js 22+ installed. First,
install the dependencies:

```bash
make install
```

Then, export the following environment variables:

```bash
export LOGFIRE_TOKEN=<your-logfire-token>
export LOGFIRE_BASE_URL=https://logfire-us.pydantic.dev/ # e.g. https://logfire-eu.pydantic.dev/ or https://logfire-us.pydantic.dev/
export OPENAI_API_KEY=<your-openai-api-key> # you can get one from https://platform.openai.com/account/api-keys
```

Run the backend:

```bash
make backend-dev
```

Then, in another shell, run the frontend:

```bash
make frontend-dev
```

The App will be available at (http://localhost:5173)[http://localhost:5173]. You
can open your Logfire live view and interact with the App to see the traces in
real-time.

# Further reading

- [Distributed tracing with Logfire](https://logfire.pydantic.dev/docs/how-to-guides/distributed-tracing/)
- [Logfire Python SDK](https://github.com/pydantic/logfire)
- [Logfire JS](https://github.com/pydantic/logfire-js)
1 change: 1 addition & 0 deletions distributed-frontend-example/frontend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_FAST_API_BACKEND_BASE_URL=http://127.0.0.1:8000
24 changes: 24 additions & 0 deletions distributed-frontend-example/frontend/.gitignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could remove this and just put it all in the root .gitignore

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
23 changes: 23 additions & 0 deletions distributed-frontend-example/frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { globalIgnores } from 'eslint/config'

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
13 changes: 13 additions & 0 deletions distributed-frontend-example/frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pydantic Stack Image Generator</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading