-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Logging in Azure SDK
The content for this wiki page has been relocated to https://docs.microsoft.com/azure/developer/java/sdk/logging-overview, except for the section below which has not yet moved.
Regardless of the logging mechanism used, if a client builder offers the ability to set HttpLogOptions, these options must additionally be configured to output any logs. An HttpLogDetailLevel must be specifed to indicate what information should be logged. This value defaults to NONE
, so if it is not specified, no logs will be output even if the logging framework or fallback logging is properly configured. For security reasons, headers and query parameters are redacted by default, so the log options must also be provided with a Set<String>
indicating which headers and query parameters are safe to print. These value may be configured as shown below. The logging is set to print both body content and header values, all header values will be redacted except the value for the user specified metadata corresponding to the key "foo"
, and all query parameters will be redacted except for the sas token query parameter "sv"
indicating the signed version of any sas which may be present.
new BlobClientBuilder().endpoint(<endpoint>)
.httpLogOptions(new HttpLogOptions()
.setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)
.setAllowedHeaderNames(Set.of("x-ms-meta-foo"))
.setAllowedQueryParamNames(Set.of("sv")))
.buildClient();
NOTE: This example uses a Storage client builder, but the principle applies for any builder which accepts HttpLogOptions
. Furthermore, this example does not demonstrate complete configuration of a client and is only intended to illustrate configuration of logging. For more information on configuring clients, see the documentation on the respective builders.
This section is under construction.
-
DO use
ClientLogger
. It wraps SLF4JLogger
providing Azure SDK-specific configuration and supporting structured logging. Check out usage examples here -
DO use structured logging via
logger.at<Level>().addKeyValue("key", "value")
to stamp context logs could be filtered, aggregated, sliced and diced with.
- Make sure keys are consistent
- If value calculation is expensive, use lambda instead (
addKeyValue("key", () -> calculateExpensiveValue())
) - Provide global context on
ClientLogger
constructor - it will be stamped on all log records produced with this logger instance and with the best possible performance
-
DO log exceptions
- Use
logger.at<Level>().log(ex)
orlogger.logWarningAs<Level>(ex)
when exception is created, don't log them again - Put additional context into the log record, adding context to exception message can also be benefitial
- Pass exception instance to log method (don't pass exception message): when
verbose
level is enabled,ClientLogger
will write the whole exception stack trace, otherwise it will only populate exception message
- Use
-
DO write troubleshooting guides based on logs SDK produces, write code thinking of how it can be troubleshoot based on logs.
- Document context keys in TSGs
- Provide examples on how to slice and dice logs to identify root cause of issue
-
DON'T duplicate logging, tracing, and metrics
- those are three different signals and we'd want users to have them all.
- TBD
-
DON'T rely on logs to solve complex issues
- Users can't repro issues in production as it leads to downtime and business impact - they revert SDK updates, find workarounds, etc
- Users can't enable verbose logs in production - it kills performance (and the application) and leads to unexpected bills
- TODO
- Frequently Asked Questions
- Azure Identity Examples
- Configuration
- Performance Tuning
- Android Support
- Unit Testing
- Test Proxy Migration
- Azure Json Migration
- New Checkstyle and Spotbugs pattern migration
- Protocol Methods
- TypeSpec-Java Quickstart
- Getting Started Guidance
- Adding a Module
- Building
- Writing Performance Tests
- Working with AutoRest
- Deprecation
- BOM guidelines
- Release process
- Access helpers