Skip to content

Dynamic Tags

What happens when a log arrives

When the desktop backend receives SDK logs:

  1. It ensures project and bucket records exist.
  2. It inserts the log row.
  3. It builds a combined tag map:
    • user tags from payload
    • plus system tag log_level
  4. It upserts tag keys/values into tags and log_tag_map.
  5. 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.