serilog / serilog-sinks-file

Write Serilog events to files in text and JSON formats, optionally rolling on time or size
Apache License 2.0
333 stars 118 forks source link

How can i tell Serilog to log into a IsolatedStorageFile ? #304

Closed flarive closed 2 months ago

flarive commented 9 months ago

Hello,

I'm currently using the Serilog.Sinks.File.

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(Path.Combine(baseLogPath, string.Format("{0}.log", AppConfigurator.LOGFILES_NAME)), shared: true, rollingInterval: RollingInterval.Day, retainedFileTimeLimit: new TimeSpan(31, 0, 0, 0))
.CreateLogger();

Instead of logging into something like %appdata%/myuser/local/... I would like to have Serilog writting log files in .net IsolatedStorageFile.

https://learn.microsoft.com/en-us/dotnet/api/system.io.isolatedstorage.isolatedstoragefile?view=net-8.0

My main problem is that the full path of the isolated storage can't be retreived, this path is not public.

I can use reflection of course to get private full path from my IsolatedStorageFile instance but i want to compile my app in NativeAOT mode and reflection is not working in Native AOT mode.

What could be the solution ? To create a new Serilog.Sinks.IsolatedStorageFile ?

bartelink commented 9 months ago

Any thoughts on an extension point that would make it possible for you do to what you need to do ? (you want to pass in a flag to say "use isolated storage" and have that create the file differently?)

I'd start with a fork to prove the concept. If it works for you, and is not too messy a change to the core impl, then a PR to add an extension point or two so you can use Serilog.Sinks.File ~with a custom input would be viable~ but perhaps override how the File is opened might make sense.

Might be worth logging on stack overflow in case someone has a good practical workaround; surely lots of people have wanted to manage log files in a similar way independent of Serilog?

(See Nick's advice below though - while forking might work in principle, in practice it's probably not that easy as the APIs/capabilities are different)

flarive commented 9 months ago

Sounds good ! Thanks a lot

flarive commented 9 months ago

here is some sample code i already use to read/write from Windows isolated storage : (be carefull that there is quota limit in the isolated storage, and you can't know exactly the physical path, it's hidden for you)

private IsolatedStorageFile _store;

public AppSettingsService()
{
    _store = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
}

public AppSettings LoadAppSettings()
{
    if (_store != null && _store.FileExists(AppConfigurator.SETTINGS_FILENAME))
    {
        using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(AppConfigurator.SETTINGS_FILENAME, FileMode.Open, _store))
        {
            using (StreamReader reader = new StreamReader(isoStream))
            {
                string jsonString = reader.ReadToEnd();
                if (!string.IsNullOrEmpty(jsonString))
                {
                    return JsonSerializer.Deserialize<AppSettings>(jsonString);
                }
            }
        }
    }

    return new AppSettings() { CurrentCulture = AppConfigurator.DEFAULT_CULTURE, CurrentTheme = AppConfigurator.DEFAULT_THEME };
}

public bool SaveAppSettings(AppSettings settings)
{
    if (_store != null)
    {
        if (_store.FileExists(AppConfigurator.SETTINGS_FILENAME))
        {
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(AppConfigurator.SETTINGS_FILENAME, FileMode.Truncate, _store))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    string jsonString = JsonSerializer.Serialize(settings);
                    writer.Write(jsonString);

                    return true;
                }
            }
        }
        else
        {
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(AppConfigurator.SETTINGS_FILENAME, FileMode.CreateNew, _store))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    string jsonString = JsonSerializer.Serialize(settings);
                    writer.Write(jsonString);

                    return true;
                }
            }
        }
    }

    return false;
}
nblumhardt commented 9 months ago

I think this needs a different sink - this package implements logging to regular files, the APIs and semantics involved are too different for it to work well tacked on, here.

Rather than fork right away, I'd start with a very simple implementation of ILogEventSink and map it out from there; you can pull in pieces of this repo as needed, but a lot of the existing code won't be applicable.

Hope this helps, Nick