Dynamic Tags
What happens when a log arrives
When the desktop backend receives SDK logs:
- It ensures project and bucket records exist.
- It inserts the log row.
- It builds a combined tag map:
- user tags from payload
- plus system tag
log_level
- It upserts tag keys/values into
tagsandlog_tag_map. - If new tags are discovered, it emits
gunsole-tags-updated.
This behavior is implemented in apps/desktop/src-tauri/src/lib.rs.
Storage model
Migration apps/desktop/src-tauri/migrations/005_tags.sql adds:
tags(project_id,key,value, unique per combo)log_tag_map(many-to-many map between logs and tag entries)- backfill for historical JSON tags and
log_level
UI behavior
The desktop UI has dynamic tag filter groups that:
- prioritize tag filters currently selected by user
- show up to 4 visible filters in the main bar
- place overflow filters in a side drawer (
+N)
This lives in apps/desktop/src/components/log-viewer/dynamic-tag-filters.tsx.
System tags
log_level is treated as a system tag key (SYSTEM_TAG_KEYS) and can be handled with specialized UX.
SDK usage pattern for clean dynamic filters
gunsole.info({ bucket: 'auth', message: 'Login success', tags: { flow: 'login', provider: 'google', region: 'us-east-1' }});Tag keys should be stable and low-cardinality. Put unique/high-cardinality values in context instead.