我正在尝试研究如何为应用程序日志记录到 Loggly 制作异步日志记录解决方案。查看Loggly 的文档,并将其视为经典的 Producer-Consumer 问题,我想出了这个:
用于 JSON 数据序列化的消息模型:
[DataContract]
public abstract class LogMessage
{
[DataMember]
public DateTime TimeStamp {get;set;}
[DataMember]
public Guid Id {get;set;}
[DataMember]
public int SentAttemptCount {get;set;}
}
[DataContract]
public class ExceptionMessage : LogMessage
{
[DataMember]
public ExceptionMessageDetails ExceptionDetails {get;set;}
}
[DataContract]
public class ExceptionMessageDetails
{
[DataMember]
public string Message {get;set;}
[DataMember]
public string Type {get;set;}
[DataMember]
public string StackTrace {get;set;}
[DataMember]
public ExceptionMessageDetails InnerException {get;set;}
}
记录器类,它将被传递给任何需要记录的东西(比如ExceptionFilter
)。这使用 aBlockingCollection
来排队发送到 Loggly 的消息。
public class LogglyLogger
{
private readonly string logglyUrl = "https://logs-01.loggly.com/inputs/xxxx/";
private readonly HttpClient client;
private readonly BlockingCollection<LogMessage> logQueue;
private readonly int maxAttempts = 4;
public LogglyLogger()
{
logQueue = new BlockingCollection<LogMessage>();
client = new HttpClient();
Task.Run(async () =>
{
foreach(var msg in logQueue.GetConsumingEnumerable())
{
try
{
await SendMessage(msg);
}
catch (Exception)
{
if (msg.SentAttemptCount <= maxAttempts)
{
msg.SentAttemptCount += 1;
logQueue.Add(msg);
}
}
}
});
}
public void SendLogMessage<T>(T msg) where T : LogMessage
{
logQueue.Add(msg);
}
private async Task SendMessage<T>(T msg) where T : LogMessage
{
await client.PostAsJsonAsync(logglyUrl, msg);
}
}
以下是我的问题:
- 这种设置模式有问题
BlockingCollection
吗? - JSON.Net 会找出正确的子类
LogMessage
,还是我需要以不同的方式发送消息? - 吞咽异常绝对是一种代码异味,但我不确定如果记录器无法发送消息会发生什么。有什么想法吗?
在此先感谢,所以。