[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 > 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

时间: 2024-07-30 19:45:15

[Asp.net]SignalR实现实时日志监控的相关文章

SignalR实现实时日志监控

.net SignalR实现实时日志监控 摘要 昨天吃饭的时候,突然想起来一个好玩的事,如果能有个页面可以实时的监控网站或者其他类型的程序的日志,其实也不错.当然,网上也有很多成熟的类似的监控系统.就想着如果通过.net该如何实现?所以就在想,通过系统内部将消息推送到前端,.net中可以通过pull或者push的方式,pull通常的做法就是ajax方式不停的请求一个接口,这种方式,不太理想.然后就在想如何通过服务端想客户端推送消息.之前看到过SignalR方面的文章可以实现push的功能,sig

[Solution] 使用 ASP.NET SignalR 添加实时 Web

ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据. 官网:http://signalr.net/ 下载:install-package Microsoft.AspNet.SignalR 本节将简单快速介绍 实现原理 Hello World 快速分析 注意事项 实现原理 如果浏览器<=

WebAPI+SignalR实现实时日志监测(二)

思路 第三方程序调用API接口时会触发日志跟踪,如果在此时将日志内容通过SignalR广播出去,并由一个Web页面接收显示,那么就能实现接口调用的实时监听. 实现改造SignalR首先我们希望能够为日志监听单独开辟一条"通道",以便不受到其他通道的影响.同时考虑到日志消息的发送是"广播",与Client无关,所以采用持久连接PersistentConnection来做这件事情. 添加我们的日志广播通道LogTracer.cs,并继承于PersistentConnec

ASP.NET MVC4使用SignalR实现实时通讯

本文介绍在ASP.NET MVC框架中如何使用SignalR进行实时通讯 1.如何在Web中实现实时通讯 实时通讯: 例如“消息提示”.“web聊天室”等.由于web浏览器中使用的是http协议(大部分请求)进行通讯,http被称为是无状态,每次http请求和应答都是通过建立tcp连接,发送数据反馈应答,关闭tcp连接.而且必须是客户端先请求服务器端,服务器端再反馈给客户端消息.并不能实现服务器端主动给客户端推送消息的功能. 实时通讯的传统实现方法: 1.刷新整个页面.这种方法最为原始,页面中设

ASP.NET Core之跨平台的实时性能监控(2.健康检查)

前言 上篇我们讲了如何使用App Metrics 做一个简单的APM监控,最后提到过健康检查这个东西. 这篇主要就是讲解健康检查的内容. 没看过上篇的,请移步:ASP.NET Core之跨平台的实时性能监控 首先我们来了解一下什么是健康检查(health checks)? 1.什么是健康检查? 健康检查,其实这个名称已经很明确了,它是检查你的应用程序是否健康运行的一种方式.随着当前各类项目越来越多的应用程序正在转向微服务式架构,健康检查就变得尤为关键.虽然微服务体系结构具有许多好处,但其中一个缺

C# ASP.NET MVC 之 SignalR 学习 实时数据推送显示 配合 Echarts 推送实时图表

本文主要是我在刚开始学习 SignalR 的技术总结,网上找的学习方法和例子大多只是翻译了官方给的一个例子,并没有给出其他一些经典情况的示例,所以才有了本文总结,我在实现推送简单的数据后,就想到了如何去推送复杂的数据,以及推送一个实时的图表数据,文本为我原创,转载请注明出处:Richard.Hu,先上一堆乱七八糟的说明先: SignalR的官方地址是: https://www.asp.net/signalr 网上给出例子是一个聊天的例子,官网地址是:https://docs.microsoft.

asp.net core api网关 实时性能监控

asp.net core api网关 实时性能监控 使用InfluxDB.Grafana Dockerfile 运行 InfluxDB.Grafana influxdb: image: influxdb ports: - "8086:8086" - "8083:8083" environment: - INFLUXDB_DB=TogetherAppMetricsDB - INFLUXDB_ADMIN_ENABLED=true - INFLUXDB_ADMIN_USE

第一章ASP.NET SignalR简介

1.1概述: ASP.NET SignalR是微软新开发的类库,为的是帮助ASP.NET开发人员很方便地开发实时网络功能. SignalR允许服务器端和客户端之间进行双向通信.服务器端现在可以连接到客户端并且把内容瞬间推送出去,而不是一个客户端不断请求服务器端从而才能获取新数据(不是通过轮询去拉服务器端数据,而是服务器端主动推送数据到客户端).SignalR支持Web Sockets套接字,并且当使用旧版浏览器的时候会自动使用相关兼容的技术.SignalR包括它的API接口,用于连接管理的解耦(

玩转ASP.NET Core中的日志组件

玩转ASP.NET Core中的日志组件简介日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 ConsoleDebugEventSourceEventLogTraceSourceAzure App Service除了内置的日志提供器,ASP.NET Core还支持了多种第三方日志工具,例如 elmah.ioGelfJSNLogKissLog.netLoggrNLogSe