-
Notifications
You must be signed in to change notification settings - Fork 544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support global and wildcard overrides in Generic Forwarding #1871
Support global and wildcard overrides in Generic Forwarding #1871
Conversation
m.tenantToQueueListMu.Lock() | ||
defer m.tenantToQueueListMu.Unlock() | ||
|
||
forwarderNames := m.overrides.Forwarders(tenantID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like for tenants w/o a configured forwarder this lock will hit repeatedly b/c it will not be found in the list. should we store a nil
value in m.tenantToQueueList
to prevent this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this is the core of the change? By repeatedly asking for the forwarder we can catch the wildcard scenarios? I'm fine with that idea, but I'd like to find a way to "cache" the nil to prevent constant lookups here.
Other than that looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the case. Please notice that I am assigning a new queueList to the tenantToQueueList
map in manager.go:98
. Suppose no forwarders are defined at all in the distributor config, OR there are no forwarders defined in the overrides config (either globally, wildcard, or per-tenant). In that case, we don't even enter this code. Below is the part of the code from distributor.go:382
that handles this case:
if len(d.cfg.Forwarders) > 0 && len(d.overrides.Forwarders(userID)) > 0 {
if err := d.forwardersManager.ForTenant(userID).ForwardTraces(ctx, traces); err != nil {
_ = level.Warn(d.logger).Log("msg", "failed to forward batches for tenant=%s: %w", userID, err)
}
}
If we wanna be super safe, we could remove the if
check from manager.go:87
. This way, "empty" queueLists will get assigned to the map, covering this case. I added this check to optimize for memory here. However, with the extra check in the caller function (in distributor.go
) this should not matter and space complexity remains the same for the whole functionality (it will be only worse "locally" in the context of the Manager
struct itself).
Let me know your thoughts on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now. I'll admit I don't like the logic to get the queue is split between this function and distributor.go:382
. It's difficult to see all the logic related to how we request a forwarder for a tenant. Likely it was put there because it mirrors the metric generator lines above it?
Personally, I think it would be cleaner to move this logic:
if len(d.cfg.Forwarders) > 0 && len(d.overrides.Forwarders(userID)) > 0 {
into the manager b/c there would be one place to look to see exactly how a forwarder is requested for a tenant. This is not a blocker though. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved in ce63eeb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm @mapno did you want to take a look?
clean up the changelog conflict and we'll merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@mapno I've rebased on top of origin/main and fixed CHANGELOG.md conflicts. |
What this PR does:
This PR adds support for global and wildcard overrides. Before, generic forwarding could only be enabled on a per-tenant basis. To make implementation behave in a similar manner to the rest of the code, I have added support for both wildcard and global overrides. From now on, users are not required to explicitly define forwarders on a per-tenant basis, but can also do so using a wildcard character in per-tenant overrides config ("*") or even define forwarders globally in the
overrides
section oftempo.yaml
.Example:
Let's imagine we have overrides defined in three ways: globally, using wildcard and on a per-tenant basis.
Given above configuration:
tenant-0
will forward to forwarder namedmy-forwarder-2
my-forwarder-3
If we were to remove the wildcard config from the
overrides.yaml
:tenant-0
will still forward to forwarder namedmy-forwarder-2
my-forwarder-1
Which issue(s) this PR fixes:
This PR is a continuation of #1775.
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]