Writing logs to file using Xamarin.Forms and Serilog

Viewed 5913

Hello I am having trouble writing logs to file on Android device using Xamarin.Forms (.NET Core shared project) and Serilog.

So far I have installed Serilog in Shared project. Installed Serilog, Serilog.Sinks.File, and Serilog.Sinks.Xamarin to my Android project and initialized logger in MainActivity:

Log.Logger = new LoggerConfiguration()
        .WriteTo.File(Path.Combine(Environment.ExternalStorageDirectory.AbsolutePath,"XamarinLib-{Date}.txt"),
                        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] {Message}{NewLine}{Exception}",
                        fileSizeLimitBytes: 100000000,
                        rollingInterval: RollingInterval.Day,
                        rollOnFileSizeLimit: true,
                        shared: false,
                        retainedFileCountLimit: 31,
                        encoding: Encoding.UTF8)
                    .WriteTo.AndroidLog()
                    .CreateLogger();

Afterwards I call the logger from shared project like:

Log.Information("Test writing to log file");

I can see the log command being executed in Visual Studio debug output, but the file is simply not created. I've tried multiple locations on both emulator and actual device (no root access).

I've also tried to use RollingFile sink in similar manner with no success.

Any ideas?

2 Answers

First, you have to allow permissions in your AndroidManifest.xml file.

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Next, The user either must, approve that on runtime in which you have to code this in your code behind. NOTE Remember to add Plugin.Permissions on your NUGET package:

       InitializeComponent();

        Task.Run(async () =>
        {
            try
            {
                var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
                if (status != PermissionStatus.Granted)
                {
                        var accepted = await DisplayAlert("Storage Permission Required",
                            "Please enable your storage permission, it will be used to store logs and crashes",
                            "ACCEPT",
                            "CANCEL");
                        if(accepted)
                        {
                            var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage);
                            status = results[Permission.Storage];
                        }
                }
            }
            catch (Exception ex)
            {
                await DisplayAlert("Exception ex", "Exception ex", "OK");
            }
        });

OR

let them change the permissions in the settings -> app -> permissions.

Finally, change the filename that will link to the storage/emulated/0/[your added directory].

After the closing the app, you can see it in the Android File Manager.

as pointed out by Ruben Bartelink the problem is that Android can't simply write to external storage (ie /storage/emulated/0... etc..). I was able to log to a file on a Xamarin.Forms project in both Android and iOS.

_Tmp = System.IO.Path.GetTempPath();            
_Path = System.IO.Path.Combine(_Tmp, "Serilog.txt");

Log.Logger = new LoggerConfiguration()
  .MinimumLevel.Debug()
  .WriteTo.File(_Path, rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7)
  .CreateLogger();

Log.Information("Started new serilogger {SERILOG} on file {FILE}", this, _Path);

Log.CloseAndFlush();

//test
foreach (string log in System.IO.Directory.GetFiles(_Tmp, "*.txt"))
{
    string test = System.IO.File.ReadAllText(log);
    System.Diagnostics.Debug.WriteLine($"Test[{log}] -> {test}");
}

which printed on the debug console:

    [0:] Test[/data/user/0/com.******/cache/Serilog20190819.txt] -> 2019-08-19 16:00:36.997 +02:00 [INF] Started new serilogger ******.Functions.Serilogger on file /data/user/0/com.******/cache/Serilog.txt
Related