CredentialProvider.Microsoft/Logging/LoggerBase.cs (67 lines of code) (raw):
// Copyright (c) Microsoft. All rights reserved.
//
// Licensed under the MIT license.
using System;
using System.Collections.Concurrent;
using System.Threading;
using NuGet.Common;
namespace NuGetCredentialProvider.Logging
{
public abstract class LoggerBase : ILogger
{
private LogLevel minLogLevel = LogLevel.Debug;
private bool allowLogWrites = false;
private ConcurrentQueue<Tuple<LogLevel, string, DateTime>> bufferedLogs = new ConcurrentQueue<Tuple<LogLevel, string, DateTime>>();
private readonly bool writesToConsole;
protected LoggerBase(bool writesToConsole)
{
this.writesToConsole = writesToConsole;
}
public void Log(LogLevel level, bool allowOnConsole, string message)
{
if (writesToConsole && !allowOnConsole)
{
return;
}
if (!allowLogWrites)
{
// cheap reserve, if it swaps out after we add, meh, we miss one log
var buffer = bufferedLogs;
if (buffer != null)
{
buffer.Enqueue(Tuple.Create(level, message, DateTime.Now));
}
// we could pass this through if buffer is null since the Set message has already come through to unblock us, but
// the race should be rare and we don't know exactly how nuget will behave with the parallelism so
// opt to ignore this one racing log message.
return;
}
else if (bufferedLogs != null)
{
ConcurrentQueue<Tuple<LogLevel, string, DateTime>> buffer = null;
buffer = Interlocked.CompareExchange(ref bufferedLogs, null, bufferedLogs);
if (buffer != null)
{
foreach (var log in buffer)
{
if (log.Item1 >= minLogLevel)
{
WriteLog(log.Item1, GetLogPrefix(log.Item3) + log.Item2);
}
}
}
}
if (level >= minLogLevel)
{
WriteLog(level, GetLogPrefix(null) + message);
}
}
public void SetLogLevel(LogLevel newLogLevel)
{
minLogLevel = newLogLevel;
allowLogWrites = true;
}
protected abstract void WriteLog(LogLevel logLevel, string message);
private string GetLogPrefix(DateTime? bufferedLogTime)
{
string timeString = bufferedLogTime.HasValue
? bufferedLogTime.Value.ToString(".HHmmss")
: null;
return $"[CredentialProvider{timeString}]";
}
}
}