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

Add Capabilities to /info Route #7977

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

kkeirstead
Copy link
Member

Summary

Adds a list of capabilities to the /info route - these are always present, and have an enabled property for consumers to determine if a feature is present. Note that this does not include information about how a feature is configured (i.e. it may be enabled, but not configured correctly for a given use case). If we'd like to adjust which properties are included just let me know.

Release Notes Entry

Add Capabilities to /info route.

@kkeirstead kkeirstead requested a review from a team as a code owner March 1, 2025 01:06
@kkeirstead
Copy link
Member Author

Note to self - update docs for DotnetMonitorInfo and the /info route example

@kkeirstead kkeirstead added the update-release-notes Pull requests that should be mentioned in the release notes label Mar 1, 2025
@schmittjoseph
Copy link
Member

Let's be sure to also add tests for this


namespace Microsoft.Diagnostics.Monitoring.Options
{
public class MonitorCapability : IMonitorCapability
Copy link
Member

@schmittjoseph schmittjoseph Mar 3, 2025

Choose a reason for hiding this comment

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

I'm not sure if this class adds value here. We already have IMonitorCapability and we can have simple concrete implementations for each capability. Each concrete implementation would then be able to have isolated logic to determine if the feature is on or not (some abstraction may be wanted for in-proc features which would have overlap).

Copy link
Member Author

Choose a reason for hiding this comment

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

@jander-msft can weigh in, but if I'm understanding this correctly that's more aligned with the initial approach I took, and then we transitioned to this model that made everything standardized

Copy link
Member

Choose a reason for hiding this comment

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

Maybe a compromise here would be that the class structure stays the same but the default implementing class doesn't have upfront knowledge about all of its capabilities. This could be done at the registration level.

Copy link
Member

Choose a reason for hiding this comment

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

We can also make the interface public but the class internal

_capability = capability;
}

public abstract void PostConfigure(string? name, T options);
Copy link
Member

Choose a reason for hiding this comment

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

I think this is ok, but just to offer some additional options for consideration:

  • Override seal PostConfigure and have a abstract method similiar to `abstract bool GetIsEnabled(T options). The base class PostConfigure implementation can call GetIsEnabled and PostConfigure(bool) in the implementation.
  • Alternatively, Make CapabilityPostConfigureOptions non-abstract and have it take an additonal parameter of Func<T, bool>. During registration this might look something like RegisterCapability<CallStackOptions>( (CallStackOptions options) => options.Enabled

where TOptions : class
where TPostOptions : class, IPostConfigureOptions<TOptions>
{
services.AddSingleton(new MonitorCapability() { Name = capabilityName });
Copy link
Member

@jander-msft jander-msft Mar 5, 2025

Choose a reason for hiding this comment

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

I'm going to propose an alternative design that (1) allows the capability properties to be read-only, (2) doesn't require relying on the options construction infrastructure, and (3) avoids the possibility of forgetting to register a MonitorCapability and/or a IPostConfigureOptions<T> pairing:

  • Add a IMonitorCapability interface with string Name and bool Enabled getter-only properties.
  • Instead of IPostConfigureOptions<T> implementations, just implement IMonitorCapability for each capability. This implementation can import IOptions<T> and then just set the Enabled property in its constructor.
  • Add each IMonitorCapability implementation as a singleton.
  • Still use MonitorCapability for API model purposes; this can be a projection of the IMonitorCapability implementations.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was a little unsure about the last point on here, but I think the latest changes should more-so be following what you had in mind.

[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
public string Name { get; init; }
Copy link
Member

Choose a reason for hiding this comment

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

I would add the [Required] attribute back to make the OpenAPI description such that the property is not nullable.

[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
public string Name { get; init; }
Copy link
Member

Choose a reason for hiding this comment

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

Can the init be removed from both of the properties since they are set through the constructor? I think STJ should still include them according to https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.ignorereadonlyproperties?view=net-9.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
update-release-notes Pull requests that should be mentioned in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants