guibranco / guibranco/logstream-ui
[FEATURE] Sampling configuration screen
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 15m
- Merged PRs (30d)
- 49
Description
## Summary
Add a **Sampling** screen where operators can view, create, edit, and delete log sampling rules, which control what percentage of high-volume low-priority entries are accepted before reaching storage.
> **Depends on:** [`[FEATURE] Log sampling — configurable entry drop rate`](https://github.com/guibranco/logstream-server/issues) in `guibranco/logstream-server`
## Motivation
Sampling rules are currently configured by editing a JSON file on the server. A UI makes them manageable for operators who need to tune storage costs during peak traffic without a deployment.
## Proposed layout
```
┌─────────────────────────────────────────────────────────────────┐
│ Sampling [+ New rule] │
│ Reduce storage volume by dropping a percentage of low- │
│ priority entries. error and critical are never sampled. │
├──────────────────────────┬───────────────────────┬─────────────┤
│ Name │ Filters │ Rate │
│ sample-billing-debug │ billing-api / debug │ 10% │
│ sample-all-info │ (all) / info │ 50% │
└──────────────────────────┴───────────────────────┴─────────────┘
```
### Sampling rule form (slide-in drawer)
| Field | Component | Notes |
|-------|-----------|-------|
| Name | `` text | Required, slug |
| App key | `` text | Optional |
| Level | `` | debug / info / notice / warning (error/critical excluded) |
| Sample rate | `` + slider | 1–99%, integer steps |
### Rate display
The rate field shows both the acceptance percentage and a plain-English explanation:
```
Rate: [████████░░] 10%
Accepts 1 in every 10 matching entries.
Drops approximately 13,500 entries/hour at current volume.
```
The "at current volume" figure is derived from the stats endpoint for the matching level/app_key.
## Files to create
- `src/hooks/useSampling.ts` — CRUD hooks for `/api/sampling` collection
- `src/screens/SamplingScreen.tsx` — main screen
- `src/components/sampling/SamplingTable.tsx` — list with name, filter summary, rate
- `src/components/sampling/SamplingForm.tsx` — slide-in drawer
- `src/components/sampling/RateSlider.tsx` — percentage input with slider
## UX details
- `error` and `critical` are excluded from the level selector with a tooltip: *"Error and critical entries are never sampled"*
- Sampling tab only visible when `GET /api/info` returns `features.sampling: true`
- Warning banner at top of screen: *"Sampling permanently discards entries. Ensure this is intentional."*
## Acceptance criteria
- [ ] Sampling tab visible when feature is enabled
- [ ] List all sampling rules with filter summary and rate
- [ ] Create rule via form drawer
- [ ] Edit rule via form drawer (pre-filled)
- [ ] Delete rule with inline confirmation
- [ ] error / critical excluded from level selector with tooltip
- [ ] Rate slider + numeric input in sync
- [ ] Warning banner shown on screen
- [ ] API errors shown inline
Contributor guide
Research direction
Start by reading the existing screen, hook, component, and feature-flag patterns before creating src/hooks/useSampling.ts, src/screens/SamplingScreen.tsx, and the three files under src/components/sampling/. Run the existing frontend checks and verify the screen against every acceptance criterion, including CRUD actions, validation, rate synchronization, warnings, feature visibility, and inline API errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript, vite
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100