Skip to content

Conversation

@vaibhavyadav-dev
Copy link
Contributor

What changed?

Added an admin command that dump all frontend dynamic config values,

Why?

Operators currently cannot easily inspect frontend runtime dynamic configuration, dumping values aids troubleshooting, incident response, and verification after config changes.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

Closes #421

@vaibhavyadav-dev vaibhavyadav-dev requested review from a team as code owners November 21, 2025 10:05
@vaibhavyadav-dev vaibhavyadav-dev changed the title feat: add command to dump dynamic config values (#421) Add command to dump dynamic config values (#421) Nov 21, 2025
@vaibhavyadav-dev
Copy link
Contributor Author

vaibhavyadav-dev commented Nov 21, 2025

@bergundy I think It's better to add DefaultKey in this handler .

Do let me know what you think,
Thanks

Copy link
Contributor

@dnr dnr left a comment

Choose a reason for hiding this comment

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

please regenerate with the correct versions of protoc/protoc-gen-go to avoid the unrelated generated file changes

}
}

func (c *Collection) GetClient() Client {
Copy link
Contributor

Choose a reason for hiding this comment

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

is this used anywhere? I'd prefer not exposing the underlying Client if we don't really need to

return err
}
func (s {{$P.Name}}TypedConstrainedDefaultSetting[T]) DefaultValue() any {
return s.cdef
Copy link
Contributor

Choose a reason for hiding this comment

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

this feels weird, s.cdef is a []TypedConstrainedValue[T], which is a type that's going to be pretty hard/awkward for any client code to use. I suppose you're only using it serialize to json or something, so it doesn't really matter what the type is?

hasDefaultConstraint = true
}
}
// add default value if not present
Copy link
Contributor

Choose a reason for hiding this comment

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

this feels kind of weird. why do we need to insert the default values here? first of all, it doesn't work for settings with multiple constrained defaults. second, it's using more memory for something we don't actually need for looking up settings. why can't the code to retrieve settings just have logic to get the default from the registry instead of doing it here? it needs that anyway to get the default for a setting that's not preset in the file at all, right?

globalRegistry registry
)

func GetDefaultValueForKey(k Key) ConstrainedValue {
Copy link
Contributor

Choose a reason for hiding this comment

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

as above, this just doesn't make any sense for settings with constrained default values, there is no single default.

- value: true
history.hostLevelCacheMaxSize:
- value: 8192
- value: 8000
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad, I did this to test my changes and forgot revert it.


message ConstrainedValue {
Constraints constraints = 1;
google.protobuf.Struct value = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, shouldn't it be a google.protobuf.Value instead? most configs are scalars, there are structs and lists but they're not the majority.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure it should be Value, should we just dump the struct as JSON? It could be simpler. But Value would be better than Struct, agree.

"go.temporal.io/server/api/adminservice/v1"
clusterspb "go.temporal.io/server/api/cluster/v1"
commonspb "go.temporal.io/server/api/common/v1"
dc "go.temporal.io/server/api/dynamicconfig/v1"
Copy link
Contributor

Choose a reason for hiding this comment

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

import should be named dynamicconfigspb ("spb" for "server proto buf")

}

protoValues := make([]*dc.ConstrainedValue, 0)
for _, ConstrainedValue := range dcEntry {
Copy link
Contributor

Choose a reason for hiding this comment

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

use lowercase for variable names

Suggested change
for _, ConstrainedValue := range dcEntry {
for _, cv := range dcEntry {

dcEntry = append(dcEntry, defaultValue)
}

protoValues := make([]*dc.ConstrainedValue, 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
protoValues := make([]*dc.ConstrainedValue, 0)
protoValues := make([]*dc.ConstrainedValue, 0, len(dcEntry))

or assign to specific indexes. or use util.MapSlice.

}

message GetDynamicConfigurationsResponse {
repeated HostConfig host_config = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

why repeated? do we allow querying multiple hosts at once?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not now, but do have plan to make so.

Copy link
Member

Choose a reason for hiding this comment

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

This was my idea, so you can compare dynamic configs across hosts. This will be a future capability though.

@vaibhavyadav-dev
Copy link
Contributor Author

Thanks for the review @dnr
I have a question about the approach since It doesn't work for settings with multiple constrained defaults, and inserting defaults at load time is bad.

I'm considering two alternatives.

  • Only display values that are explicitly configured in the dynamic config file. If a setting isn't present, don't show it.
  • Retrieve defaults at display time from the registry based on the actual constraints being queried.

Which approach would you prefer? I'm leaning toward first one as it's simpler and provides value for operators troubleshooting config issues.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add admin command to dump dynamic config value[s]

3 participants