ChangemakerStudios / serilog-sinks-mongodb

A sink for Serilog that writes events to MongoDB
Apache License 2.0
92 stars 53 forks source link

Memory leak #53

Closed unwaged closed 3 years ago

unwaged commented 4 years ago

Software version : 4.1.0-dev-00069 on dotnet core 3.1 step to produce : 1.create a simple console app (C#) 2.Create a mongodb logger with : _serverobject.EventLogger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.MongoDB("mongodb://127.0.0.1:27017/logs", "SinaConsole", LogEventLevel.Debug) .CreateLogger(); 3.start Performance Profiler and select .NET object allocation

Expected : There should be no memory leak over time. Observed: There is a memory leak over the time. there is no problem with other loggers( .WriteTo.file . etc.)

image

Jaben commented 3 years ago

Do you have any more information on this issue? 37 seconds of diagnostics is not a great sample. Can you show some data running this app for a few hours?

Thanks.

BrammyS commented 3 years ago

Seems like there is still a memory leak. trying to profile it now with dotMemory.

BrammyS commented 3 years ago

Do you have any more information on this issue? 37 seconds of diagnostics is not a great sample. Can you show some data running this app for a few hours?

Thanks.

I'm not running it for an hour since that is a bit overkill to see this leak.

I made a simple console app with .net5 with the MongoDB, file and console sinks. MongoDB was the only one that was experiencing a memory leak.

using System;
using Serilog;

namespace memLeaktest1
{
    public class Program
    {
        private const string HelloWorld = "Hello world";

        public static void Main()
        {
            Console.ReadKey();

            Log.Logger = new LoggerConfiguration().WriteTo.MongoDB("mongodb://127.0.0.1:27017/memTest", "logs").CreateLogger();
            //Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
            //Log.Logger = new LoggerConfiguration().WriteTo.File("test.txt").CreateLogger();

            for (var i = 0; i < int.MaxValue; i++)
            {
                Log.Information(HelloWorld);
            }
        }
    }
}

I'm still very new to profiling so I'll just post some screenshots of what I've found below :)

image image image

BrammyS commented 3 years ago

Seems to be working fine with a bit more realistic test :P I'll run this one a bit longer just in case. But I'm guessing that it wasn't able to empty the queue in the first test.

using System;
using System.Threading.Tasks;
using Serilog;

namespace memLeaktest1
{
    public class Program
    {
        private const string HelloWorld = "Hello world";

        public static async Task Main()
        {
            Console.ReadKey();

            Log.Logger = new LoggerConfiguration().WriteTo.MongoDB("mongodb://127.0.0.1:27017/memTest", "logs").CreateLogger();
            //Log.Logger = new LoggerConfiguration().WriteTo.Async(writeTo => writeTo.MongoDB("mongodb://127.0.0.1:27017/memTest", "logs")).CreateLogger();
            //Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
            //Log.Logger = new LoggerConfiguration().WriteTo.File("test.txt").CreateLogger();

            while (true)
            {
                for (var i = 0; i < 500; i++)
                {
                    Log.Information(HelloWorld);
                }

                await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
            }
        }
    }
}

image image

Jaben commented 3 years ago

Thanks for doing this extensive testing. I'm going to close this as it seems to be working as expected.