Skip to content
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

Loki: Common Config #4347

Merged
merged 11 commits into from
Oct 1, 2021
Merged

Loki: Common Config #4347

merged 11 commits into from
Oct 1, 2021

Conversation

slim-bean
Copy link
Collaborator

@slim-bean slim-bean commented Sep 17, 2021

This PR sets out to add a new common section to Loki's config file which is to be used for simplifying Loki's config for most use cases by applying a set of opinionated defaults for as many config options as possible covering a vast majority of Loki use cases.

Checklist

  • Documentation added
  • Tests updated

…outside of this package.

create a pkg/cfg which handles building the Loki config, this is created separately from pkg/util (which is Apache 2 licensed) to maintain proper separations of AGPL and Apache 2 code
Update the main.go for several of the apps with the refactoring
pkg/cfg/cfg.go Outdated

// Apply all our custom logic here to set values in the Loki config from values in the common config
// FIXME this is just an example showing how we can use values from the common section to set values on the Loki config object
r.StorageConfig.BoltDBShipperConfig.SharedStoreType = r.Common.Store
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here we can do anything needed to map common configs to the Loki configs

package common

type Config struct {
Store string // This is just an example, but here we should define all the 'common' config values used to set other Loki values.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here we can define the common config struct

@trevorwhitney
Copy link
Collaborator

I'd like to see a ring config make it into common. Redefining the same ring kv config for each component is tedious, since most deployments typically use 1 kv type for all their rings.

@09jvilla
Copy link
Contributor

09jvilla commented Sep 20, 2021

@slim-bean does this just create a common config, or does it also set some reasonable defaults in that common config? I'm wondering if we need to leave
https://github.com/grafana/backend-enterprise/issues/2173 (Set chunk target size to 1MB by default)
open or if it is covered in this draft PR.

(My rough glance as this PR suggests it only puts the common config in place, but doesn't redefine any of the defaults).

@slim-bean
Copy link
Collaborator Author

@09jvilla this was mostly just a POC to make sure this mechanism would work. We can do whatever we want with whatever defaults we want in here. So we could definitely add some code for setting the chunk_target_size

@replay
Copy link
Contributor

replay commented Sep 20, 2021

I think this mechanism makes sense.
Unfortunately it's really a bit hacky how cfg.YAMLFlag(os.Args[1:], "config.file") has to be called twice, but I can't think of a better way to do this, so let's go with it.

If that's fine with you @slim-bean then i'll push into this PR's branch to add more common configs?

@owen-d
Copy link
Member

owen-d commented Sep 29, 2021

Looks reasonable to me 👍

@trevorwhitney
Copy link
Collaborator

@slim-bean @replay @owen-d I refactored the implementation a bit, added tests, and added an example of how this will work using a common path prefix config. Let me know what you think, thanks!

@trevorwhitney trevorwhitney marked this pull request as ready for review September 29, 2021 16:10
@trevorwhitney trevorwhitney requested a review from a team as a code owner September 29, 2021 16:10
pkg/loki/config_wrapper.go Outdated Show resolved Hide resolved
Copy link
Contributor

@replay replay left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@owen-d owen-d left a comment

Choose a reason for hiding this comment

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

A few nits, then LGTM

pkg/loki/common/common.go Show resolved Hide resolved
pkg/loki/config_wrapper.go Outdated Show resolved Hide resolved
pkg/loki/config_wrapper.go Outdated Show resolved Hide resolved
pkg/loki/config_wrapper_test.go Outdated Show resolved Hide resolved
config := ConfigWrapper{}
fs := flag.NewFlagSet(t.Name(), flag.PanicOnError)

file, err := ioutil.TempFile("", "config.yaml")
Copy link
Member

Choose a reason for hiding this comment

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

It'd be good to remove this file via defer when the test completes.

return config, defaults
}

t.Run("common path prefix config", func(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: These look like good candidates for table tests.

Copy link
Collaborator

@trevorwhitney trevorwhitney Sep 30, 2021

Choose a reason for hiding this comment

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

TBH, I find table tests harder to read and understand. I think they're great for checking relationships between inputs and outputs that resemble a truth table, but for something like this I think it would make it more difficult to understand why a test fails.

For example, if the test testing that command line input takes precedence fails, the output will give me a line number for that assertion. When I go to that assertion, it won't be immediately clear why it failed because we'll just be passing tt.args to the function. In order to determine which input actually caused the failure I would have to copy the name of the failing test from my terminal and then grep for that in the array of inputs to correlate the failure to the correct input data.

Instead, structuring the test like this, all shared logic is still extracted to the testContext function, but now when a test fails I'm taken to a line with the failing input data right there above it (ie. args := []string{"-foo", "bar"}). IMO this makes it a lot easier to quickly understand why a test fails. Sure it may be a few more lines, but I will trade verbosity for readability all day, especially in tests.

Thoughts?

@owen-d owen-d merged commit 11e215d into main Oct 1, 2021
@owen-d owen-d deleted the loki-common-config branch October 1, 2021 18:13
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.

5 participants