ActiveMQ訊息佇列和SignalR之日誌實時監控及警報小例項
主要技術:
log4net-生成日誌。
ActiveMQ-生成日誌的時候傳送訊息,並實時監控日誌。
SignalR-將ActiveMQ監控的日誌實時顯示到瀏覽器上,而不用重新整理瀏覽器。
小例項介紹:
左側命名為系統一,右側命名為系統二
系統一是生成日誌的小工具,系統二根據生成的日誌實時顯示資料,如果ERROR級別的日誌超過50條則實時顯示警報。
系統一主要程式碼分析:
1.訊息佇列類-傳送訊息的方法
public class ActiveMQHelper
{
private IConnectionFactory factory;
/// <summary>
/// 初始化ActiveMQ工廠
/// </summary>
public ActiveMQHelper()
{
try
{
//初始化工廠,這裡預設的URL是不需要修改的
factory = new ConnectionFactory("tcp://localhost:61616");
}
catch(Exception ex)
{
new LogHelper(typeof(ActiveMQHelper)).Fatal(string.Format("訊息佇列伺服器初始化失敗"),ex);
}
}
/// <summary>
/// 傳送訊息方法
/// </summary>
/// <param name="msg"></param>
public void CreateConnection(string msg)
{
//通過工廠建立連線
using (IConnection connection = factory.CreateConnection())
{
//通過連線建立Session會話
using (ISession session = connection.CreateSession())
{
//通過會話建立生產者,方法裡面new出來的是MQ中的Queue
IMessageProducer prod = session.CreateProducer(new Apache.NMS.ActiveMQ.Commands.ActiveMQQueue("LogsQueue"));
//建立一個傳送的訊息物件
ITextMessage message = prod.CreateTextMessage();
//給這個物件賦實際的訊息
message.Text = msg;
//設定訊息物件的屬性,這個很重要哦,是Queue的過濾條件,也是P2P訊息的唯一指定屬性
message.Properties.SetString("filter", "log");
//生產者把訊息傳送出去,幾個列舉引數MsgDeliveryMode是否長鏈,MsgPriority訊息優先級別,傳送最小單位,當然還有其他過載
prod.Send(message, MsgDeliveryMode.Persistent, MsgPriority.Normal, TimeSpan.MinValue);
}
}
}
}
2.生成error日誌的時候傳送一條訊息
系統二主要程式碼分析:
1.頁面程式碼
SignalR簡介:瀏覽器之所以能不重新整理而事實載入資料,全靠SignalR的功勞。後臺動態生成javascript函式,頁面上呼叫後臺生成的函式即可。
下圖呼叫的是後臺MyHub.cs類的建構函式,呼叫方法為var chat = $.connection.myHub,SignalR具體使用請自行搜尋相關資料。
2.後臺程式碼 MyHub.cs類:
說明:下面灰色的一行程式碼就是動態生成的javascript動態函式
Clients.All.addNewMessageToPage(json); //前臺頁面要呼叫的函式
public class MyHub : Hub
{
public delegate void DelegateRevMessage(ITextMessage message);
private static string logPath = ConfigHelper.GetAppSetting("logpath");
public MyHub()
{
var index = new Random().Next(1, 100);
//建立連線工廠
IConnectionFactory factory = new ConnectionFactory("tcp://localhost:61616");
//通過工廠構建連線
Apache.NMS.IConnection connection = factory.CreateConnection();
//這個是連線的客戶端名稱標識
connection.ClientId = "LogsQueueListener"+index;
//啟動連線,監聽的話要主動啟動連線
connection.Start();
//通過連線建立一個會話
ISession session = connection.CreateSession();
//通過會話建立一個消費者,這裡就是Queue這種會話型別的監聽引數設定
IMessageConsumer consumer = session.CreateConsumer(new Apache.NMS.ActiveMQ.Commands.ActiveMQQueue("LogsQueue"), "filter='log'");
//註冊監聽事件
consumer.Listener += new MessageListener(consumer_Listener);
}
void consumer_Listener(IMessage message)
{
ITextMessage msg = (ITextMessage)message;
DelegateRevMessage delegateRev = RevMessage;
IAsyncResult result = delegateRev.BeginInvoke(msg, null, null);
delegateRev.EndInvoke(result);
}
/// <summary>
/// 訊息佇列實時監控的方法
/// </summary>
/// <param name="message"></param>
public void RevMessage(ITextMessage message)
{
//message.Text : 此值為訊息佇列中的值
List<LogInfoModel> list = this.Analysis(DateTime.Now);
if (list != null && list.Count > 0)
{
var fatalList = list.Where(x => x.Level.ToLower() == LevelEnum.FATAL.AsString().ToLower()).ToList();
var errorList = list.Where(x => x.Level.ToLower() == LevelEnum.ERROR.AsString().ToLower()).ToList();
/*
* 此處可以根據日誌級別及日誌數量,處理警報操作。
* 比如if(fatalList.Count>0){//發郵件;//微信提醒;//發簡訊等} //如果有fatal級別的日誌則立馬警報;
* 或者if(errorList.Count>50){//發郵件;//微信提醒;//發簡訊等} //如果error級別的日誌超過50條則立馬警報;
* **/
var json = new { fatalCount = fatalList.Count, errorCount = errorList.Count };
Clients.All.addNewMessageToPage(json); //前臺頁面要呼叫的函式
}
}
/// <summary>
/// 根據日期獲取當天的日誌列表
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public List<LogInfoModel> Analysis(DateTime date)
{
var loganalysis = new LogAnalysisBll();
var month = date.Month.ToString();
var day = date.Day.ToString();
month = month.Length == 1 ? "0" + month : month;
day = day.Length == 1 ? "0" + day : day;
//根據日誌路徑分析日誌,獲取列表
var list = loganalysis.GetLog(string.Format("{4}{0}\\{1}\\{2}\\{3}.log", date.Year, month, date.Day, date.ToString("yyyyMMdd"), logPath));
return list;
}
}
特別說明:我也是剛開始研究ActiveMQ和SignalR,如果有不妥的地方,還望大神門能多多指導,O(∩_∩)O