Skip to content

feat(querier): add wildcard tenant query support#20690

Open
amogh-orolabs-dev wants to merge 1 commit intografana:mainfrom
amogh-orolabs-dev:feature/wildcard-tenant-queries
Open

feat(querier): add wildcard tenant query support#20690
amogh-orolabs-dev wants to merge 1 commit intografana:mainfrom
amogh-orolabs-dev:feature/wildcard-tenant-queries

Conversation

@amogh-orolabs-dev
Copy link

Summary

This PR adds experimental support for wildcard tenant queries in Loki, allowing administrators to query all tenants using * in the X-Scope-OrgID header instead of explicitly listing each tenant ID.

Closes #7356

Motivation

In multi-tenant Loki deployments with many tenants, administrators currently need to manually maintain lists of tenant IDs in their datasource configurations or query headers. This is error-prone and requires constant updates as tenants are added or removed.

This feature addresses the community request for a way to query "all tenants" or "all tenants except specific ones" without explicit enumeration.

Changes

New Files

  • pkg/querier/tenant_discovery.go - Core tenant discovery interface and storage-based implementation
  • pkg/querier/wildcard_tenant_querier.go - Querier wrapper that handles wildcard resolution
  • pkg/querier/tenant_discovery_test.go - Unit tests for tenant discovery
  • pkg/querier/wildcard_tenant_querier_test.go - Unit tests for wildcard querier
  • integration/wildcard_tenant_queries_test.go - Integration tests
  • docs/sources/configure/wildcard-tenant-queries.md - User documentation

Modified Files

  • pkg/querier/querier.go - Added configuration options:
    • wildcard_tenant_queries_enabled (bool, default: false)
    • wildcard_tenant_cache_ttl (duration, default: 5m)
  • pkg/loki/modules.go - Wired wildcard querier into initialization

Design

Tenant Discovery

The feature uses a TenantDiscovery interface:

type TenantDiscovery interface {
    GetAllTenants(ctx context.Context) ([]string, error)
    IsWildcard(orgID string) bool
}

The StorageTenantDiscovery implementation discovers tenants by listing them from the index storage (S3/GCS/etc). Results are cached with a configurable TTL to avoid expensive storage operations on every query.

Query Flow

  1. Request arrives with X-Scope-OrgID: * (or *|!excluded)
  2. WildcardTenantQuerier.resolveWildcardTenants() detects the wildcard
  3. StorageTenantDiscovery.GetAllTenants() retrieves all tenant IDs from storage (or cache)
  4. Exclusions are applied if any !tenant patterns are present
  5. Context is updated with resolved tenant IDs
  6. Query proceeds through normal MultiTenantQuerier code path
  7. Results include __tenant_id__ label on each log entry

Supported Syntax

Syntax Description
* Query all tenants
*|!tenant1 All tenants except tenant1
*|!t1|!t2|!t3 All tenants except t1, t2, t3

Configuration

querier:
  multi_tenant_queries_enabled: true
  wildcard_tenant_queries_enabled: true
  wildcard_tenant_cache_ttl: 5m

Testing

  • Unit tests for tenant discovery caching, concurrent access, edge cases
  • Unit tests for wildcard resolution, exclusion handling, error cases
  • Integration tests for end-to-end validation

Breaking Changes

None - this is an opt-in experimental feature.

Checklist

  • Tests added
  • Documentation updated
  • No breaking changes
  • Implementation fully wired into Loki startup

Add experimental support for wildcard tenant queries using "*" in the
X-Scope-OrgID header. This allows administrators to query all tenants
without explicitly listing each tenant ID.

Features:
- Support for "*" to query all tenants
- Exclusion syntax: "*|!tenant1|!tenant2" to exclude specific tenants
- Tenant discovery from index storage with configurable cache TTL
- New config options:
  - querier.wildcard-tenant-queries-enabled (default: false)
  - querier.wildcard-tenant-cache-ttl (default: 5m)

Closes grafana#7356
@amogh-orolabs-dev amogh-orolabs-dev requested a review from a team as a code owner February 5, 2026 12:13
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 67afe0b524

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +74 to +78
if q.discovery.IsWildcard(id) {
hasWildcard = true
} else if strings.HasPrefix(id, "!") {
// Tenant exclusion syntax: !tenant_id
excludeTenants[strings.TrimPrefix(id, "!")] = struct{}{}

Choose a reason for hiding this comment

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

P2 Badge Avoid treating valid tenant IDs starting with ! as exclusions

With wildcard queries enabled, any tenant ID that starts with ! is now parsed as an exclusion and triggers ErrExcludeWithoutWildcard unless * is present. Loki’s tenant validation allows ! in tenant IDs, so a tenant named like !prod would become unqueryable once this feature is turned on. That’s a regression for valid tenant IDs and means enabling wildcard queries can break existing tenants that start with !.

Useful? React with 👍 / 👎.

Comment on lines +577 to +581
// Use the active period config to determine the object store and index prefix
periodConfigs := t.Cfg.SchemaConfig.Configs
if len(periodConfigs) > 0 {
activePeriodIdx := config.ActivePeriodConfig(periodConfigs)
activePeriod := periodConfigs[activePeriodIdx]

Choose a reason for hiding this comment

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

P2 Badge Discover tenants from all schema configs, not just active

Tenant discovery is tied to only the active schema period’s object store and prefix. In deployments with multiple schema configs (e.g., a migration that changed index store or prefix), tenants that only have data in non-active periods won’t be discovered, so * queries will omit them even when the query time range includes their historical data. That violates the “all tenants” expectation for wildcard queries in multi-schema setups.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wildcard for X-Scope-OrgID when querying

2 participants