Loggly へのアプリケーション ロギング用の非同期ロギング ソリューションを作成する方法を考えています。Loggly's ducumentationを見て、これを古典的な生産者と消費者の問題と考えて、私はこれを思いつきました:
データの 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;}
}
ログに記録する必要があるものすべてに渡される Logger クラス ( などExceptionFilter
)。これは、BlockingCollection
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
か、それとも別の方法でメッセージを送信する必要がありますか? - 例外を飲み込むのは間違いなくコードの匂いですが、ロガーがメッセージの送信に失敗した場合に何が起こるかわかりません。何かご意見は?
よろしくお願いします。