使用MongoDB 記錄業務日志


      最近公司有個需求,要對業務日志進行記錄並根據日志排查問題,以前都是使用log4net之類的日志組件來記錄到文件,這種方式已經不能滿足業務的需要,因為日志文件會很大,即使進行分割后,查找也是很不方便,何況現在項目基本都是分布式,會有多台應用服務器,那么就需要把多台服務器上的日志弄到一起,十分的麻煩,經過選擇后ELK進入視線,測試環境也搭建了一套,現在唯一的問題就是怎么把多台服務器上的日子泵出到elstaticsearch中,我們的應用服務器都是windows,所以需要在每一台應用服務器上安裝一個服務,如:NXlog之類的,經過考慮覺得這種方式太麻煩,所以決定把日志先記錄到MongoDb,先實現簡單的日志查詢,再統一從MongoDb將數據泵出到elstaticsearch中,思路有了,開始動手測試。

第一步,插入測試數據,MongoDb數據庫我是安裝在本地一個linux虛擬機里,插入1000000條數據耗時8分鍾,有興趣的童鞋自己測試一下,用來存儲日志完全沒有問題,廢話不多說了,上代碼:

 1         static void Main(string[] args)
 2         {
 3             try
 4             {
 5 #region 插入測試數據
 6                 //var sw = new Stopwatch();
 7                 //sw.Start();
 8                 //string tableName = "InsuranceLog";
 9                 //for (var i = 0; i < 1000000; i++)
10                 //{
11                 //    var lb = new LogBase<InsuranceLog>()
12                 //    {
13                 //        Message = new InsuranceLog
14                 //        {
15                 //            BusinessKey = i.ToString(),
16                 //            BusinessName = "政策查詢" + i,
17                 //            BusinessParameters = "根據實際需要組織<xml><OrderId>AutoHome" + i + "</OrderId></xml>"
18                 //        }
19                 //    };
20 
21                 //    InsertOneLogToMongoDbAsync(lb, tableName);
22                 //}
23                 //sw.Stop();
24                 //Console.WriteLine("插入100000條數據耗時:" + sw.ElapsedMilliseconds + "ms");
25 #endregion
26 
27 #region 根據條件從1000000條數據中獲取指定數據
28                 var sw = new Stopwatch();
29                 sw.Start();
30                 var obj = GetList();
31                 sw.Stop();
32                 Console.WriteLine("從100000條數據獲取指定數據耗時:" + sw.ElapsedMilliseconds + "ms");
33                 foreach (var o in obj)
34                 {
35                     if (o.Message != null)
36                     {
37                         Console.WriteLine("調用時間:"+o.CallTime);
38                         Console.WriteLine("業務key:" + o.Message.BusinessKey);
39                         Console.WriteLine("業務名稱:" + o.Message.BusinessName);
40                         Console.WriteLine("業務參數:" + o.Message.BusinessParameters);
41                     }
42                 }
43 #endregion
44                 Console.ReadKey();
45             }
46             catch (Exception ex)
47             {
48                 throw;
49             }
50         }
51 
52 
53         /// <summary>
54         /// 從MongoDb 獲取數據
55         /// </summary>
56         /// <returns></returns>
57         static List<LogBase<InsuranceLog>> GetList()
58         {
59             try
60             {
61                 var client = new MongoClient("mongodb://192.168.21.129:27017");
62                 var database = client.GetDatabase("logs");
63                 var collection = database.GetCollection<LogBase<InsuranceLog>>("InsuranceLog");
64                 var b = (from x in collection.AsQueryable()
65                          where x.CallTime.StartsWith("201604281414")
66                          && x.CallTime.EndsWith("000")
67                          select x).ToList();
68                 return b;
69             }
70             catch (Exception ex)
71             {
72                 throw;
73             }
74         }
75 
76 
77         /// <summary>
78         /// 插入單條數據
79         /// </summary>
80         /// <typeparam name="T"></typeparam>
81         /// <param name="t"></param>
82         /// <param name="name"></param>
83         static async Task InsertOneLogToMongoDbAsync<T>(T t, string name)
84         {
85             try
86             {
87                 var client = new MongoClient("mongodb://192.168.21.129:27017");
88                 var database = client.GetDatabase("logs");
89                 var collection = database.GetCollection<T>(name);
90                 await collection.InsertOneAsync(t);
91             }
92             catch (Exception ex)
93             {
94                 throw;
95             }
96         }

主要測試點在查詢上,要根據條件快速檢索出需要的數據,我測試了一下,單條數據大概是800ms左右,我的查詢條件取出來38條數據,耗時842ms,

 

重點:日志基類,擴展性很好,支持自定義實體類

 1     /// <summary>
 2     ///     日志基類
 3     /// </summary>
 4     [BsonIgnoreExtraElements]
 5     public class LogBase<T>
 6     {
 7         public LogBase()
 8         {
 9             CallTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");
10             SerialNo = Guid.NewGuid().ToString("N");
11             ClientType = "1";
12             Message = default(T);
13             var myEntry = Dns.GetHostEntry(Dns.GetHostName());
14             var address = myEntry.AddressList.FirstOrDefault(e => e.AddressFamily.ToString().Equals("InterNetwork"));
15             if (address == null) return;
16             var ip = address.ToString();
17             HostIp = ip;
18         }
19 
20         /// <summary>
21         ///     調用時間,格式:yyyyMMddHH24mmss
22         /// </summary>
23         public string CallTime { get; private set; }
24 
25         /// <summary>
26         ///     消息序列號 UUID
27         /// </summary>
28         public string SerialNo { get; private set; }
29 
30         /// <summary>
31         ///     客戶端IP地址
32         /// </summary>
33         public string HostIp { get; private set; }
34 
35         /// <summary>
36         ///     客戶端類型:1:pc 2:手機
37         /// </summary>
38         public string ClientType { get; private set; }
39 
40         /// <summary>
41         ///     業務信息
42         /// </summary>
43         public T Message { get; set; }
44 
45     }
View Code

測試程序用到的自定義日志類:

 1 public class InsuranceLog
 2     {
 3         /// <summary>
 4         ///     當前登錄用戶
 5         /// </summary>
 6         public string UserName { get; set; }
 7 
 8         /// <summary>
 9         ///     業務key
10         /// </summary>
11         public string BusinessKey { get; set; }
12 
13         /// <summary>
14         ///     業務名稱 如:查詢政策  下訂單  查看訂單
15         /// </summary>
16         public string BusinessName { get; set; }
17 
18         /// <summary>
19         ///     業務參數
20         /// </summary>
21         public string BusinessParameters { get; set; }
22     }
View Code

未完待續

 


免責聲明!

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



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