日志收集系统

1:背景

  最近公司说,咱们业务系统那么多,每个系统都在写自己的日志,不方便查看和管理。

  于是,想搞个日志收集系统。

2:构思

  

3:实现

  a):收集服务

    收集服务采用ServiceStack框架,提供web api 的方式访问。

    客户端调用服务,直接把日志信息丢到消息队列中    

 public AopResult<Int32> Get(LogRequest obj)
        {
            if (obj == null) return AopResult.Fail<Int32>("参数不正确!");
            if (string.IsNullOrEmpty(obj.AppNo)) return AopResult.Fail<Int32>("请提供应用编号!");
            if (string.IsNullOrEmpty(obj.Tag)) return AopResult.Fail<Int32>("请提供应用标签!");
            if (string.IsNullOrEmpty(obj.Content)) return AopResult.Fail<Int32>("请提供日志内容!");
            
            LogQueueHelper.EnQueue(ParserImp.Parser(obj));
            return AopResult.Success(0);
        }
View Code

  b):读取日志并创建写入任务

    考虑到日志量过大,需要分表的操作,因此,在日志系统中,创建一个基表。

    基表的数据包括,日志应用,标签,队列名,表名,创建日期,是否启用等信息

    public class QueueKey
    {
        
        /// <summary>
        /// MongoDB 默认主键
        /// </summary>
        public string _id { get; set; }

        /// <summary>
        /// 队列名
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// 应用
        /// </summary>
        public string AppNo { get; set; }

        /// <summary>
        /// 标签
        /// </summary>
        public string Tag { get; set; }

        /// <summary>
        /// 当前集合名称
        /// </summary>
        public string CollectionName { get; set; }

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool Enabled { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }
    }
View Code

    创建一个任务,定时执行从队列中读取日志信息,并根据基表数据(缓存中),创建写入。并把写入任务放入到任务队列中。

    

 public static void FlushLog()
        {
            while (true)
            {
                try
                {
                    if (LogQueueHelper.QueueKeys.Any())
                    {
                        //判断是否需要分库
                        var needRe = DateTime.Now.ToString("dd") == "01";
                        for (var i = 0; i < LogQueueHelper.QueueKeys.Count; i++)
                        {
                            var queueKey = LogQueueHelper.QueueKeys[i];
                            if (needRe) queueKey = DbHelper.RefreshQueueKey(queueKey);
                            var queue = LogQueueHelper.Logs[queueKey.Key];
                            var length = queue.Count;
                            var m = 0;
                            var lst = new List<LogContent>();
                            while (m < length)
                            {
                                m++;
                                lst.Add(queue.Dequeue());
                            }
                            TaskHelper.AddTask(() => DbHelper.Insert(lst, queueKey));
                        }
                    }
                }
                finally
                {
                    Thread.Sleep(Config.QueueConfig.QueueSleep);
                }
            }
        }
View Code

  c):执行日志写入任务

    创建一个任务集合,每隔2S钟,从任务队列中添加一个任务到集合,上限为5个。

    在添加任务到集合之前,判断集合中的任务,如果大于等于5个,则判断准备移除集合中已完成的任务。移除失败,跳出循环,继续下次执行。移除成功,则从队列中,取出下一个任务,启动后,添加到集合中

public static void RunTask()
        {
            while (true)
            {
                Thread.Sleep(2 * 1000);
                if (RunTasks.Count >= 5)
                {
                    var task = RunTasks.FirstOrDefault(p => p.IsCompleted);
                    if (task == null) continue;
                    task.Dispose();
                    RunTasks.Remove(task);
                }
                if (QueueTasks.Count > 0)
                {
                    var task = QueueTasks.Dequeue();
                    task.Start();
                    RunTasks.Add(task);
                }
            }
        }
View Code

4:结束

  这是一个简陋的日志收集系统,欢迎大神拍砖,让我改进。

原文地址:https://www.cnblogs.com/lwein/p/4950629.html