.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 > 0)
{
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(0, 2);
LogHelper.WriteLog(new Log { Content = "这是一次日志", Dt = DateTime.Now, Type = logtypes[index] });
return View();
}
}
}

好了,到现在基本上大功告成。测试一下。

通过不停的刷新test页面,你会发现home页面上会相应的动态展示这次操作的日志。

总结

昨天突然有这个想法,今天就折腾了一上午,将这个想法用代码实现了一下。这里没有signalr的相关介绍,感兴趣的话,可以看下面的参考资料中的内容。

参考资料

http://www.asp.net/signalr

SignalR实现实时日志监控的更多相关文章

  1. [Asp.net]SignalR实现实时日志监控

    摘要 昨天吃饭的时候,突然想起来一个好玩的事,如果能有个页面可以实时的监控网站或者其他类型的程序的日志,其实也不错.当然,网上也有很多成熟的类似的监控系统.就想着如果通过.net该如何实现?所以就在想 ...

  2. 用SignalR实现实时查看WebAPI请求日志

    实现的原理比较直接,定义一个MessageHandler记录WebAPI的请求记录,然后将这些请求日志推送到客户端,客户端就是一个查看日志的页面,实时将请求日志展示在页面中. 这个例子的目的是演示如何 ...

  3. SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序

    SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论   异常汇总:http://www ...

  4. Logstash实践: 分布式系统的日志监控

    文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...

  5. Linux系统性能统计工具Sar和实时系统性能监控脚本

    sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情 ...

  6. ElasticSearch实战-日志监控平台

    1.概述 在项目业务倍增的情况下,查询效率受到影响,这里我们经过讨论,引进了分布式搜索套件——ElasticSearch,通过分布式搜索来解决当下业务上存在的问题.下面给大家列出今天分析的目录: El ...

  7. GO开发:用go写个日志监控系统

    日志收集系统架构 1.项目背景 a. 每个系统都有日志,当系统出现问题时,需要通过日志解决问题 b. 当系统机器比较少时,登陆到服务器上查看即可满足 c. 当系统机器规模巨大,登陆到机器上查看几乎不现 ...

  8. 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用

    https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...

  9. .NetCore使用skywalking实现实时性能监控

    一.简介 很久之前写了一篇 <.Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控>关于NetCore性能监控的文章,使用Inf ...

随机推荐

  1. 实用AutoHotkey功能展示

    AutoHotkey是什么 AutoHotkey是一个自动化脚本语言. AutoHotkey有什么用 可以让你用热键操控一切,操作电脑就像在表演魔术 我的口号 AutoHotkey!用过都说好! Au ...

  2. sql中插入多条记录-微软批处理

    这是使用批处理的一个例子: System.IO.StreamWriter messagelog = null; string messageString = ""; SqlConn ...

  3. WPF中获取控件之间的相对位置

    1,获取元素相对于父控件的位置 使用Vector VisualTreeHelper.GetOffset(Visual visual)方法,其会返回visual在其父控件中的偏移量,然后你再将返回值的V ...

  4. Qt中事件分发源代码剖析(一共8个步骤,顺序非常清楚:全局的事件过滤器,再传递给目标对象的事件过滤器,最终传递给目标对象)

    Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的.下面举例说明: 1)首先看看下面一段示例代码: in ...

  5. UVA 11045-My T-shirt suits me(二分图匹配)

    题意:有N件T恤,N是6的倍数,因为有6种型号,每种件数相同,有M个人,每个人有两种型号的T恤适合他,每个人可以挑其中的一种,问能否所有的人都能分配到T恤. 解析:典型的二分图匹配,每N/6为同种T恤 ...

  6. 【斗地主技巧】斗地主算法逻辑中的天之道<转>

    ******************************************************************** 作者比较喜欢玩斗地主,所以经常搜集一些网友斗地主的心得,下面这 ...

  7. Kindeditor+web.py+SAE Storage 实现文件上传 - 开源中国社区

    Kindeditor+web.py+SAE Storage 实现文件上传 - 开源中国社区 Kindeditor+web.py+SAE Storage 实现文件上传

  8. [转]使用Navicat for Oracle工具连接oracle的

    使用Navicat for Oracle工具连接oracle的 这是一款oracle的客户端的图形化管理和开发工具,对于许多的数据库都有支持.之前用过 Navicat for sqlserver,感觉 ...

  9. JSP中的include的两种用法

    1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...

  10. vb.NET基础总结

    vb.NET语言的学习,相对于原来的添加了.net平台,也 是基于对vb学习的继承与扩展,是在面向对象基础上的编程语言,vb中学到的控制语句,主要的数据类型,对象的事件,方法,属性等继续应用于vb.n ...