[Asp.net]SignalR实现实时日志监控
摘要
昨天吃饭的时候,突然想起来一个好玩的事,如果能有个页面可以实时的监控网站或者其他类型的程序的日志,其实也不错。当然,网上也有很多成熟的类似的监控系统。就想着如果通过.net该如何实现?所以就在想,通过系统内部将消息推送到前端,.net中可以通过pull或者push的方式,pull通常的做法就是ajax方式不停的请求一个接口,这种方式,不太理想。然后就在想如何通过服务端想客户端推送消息。之前看到过SignalR方面的文章可以实现push的功能,signalr也是第一次接触,在这个网站http://www.asp.net/signalr看了一些文章。就自己动手做了这样的日志监控的demo。
一个简单的例子
先上一段代码,如下:
该类是一个监控日志文件是否变化的一个单例类。其中维护一个日志队列。
public class FileSystemWatcherSingle
{
public FileSystemWatcher wather;
private static FileSystemWatcherSingle _instance;
private static readonly object _objLock = new object();
public Queue<Log> MyQueue;
private string _watherFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log");
private FileSystemWatcherSingle()
{
if (MyQueue == null)
{
MyQueue = new Queue<Log>();
}
if (wather == null)
{
wather = new FileSystemWatcher();
if (!Directory.Exists(_watherFolderPath))
{
Directory.CreateDirectory(_watherFolderPath);
}
wather.Path = _watherFolderPath;
wather.EnableRaisingEvents = true;
}
} public static FileSystemWatcherSingle CreateInstance()
{
if (_instance == null)
{
lock (_objLock)
{
if (_instance == null)
{
_instance = new FileSystemWatcherSingle();
}
}
}
return _instance;
}
}
写日志的操作
在写入文件之前,将当前的日志加入到日志队列里面。
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web; namespace Wolfy.LogMonitor.Models
{
public class LogHelper
{
public static void WriteLog(Log log)
{
string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log");
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
string _watherFilePath = Path.Combine(dir, DateTime.Now.ToString("yyyy-MM-dd") + ".log");
if (!File.Exists(_watherFilePath))
{
File.Create(_watherFilePath);
}
FileSystemWatcherSingle wather = FileSystemWatcherSingle.CreateInstance();
wather.MyQueue.Enqueue(log);
File.AppendAllText(_watherFilePath, string.Format("{0} {1}\r\n{2}", log.Type.ToString(), log.Dt, log.Content));
}
}
}
LogHub类
需要安装SignalR,在安装完成时,有个Readme文件,根据里面的提示,需要添加StartUp类,添加对应的owin程序集。
using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Wolfy.LogMonitor.App_Start;
[assembly: OwinStartup(typeof(Startup))]
namespace Wolfy.LogMonitor.App_Start
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
LogHub继承Hub类,并在这里想所有客户端推送消息。并在这里面面为文件监控类FileSystemWatcher注册创建和Change事件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System.Timers;
using Newtonsoft.Json; namespace Wolfy.LogMonitor.Models
{
[HubName("logHub")]
public class LogHub : Hub
{
private FileSystemWatcherSingle fileWather;
public void Send(string name, string message)
{
// Call the addNewMessageToPage method to update clients.
Clients.All.addNewMessageToPage(name, message);
} public LogHub()
{
fileWather = FileSystemWatcherSingle.CreateInstance();
fileWather.wather.Changed += wather_Changed;
fileWather.wather.Created += wather_Created;
} void wather_Created(object sender, System.IO.FileSystemEventArgs e)
{
this.Send("system", "创建文件:" + e.Name);
} void wather_Changed(object sender, System.IO.FileSystemEventArgs e)
{
while (fileWather.MyQueue != null && fileWather.MyQueue.Count > )
{
Log log = fileWather.MyQueue.Dequeue();
if (log != null)
{
this.Send(log.Type.ToString(), JsonConvert.SerializeObject(log));
}
}
}
}
}
前端
home:log展示的页面。根据日志类型为该条日志显示不同的颜色。
@{
ViewBag.Title = "Home";
} <div id="container">
</div> <script>
$(function () {
// Reference the auto-generated proxy for the hub.
var log = $.connection.logHub;
console.log(log);
// Create a function that the hub can call back to display messages.
log.client.addNewMessageToPage = function (name, message) {
console.log(name);
console.log(message);
// Add the message to the page.
if (name === "Info") {
$('#container').append('<p style="color:green;">' + message + '</p>');
} else {
$('#container').append('<p style="color:red;">' + message + '</p>');
}
};
// Start the connection.
$.connection.hub.start().done();
}); </script>
LogController
Test页面是一个测试页面,通过不停的刷新写入随机类型的日志。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Wolfy.LogMonitor.Models; namespace Wolfy.LogMonitor.Controllers
{
public class LogController : Controller
{
// GET: Log
public ActionResult Home()
{
return View();
}
public ActionResult Test()
{
LogType[] logtypes = { LogType.Info, LogType.Error };
Random r = new Random();
int index = r.Next(, );
LogHelper.WriteLog(new Log { Content = "这是一次日志", Dt = DateTime.Now, Type = logtypes[index] });
return View();
}
}
}
好了,到现在基本上大功告成。测试一下。
通过不停的刷新test页面,你会发现home页面上会相应的动态展示这次操作的日志。
总结
昨天突然有这个想法,今天就折腾了一上午,将这个想法用代码实现了一下。这里没有signalr的相关介绍,感兴趣的话,可以看下面的参考资料中的内容。
参考资料
http://www.asp.net/signalr
[Asp.net]SignalR实现实时日志监控的更多相关文章
- SignalR实现实时日志监控
.net SignalR实现实时日志监控 摘要 昨天吃饭的时候,突然想起来一个好玩的事,如果能有个页面可以实时的监控网站或者其他类型的程序的日志,其实也不错.当然,网上也有很多成熟的类似的监控系统 ...
- Asp.net SignalR 让实时通讯变得如此简单
巡更项目中,需要发送实时消息,以及需要任务开始提醒,于是便有机会接触到SignalR,在使用过程中,发现用SignalR实现通信非常简单,下面我思明将从三个方面分享一下: 一.SignalR是什么 A ...
- [ASP.NET] 使用 ASP.NET SignalR 添加实时 Web
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...
- Asp.net SignalR 让实时通讯变得简单
巡更项目中,需要发送实时消息,以及需要任务开始提醒,于是便有机会接触到SignalR,在使用过程中,发现用SignalR实现通信非常简单,下面我思明将从三个方面分享一下: 一.SignalR是什么 A ...
- 使用 ASP.NET SignalR实现实时通讯
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...
- 用SignalR实现实时查看WebAPI请求日志
实现的原理比较直接,定义一个MessageHandler记录WebAPI的请求记录,然后将这些请求日志推送到客户端,客户端就是一个查看日志的页面,实时将请求日志展示在页面中. 这个例子的目的是演示如何 ...
- asp.net core结合NLog搭建ELK实时日志分析平台
0.整体架构 整体架构目录:ASP.NET Core分布式项目实战-目录 一.介绍ELK 1.说明(此篇ELK采用rpm的方式安装在服务器上)-牛刀小试 承接上一篇文章的内容准备部署ELK来展示asp ...
- ASP.NET Core之跨平台的实时性能监控(2.健康检查)
前言 上篇我们讲了如何使用App Metrics 做一个简单的APM监控,最后提到过健康检查这个东西. 这篇主要就是讲解健康检查的内容. 没看过上篇的,请移步:ASP.NET Core之跨平台的实时性 ...
- C# ASP.NET MVC 之 SignalR 学习 实时数据推送显示 配合 Echarts 推送实时图表
本文主要是我在刚开始学习 SignalR 的技术总结,网上找的学习方法和例子大多只是翻译了官方给的一个例子,并没有给出其他一些经典情况的示例,所以才有了本文总结,我在实现推送简单的数据后,就想到了如何 ...
随机推荐
- 【转】Apache的Order Allow,Deny 详解
Apache的Order Allow,Deny 详解 Allow和Deny可以用于apache的conf文件或者.htaccess文件中(配合Directory, Location, Files等 ...
- VS2013编译python源码
系统:win10 手头有个python模块,是用C写的,想编译安装就需要让python调用C编译器.直接编译发现使用的是vc9编译,不支持C99标准(两个槽点:为啥VS2008都还不支持C99?手头这 ...
- 【bzoj2809】 Apio2012—dispatching
http://www.lydsy.com/JudgeOnline/problem.php?id=2809 (题目链接) 题意 给出一棵树,每个节点有两个权值${c}$,${L}$,分别代表花费和领导力 ...
- bzoj3669[Noi2014]魔法森林
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- NuGet在Push的时候提示“远程服务器返回错误:(403)已禁用”问题解决
在使用NuGet把包push到nuget官网的时候,提示了如下信息: Failed to process request. 'The specified API key is invalid or d ...
- 文件内容统计——Linux wc命令
有了该命令,就可以得到当前目录下所有符合条件的文件总数,如下: find -type f | wc -l 这个命令的功能也很好记,因为它功能很有限: wc -c filename:显示一个文件的字节数 ...
- 洛谷P3398 仓鼠找sugar
题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...
- Uva10881 Piotr's Ants
蚂蚁相撞会各自回头.←可以等效成对穿而过,这样移动距离就很好算了. 末状态蚂蚁的顺序和初状态其实是相同的. 那么剩下的就是记录每只蚂蚁的标号,模拟即可. /*by SilverN*/ #include ...
- wordpress /wp-content/plugins/wp-symposium/server/php/UploadHandler.php File Arbitrary Upload Vul
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Relevant Link:2. 漏洞触发条件3. 漏洞影响范围4. 漏 ...
- osquery An Operating System Instrumentation Framewor
catalog . Getting Started . install guide for OS X and Linux . Features Overview . Logging . query e ...