Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 547
Simas Paškauskas Avatar asked Nov 28 '25 16:11

Simas Paškauskas


2 Answers

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

    }
);
like image 106
PEK Avatar answered Dec 01 '25 11:12

PEK


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

like image 33
Roubachof Avatar answered Dec 01 '25 09:12

Roubachof



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!