日志收集系統


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:結束

  這是一個簡陋的日志收集系統,歡迎大神拍磚,讓我改進。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM