-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[API Proposal]: Add logging APIs to System.ClientModel #111046
Comments
Tagging subscribers to this area: @dotnet/area-extensions-logging |
Please open this issue in the repo https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/core/System.ClientModel. |
@terrajobst, @eerhardt, I assume we want to review this? |
Tagging subscribers to this area: @dotnet/area-meta |
@stephentoub Is this issue occurring in runtime solely for the purpose of the design review, or are we planning to incorporate any code from the Azure SDK into the runtime? For now, I've updated the area label to |
Design review |
Background and motivation
The System.ClientModel library provides building blocks for .NET clients that call cloud services.
Currently, this library does not provide built-in functionality for logging. There are two scenarios when logs should be produced: HTTP request/response logging and information from the System.ClientModel HTTP pipeline (i.e. everything else). This distinction is important for the discussion of these APIs.
Logging HTTP requests and responses from System.ClientModel requires careful consideration in regards to the logging implementations already available in HttpClientFactory and the ASP.NET middleware. After an in-depth investigation and team discussion, we decided the HTTP logging available does not meet the needs for all System.ClientModel logging scenarios. Therefore, we must have HTTP logging built into the library itself.
Additional logs that should be produced by the pipeline (i.e. everything else) are information about retries and information about the transport layer (exceptions and delays). The motivation for these logs is relatively straightforward. Based on interactions with customers in the Azure.Core package, these logs have proven to be helpful to diagnose and solve issues in customer apps and client libraries.
Motivation for adding public APIs
Simple logging to Event Source can be implemented without adding any public APIs. Adding public APIs is meant to achieve the following goals, in order of importance:
API Proposal
API description
ClientLoggingOptions
This class is an options bag that allows a System.ClientModel-based client to configure logging within its pipeline. These options apply to all logging within the pipeline: the Http request/response logging in
MessageLoggingPolicy
and logs written inClientRetryPolicy
andPipelineTransport
.public ILoggerFactory? LoggerFactory {get; set; }
will be used to create instances of ILogger to use to write logs. If an ILoggerFactory is not provided, logs will be written to Event Source instead.public IList<string> AllowedHeaderNames { get; }
will be used to determine which header keys to include values for in logs. All headers not on this list will have their values sanitized.public IList<string> AllowedQueryParameters { get; }
will be used to determine which query parameters to include values for in logs. All query parameters not on this list will have their values sanitized.public bool? EnableLogging { get; set; }
will be used to determine whether logging should be enabled. If this value is set to false, logs will not be written at all. This is true even if an ILoggerFactory is set or the Event Source is enabled. This option takes precedence over all other options.public bool? EnableMessageLogging { get; set; }
will be used to determine whether information about Http request and responses.public bool? EnableMessageContentLogging { get; set; }
will be used to determine whether HTTP request content and HTTP response content should be logged. If a value is not provided, content logging will be disabled.public int? MessageContentSizeLimit { get; set; }
will be used to determine the size limit for content logging.public virtual void Freeze();
andprotected void AssertNotFrozen();
are part of the pipeline options pattern that has already been established.MessageLoggingPolicy
This policy handles HTTP message logging. It logs information about HTTP requests and responses. This policy is added to the pipeline just before the transport if ClientLoggingOptions.EnableLogging and ClientLoggingOptions.EnableMessageLogging are set to true or are not set at all. If either is set to false then this policy is not added to the HTTP pipeline and information about HTTP requests and responses is not logged.
This class is public so in the future we can add virtual methods that allow customization of HTTP message logging beyond the options class.
Additions to ClientPipelineOptions
public ClientLoggingOptions? ClientLoggingOptions { get; set; }
allows configuration of logging within the client pipeline.public PipelinePolicy? MessageLoggingPolicy { get; set; }
follows the pipeline options pattern for default policies added to the pipeline. If this property is set to aPipelinePolicy
, thatPipelinePolicy
instance will be added to the pipeline as the logging policy instead of creating a new one.Additional constructors on ClientRetryPolicy, PipelineTransport, and HttpClientPipelineTransport
These new constructors allow each policy to write logs. Since System.ClientModel provides building blocks for clients, these policies need to be easily extensible by clients implementing them.
API Usage
Default scenario
If a client is using default options, the pipeline will write basic logs to Event Source when "System.ClientModel" Event Source is enabled. Below is an example using an EventListener to collect logs, but logs can be collected using codeless options as well, such as Visual Studio or PerfView.
Using
ClientLoggingOptions
for simple customizationsIf customers pass an
ILoggerFactory
to the client usingClientLoggingOptions
, logs will be written toILogger
instances created from this factory, instead of Event Source.Sample using
ClientLoggingOptions
to disable logging entirely. Logs will never be written to EventSource nor ILogger regardless of any other options set.Sample using
ClientLoggingOptions
to enable and customize content logging. Content logging impacts performance and is disabled by default. It is intended to be used as a debugging tool.Sample using
ClientLoggingOptions
to disable HTTP message logging (information about requests and responses). Information about retries and exceptions from the transport will still be logged.Sample using
ClientLoggingOptions
to customize sanitization.Advanced scenarios
Example using a custom retry policy
This is a simple, illustrative example of how the new constructor can be used to create a custom retry policy. The new constructor allows users to add additional logs to the retry policy, and also preserves the logging behavior in the base class.
Definition:
Usage:
Example using a custom transport
This is a simple, illustrative example of how the new constructor can be used to create a custom transport. The new constructor allows users to add additional logs to the retry policy, and also preserves the logging behavior in the base class.
Definition:
Usage:
Example using HttpClient for HTTP logs instead of System.ClientModel
Alternative Designs
Risks
No response
The text was updated successfully, but these errors were encountered: