首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网站异步投递到Loggly

网站异步投递到Loggly
EN

Stack Overflow用户
提问于 2014-03-12 00:04:44
回答 1查看 928关注 0票数 1

我正在努力解决如何为应用程序日志到Loggly创建异步日志记录解决方案。看看洛格利氏导管,把它看作是一个典型的生产者-消费者问题,我想出了这个问题:

用于数据的JSON序列化的消息模型:

代码语言:javascript
复制
[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)。这使用BlockingCollection对发送到Loggly的消息进行排队。

代码语言:javascript
复制
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子类,还是需要以不同的方式发送消息?
  • 吞咽异常绝对是一种代码气味,但我不确定如果记录器无法发送消息,应该发生什么。有什么想法吗?

提前谢了,所以。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-04 21:02:24

我最终解决了这个问题,直接控制了发送的内容。

LogMessageEvelope类成熟了一些,添加了一个非序列化的MessageTags属性,将所需的标记传递给Loggly。

代码语言:javascript
复制
/// <summary>
/// Send the log message to loggly
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
private void SendMessage(LogMessageEnvelope message)
{
    // build list of tags
    string tags = string.Join(",", message.MessageTags); 

    // serialize the message
    JsonSerializerSettings settings = new JsonSerializerSettings 
    { 
        NullValueHandling = NullValueHandling.Ignore,
    };
    string content = 
        JsonConvert.SerializeObject(message, Formatting.Indented, settings);

    // build the request
    HttpRequestMessage request = new HttpRequestMessage();
    request.RequestUri = new Uri(logglyUrl);
    request.Method = HttpMethod.Post;
    request.Content = new StringContent(content, Encoding.UTF8);
    request.Headers.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));
    request.Headers.Add("X-LOGGLY-TAG", tags);

    // send the request
    HttpClient client = new HttpClient();
    client.SendAsync(request)
          .ContinueWith(sendTask =>
            {
                // handle the response
                HttpResponseMessage response = sendTask.Result;
                if (!response.IsSuccessStatusCode)
                    // handle a failed log message post
            });
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22339312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档