Logging in MSAL.NET

The Microsoft Authentication Library (MSAL) apps generate log messages that can help diagnose issues. An app can configure logging with a few lines of code, and have custom control over the level of detail and whether or not personal and organizational data is logged. We recommend you create an MSAL logging implementation and provide a way for users to submit logs when they have authentication issues.

Logging levels

MSAL provides several levels of logging detail:

  • LogAlways: No level filtering is done on this log level. Log messages of all levels will be logged.
  • Critical: Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention.
  • Error: Indicates something has gone wrong and an error was generated. Used for debugging and identifying problems.
  • Warning: There hasn't necessarily been an error or failure, but are intended for diagnostics and pinpointing problems.
  • Informational: MSAL will log events intended for informational purposes not necessarily intended for debugging.
  • Verbose (Default): MSAL logs the full details of library behavior.

Note

Not all log levels are available for all MSAL SDK's

Personal and organizational data

By default, the MSAL logger doesn't capture any highly sensitive personal or organizational data. The library provides the option to enable logging personal and organizational data if you decide to do so.

The following sections provide more details about MSAL error logging for your application.

Configure logging in MSAL.NET

In MSAL, logging is set at application creation using the .WithLogging builder modifier. This method takes optional parameters:

  • IIdentityLogger is the logging implementation used by MSAL.NET to produce logs for debugging or health check purposes. Logs are only sent if logging is enabled.
  • Level enables you to decide which level of logging you want. Setting it to Errors will only get errors
  • PiiLoggingEnabled enables you to log personal and organizational data (PII) if set to true. By default, this parameter is set to false, so that your application doesn't log personal data.
  • LogCallback is set to a delegate that does the logging. If PiiLoggingEnabled is true, this method will receive messages that can have PII, in which case the containsPii flag will be set to true.
  • DefaultLoggingEnabled enables the default logging for the platform. By default it's false. If you set it to true it uses Event Tracing in Desktop/UWP applications, NSLog on iOS and logcat on Android.

IIdentityLogger Interface

namespace Microsoft.IdentityModel.Abstractions
{
    public interface IIdentityLogger
    {
        //
        // Summary:
        //     Checks to see if logging is enabled at given eventLogLevel.
        //
        // Parameters:
        //   eventLogLevel:
        //     Log level of a message.
        bool IsEnabled(EventLogLevel eventLogLevel);

        //
        // Summary:
        //     Writes a log entry.
        //
        // Parameters:
        //   entry:
        //     Defines a structured message to be logged at the provided Microsoft.IdentityModel.Abstractions.LogEntry.EventLogLevel.
        void Log(LogEntry entry);
    }
}

Note

Partner libraries (Microsoft.Identity.Web, Microsoft.IdentityModel) provide implementations of this interface already for various environments (in particular ASP.NET Core)

IIdentityLogger Implementation

The following code snippets are examples of such an implementation. If you use the .NET core configuration, environment variable driven logs levels can be provided for free, in addition to the configuration file based log levels.

Log level from configuration file

It's highly recommended to configure your code to use a configuration file in your environment to set the log level as it will enable your code to change the MSAL logging level without needing to rebuild or restart the application. This is critical for diagnostic purposes, enabling us to quickly gather the required logs from the application that is currently deployed and in production. Verbose logging can be costly so it's best to use the Information level by default and enable verbose logging when an issue is encountered. See JSON configuration provider for an example on how to load data from a configuration file without restarting the application.

Log Level as Environment Variable

Another option we recommended is to configure your code to use an environment variable on the machine to set the log level as it will enable your code to change the MSAL logging level without needing to rebuild the application. This is critical for diagnostic purposes, enabling us to quickly gather the required logs from the application that is currently deployed and in production.

See EventLogLevel for details on the available log levels.

Example:

    class MyIdentityLogger : IIdentityLogger
    {
        public EventLogLevel MinLogLevel { get; }

        public TestIdentityLogger()
        {
            //Try to pull the log level from an environment variable
            var msalEnvLogLevel = Environment.GetEnvironmentVariable("MSAL_LOG_LEVEL");

            if (Enum.TryParse(msalEnvLogLevel, out EventLogLevel msalLogLevel))
            {
                MinLogLevel = msalLogLevel;
            }
            else
            {
                //Recommended default log level
                MinLogLevel = EventLogLevel.Informational;
            }
        }

        public bool IsEnabled(EventLogLevel eventLogLevel)
        {
            return eventLogLevel <= MinLogLevel;
        }

        public void Log(LogEntry entry)
        {
            //Log Message here:
            Console.WriteLine(entry.message);
        }
    }

Using MyIdentityLogger:

    MyIdentityLogger myLogger = new MyIdentityLogger(logLevel);

    var app = ConfidentialClientApplicationBuilder
        .Create(TestConstants.ClientId)
        .WithClientSecret("secret")
        .WithExperimentalFeatures() //Currently an experimental feature, will be removed soon
        .WithLogging(myLogger, piiLogging)
        .Build();

Tip

See the MSAL.NET wiki for samples of MSAL.NET logging and more.

Next steps

For more code samples, refer to Microsoft identity platform code samples.