2 votes

Est-il nécessaire d'implémenter la journalisation asynchrone pour ASP.NET MVC avec log4net ?

J'ai vu une implémentation de file d'attente de messages comme une classe de journalisation avec log4net.

Il est utilisé pour une application web ASP.NET MVC, donc je pense que les fils sont déjà isolés. Quel est l'avantage de cette mise en œuvre ?

public class Logger
{
    private ILog _logger;
    private static Logger _instance;
    private Queue<Action> _logQueue = new Queue<Action>();
    private ManualResetEvent _newItemsExist = new ManualResetEvent(false);
    private ManualResetEvent _terminate = new ManualResetEvent(false);
    private ManualResetEvent _waiter = new ManualResetEvent(false);
    private static object _syncLock = new object();

    private Thread _logThread;

    public enum LoggingType { Debug, Info, Warn, Error, Fatal };
    public Logger()
    {
        _logger = LogManager.GetLogger(
            System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        _logThread = new Thread(new ThreadStart(ProcessQueue));
        _logThread.IsBackground = true;
        _logThread.Start();
    }

    public static Logger Instance
    {
        get
        {
            if (_instance == null)
                lock (_syncLock)
                    if (_instance == null)
                        _instance = new Logger();

            return _instance;
        }
    }

    private void ProcessQueue()
    {
        while (true)
        {
            _waiter.Set();

            int i = ManualResetEvent.WaitAny(new WaitHandle[] { _newItemsExist, _terminate });
            if (i == 1) return;

            _newItemsExist.Reset();
            _waiter.Reset();

            Queue<Action> queueCopy;
            lock (_logQueue)
            {
                queueCopy = new Queue<Action>(_logQueue);
                _logQueue.Clear();
            }

            foreach (Action logAction in queueCopy)
                logAction();
        }
    }
    public void _LogMessage(string msg_, Exception inEx_, LoggingType type_)
    {
        lock (_logQueue)
            _logQueue.Enqueue(() => AsyncLogMessage(msg_, inEx_, type_));

        _newItemsExist.Set();
    }
    private void AsyncLogMessage(string msg_, Exception inEx_, LoggingType type_)
    {
        switch (type_)
        {
            case LoggingType.Debug:
                _logger.Debug(msg_, inEx_);
                break;

            case LoggingType.Info:
                _logger.Info(msg_, inEx_);
                break;

            case LoggingType.Warn:
                _logger.Warn(msg_, inEx_);
                break;

            case LoggingType.Error:
                _logger.Error(msg_, inEx_);
                break;

            case LoggingType.Fatal:
                _logger.Fatal(msg_, inEx_);
                break;
        }
    }
}

1voto

MaYaN Points 2668

Vous ne devez pas implémenter de logger asynchrone pour log4net Il existe une très bonne mise en œuvre accompagnée d'un article de blog contenant des points de référence et expliquant les détails nécessaires.

En résumé, l'asynchronisme n'est que la moitié du problème, vous devez également fournir une journalisation par lots pour augmenter le débit, sinon le fait de purger chaque message de journalisation l'un après l'autre provoque un goulot d'étranglement sur le thread principal ou autre.

Vous pouvez trouver la bibliothèque sur GitHub , NuGet et l'article de blog ICI .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X