Simas Paškauskas
Simas Paškauskas

Reputation: 623

Logging on .net MAUI

.net MAUI recently removed logging in one of it's newest release. What is the alternative now and how should it be implemented? Have been going all over online, but couldn't find a single example of any logging architecture implemented. Tried log4net, NLog, but did not manage to set any of them up at the end. There is 0 examples online for setting it up any logging on MAUI.

Also, saw the builder.Services.AddLogging() and builder.Logging.Services in MauiProgram which should work with dependency injection, but can't find any Maui example for that implementation too.

How one should set up a basic logging in MAUI now?

Upvotes: 20

Views: 17706

Answers (4)

PEK
PEK

Reputation: 4328

Start by adding a reference to Microsoft.Extensions.Logging.Debug. You could do it like this if you only want it in debug mode:

<ItemGroup Condition="'$(Configuration)' == 'Debug'">
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
</ItemGroup>

Then when the application starts:

var builder = MauiApp.CreateBuilder();
// ...
#if DEBUG
builder.Services.AddLogging(
    configure =>
    {
        configure.AddDebug();
    }
);
#endif

You could also add filters:

#if DEBUG
builder.Services.AddLogging(
    configure =>
    {
        configure
            .AddDebug()
            .AddFilter("MyCompany.MyApp.Namespace", LogLevel.Trace)
            .AddFilter("Microsoft", LogLevel.Warning);
    }
);
#endif

Android logging (Logcat)

If you want to use the native logging support on Android, an easy fix for this is to add a reference to Microsoft.Extensions.Logging.Console and then configure it:

builder.Services.AddLogging(
    configure =>
    {
        configure.AddDebug();
        configure.AddConsole();
    }
);

While this works, the logs are a bit hard to read. A better way is to use a custom logging provider that wraps the native logging support. In the Android folder, add this code:

    using Microsoft.Extensions.Logging;

    namespace MyMauiApp;

    public class AndroidLoggerProvider : ILoggerProvider
    {
        public AndroidLoggerProvider()
        {
        }

        public ILogger CreateLogger(string categoryName)
        {
            // Category name is often the full class name, like
            // MyApp.ViewModel.MyViewModel
            // This removes the namespace:
            int lastDotPos = categoryName.LastIndexOf('.');
            if (lastDotPos > 0)
            {
                categoryName = categoryName.Substring(lastDotPos + 1);
            }
        
            return new AndroidLogger(categoryName);
        }

        public void Dispose() { }
    }

    public class AndroidLogger : ILogger
    {
        private readonly string Category;

        public IDisposable BeginScope<TState>(TState state) => null!;

        public bool IsEnabled(LogLevel logLevel) => true;

        public AndroidLogger(string category)
        {
            Category = category;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
        {
            string message = formatter(state, exception);

            Java.Lang.Throwable? throwable = null;

            if (exception is not null)
            {
                throwable = Java.Lang.Throwable.FromException(exception);
            }

            switch (logLevel)
            {
                case LogLevel.Trace:
                    Android.Util.Log.Verbose(Category, throwable, message);
                    break;

                case LogLevel.Debug:
                    Android.Util.Log.Debug(Category, throwable, message);
                    break;

                case LogLevel.Information:
                    Android.Util.Log.Info(Category, throwable, message);
                    break;

                case LogLevel.Warning:
                    Android.Util.Log.Warn(Category, throwable, message);
                    break;

                case LogLevel.Error:
                    Android.Util.Log.Error(Category, throwable, message);
                    break;

                case LogLevel.Critical:
                    Android.Util.Log.Wtf(Category, throwable, message);
                    break;
            }
        }
    }

And then you configure it like this:

builder.Services.AddLogging(
    configure =>
    {
        // You don't need the debug logger on Android if you use AndroidLoggerProvider.
        // configure.AddDebug();

#if ANDROID
#if DEBUG
        LogLevel androidLogLevel = LogLevel.Debug;
#else
        LogLevel androidLogLevel = LogLevel.Information;
#endif

        configure
            .AddProvider(new AndroidLoggerProvider())
            .AddFilter("MyMauiApp", androidLogLevel);
#endif

    }
);

Upvotes: 22

Murat Gungor
Murat Gungor

Reputation: 125

I used MetroLog.Maui here is a video I recorded https://youtu.be/8CPXDHQlBa0

In a Utility class

private static ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddStreamingFileLogger(options =>
    {
        options.RetainDays = 2;               
        options.FolderPath = Path.Combine(FileSystem.CacheDirectory, "InfoBoardLogs");
    }));

    public static ILogger Logger(string categoryName) {
        return loggerFactory.CreateLogger(categoryName);
    }
//Usege
using Microsoft.Extensions.Logging;
private readonly ILogger _logger;

_logger = Utilities.Logger(nameof(ImageDisplay));
_logger.LogInformation("\n++++++++++++++ ImageDisplay Constructor");

Upvotes: -1

Roubachof
Roubachof

Reputation: 3401

There is a package taylor made for logging in MAUI: https://github.com/roubachof/MetroLog

Including:

  • Share logs as a zip file
  • Displaying logs in a page
  • Shake the device to display logs

And you can find a tutorial by Gerald here: https://www.youtube.com/watch?v=WicmnH72kf0

Upvotes: 3

Rolf Kristensen
Rolf Kristensen

Reputation: 19867

NLog.Targets.MauiLog enables debug logging on the various platforms:

  • Apple iOS / MacOS - Unified Logging
  • Android - Android.Util.Log / LogCat
  • NetStandard - System.Diagnostics.Debugger.Log

Upvotes: 0

Related Questions