Skip to content

Commit 5ca08bd

Browse files
Add UI Telemetry documentation and sidebar entry (#514)
* Add UI Telemetry documentation and sidebar entry * Remove mention of IP addresses from UI Telemetry privacy section
1 parent c70c2fb commit 5ca08bd

2 files changed

Lines changed: 137 additions & 0 deletions

File tree

docs/user/ui-telemetry.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
title: "UI Telemetry"
3+
llm_description: "Explains what anonymous frontend telemetry data Dappnode collects, how it flows through a proxy to Grafana Cloud, and how to enable or disable it."
4+
---
5+
6+
# UI Telemetry
7+
8+
Dappnode collects **optional, anonymous frontend telemetry** from the Dappnode UI to help improve the product. This telemetry is powered by the [Grafana Faro Web SDK](https://github.com/grafana/faro-web-sdk/), an open-source frontend observability library.
9+
10+
:::caution
11+
UI Telemetry is **disabled by default**. No data is sent until you explicitly enable it in the Dappnode settings. You are always in control.
12+
:::
13+
14+
## Why We Collect Telemetry
15+
16+
This telemetry data helps the Dappnode team:
17+
18+
- **Improve product performance** — identify slow pages, rendering bottlenecks, and resource loading issues in real-world conditions
19+
- **Help users in support** — inspect error logs and traces to diagnose issues faster when users report problems
20+
- **Identify and fix UI bugs** — detect unhandled exceptions and crashes that users may not report
21+
- **Prioritize development efforts** — understand which pages and features are most used so we can focus on what matters most
22+
23+
## Architecture Overview
24+
25+
Every Dappnode user who has telemetry enabled sends metrics from their browser to a **proxy server** operated by Dappnode. The proxy applies filtering and security checks before forwarding the data to **Grafana Cloud** for visualization and processing.
26+
27+
```
28+
┌──────────────────┐ ┌──────────────────────────────────┐ ┌───────────────┐
29+
│ Dappnode UI │──────▶│ Proxy │──────▶│ Grafana Cloud │
30+
│ (your browser) │ HTTPS │ grafana-cloud-proxy.dappnode.net│ │ (storage & │
31+
│ │ │ filtering & security layer │ │ dashboards) │
32+
└──────────────────┘ └──────────────────────────────────┘ └───────────────┘
33+
```
34+
35+
:::info
36+
The proxy acts as a security and filtering layer between your browser and Grafana Cloud. Your Dappnode UI never communicates directly with Grafana Cloud — all telemetry goes through the Dappnode-operated proxy first.
37+
:::
38+
39+
## What Data Is Collected
40+
41+
The following sections describe each category of data collected by the Faro SDK with the current Dappnode configuration.
42+
43+
### Errors & Exceptions
44+
45+
Unhandled JavaScript errors and rejected promises are automatically captured. This includes:
46+
47+
- **Error message** and **error type**
48+
- **Stack trace** (file name, line number, column number)
49+
- The browser's `window.onerror` and `onunhandledrejection` events
50+
51+
This helps the team detect crashes and bugs that occur in production, even when users don't report them.
52+
53+
### Console Logs
54+
55+
The SDK captures browser console messages at the `console.error` and `console.warn` levels. These provide context around errors and help diagnose issues.
56+
57+
:::note
58+
Lower-level console methods (`console.log`, `console.debug`, `console.trace`) are **not captured** by default.
59+
:::
60+
61+
### Web Vitals (Performance Metrics)
62+
63+
[Web Vitals](https://web.dev/vitals/) are industry-standard metrics that measure real-user experience. The following are collected:
64+
65+
| Metric | What it measures |
66+
| ----------------------------------- | ------------------------------------------------------------------- |
67+
| **TTFB** (Time to First Byte) | How long until the browser receives the first byte from the server |
68+
| **FCP** (First Contentful Paint) | How long until the first text or image appears on screen |
69+
| **LCP** (Largest Contentful Paint) | How long until the largest visible element finishes rendering |
70+
| **FID** (First Input Delay) | Delay between a user's first interaction and the browser's response |
71+
| **INP** (Interaction to Next Paint) | Responsiveness across all interactions during the session |
72+
| **CLS** (Cumulative Layout Shift) | How much unexpected layout movement occurs on the page |
73+
74+
### Navigation & Resource Performance
75+
76+
The SDK automatically tracks page load and resource fetch performance, including:
77+
78+
- **Page load timing** — total load time, DOM parsing time, DOM processing time, time to first byte
79+
- **Resource timing** — load duration of JavaScript, CSS, images and other assets (DNS lookup, TCP handshake, TLS negotiation, request/response time)
80+
81+
This data helps identify slow-loading pages and bottleneck resources.
82+
83+
### Session Tracking
84+
85+
An **anonymous session ID** is generated and stored in your browser's `localStorage` to group related events together. This allows the team to understand sequences of errors or performance issues within a single session.
86+
87+
- Sessions have a **maximum lifetime of 4 hours**
88+
- Sessions expire after **15 minutes of inactivity**
89+
- Session lifecycle events are tracked: `session_start`, `session_resume`, `session_extend`
90+
- **No user identity** is attached to sessions — they are completely anonymous
91+
92+
### Page & Route Tracking
93+
94+
The URL path of each page you visit within the Dappnode UI is recorded. This uses React Router v6 integration to track single-page application (SPA) view changes.
95+
96+
- Only the **route path** is tracked (e.g., `/stakers/ethereum`)
97+
- This helps understand which sections of the UI are most used and where errors occur
98+
99+
### Distributed Traces
100+
101+
HTTP requests made by the Dappnode UI (via `fetch` and `XMLHttpRequest`) are traced using [OpenTelemetry](https://opentelemetry.io/). For each request, the following timing data is captured:
102+
103+
- Request duration, DNS lookup time, TCP handshake time, TLS negotiation time
104+
- Request and response time, redirect time
105+
- Response status and resource size
106+
107+
:::note
108+
Requests to the telemetry proxy itself are excluded from tracing to avoid recursive data collection.
109+
:::
110+
111+
## What We Do NOT Collect
112+
113+
:::tip
114+
Dappnode takes your privacy seriously. The following data is **never** collected:
115+
116+
- **Personal information** — no names, emails, or account identifiers
117+
- **Form inputs or credentials** — no passwords, seed phrases, or private keys
118+
- **Wallet addresses** — no blockchain addresses of any kind
119+
- **Screenshots or session recordings** — no visual capture of your screen
120+
- **Keystrokes** — no keyboard input is recorded
121+
:::
122+
123+
## How to Enable or Disable Telemetry
124+
125+
You can enable or disable UI Telemetry at any time from the Dappnode settings:
126+
127+
1. Navigate to [http://my.dappnode/system/advanced](http://my.dappnode/system/advanced)
128+
2. Scroll to the **"UI Telemetry"** section
129+
3. Toggle the switch to **enable** or **disable** telemetry
130+
4. The change takes effect immediately — no restart required
131+
132+
When disabled, the Faro SDK is paused and **no data is sent** to the proxy or Grafana Cloud.

sidebars.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,11 @@ const sidebars = {
547547
},
548548
],
549549
},
550+
{
551+
type: "doc",
552+
label: "UI Telemetry",
553+
id: "user/ui-telemetry",
554+
},
550555
{
551556
type: "category",
552557
label: "Dappnode Cloud",

0 commit comments

Comments
 (0)