最初写NebuLog就是出于不想看别人的工具文档(阅读水平差)。不过后来发现通过网络把日志信息发出来的想法还是有实用性,除了不用占用服务器硬盘或者数据库空间以外,还能把http://asp.net core一个基本的action执行时间从几百毫秒降到毫秒级(请自行比较一下log to file和signalr发送的差异)。

现在简单介绍一下NebuLog在http://Asp.net core里面的用法(客户端和服务端都是MVC项目):

服务器

demo建议调试运行部署NebuLogNebuLogServerSampleNebuLogMvcServerSample项目。如果实用请自行开发用户界面。源码在GitHub地址是:

https://github.com/imadyTech/NebuLog​github.com

imadyTech/NebuLog

https://github.com/imadyTech/NebuLog​github.com

StartUp.cs是我们熟悉的模式,其中注意services添加SignalR的注册,Configure中要在UseEndpoints配置NebuLogHub(重要)。

public void ConfigureServices(IServiceCollection services){services.Configure<CookiePolicyOptions>(options =>{......services.AddSignalR( ).AddMessagePackProtocol();......}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){......app.UseEndpoints(endpoints =>{endpoints.MapHub<NebuLogHub>("/NebuLogHub");......});

Mvc示例实际上通过asp.netcore的MVC来提供监控界面的HTML和js代码。因为示例直接用微软模板创建,大部分没有什么改动,只是wwwroot中有几个比较重要的文件:

  • 页面HTML通过Monitor.cshtml提供;
  • NebuLog前端操作代码都在NebuLogClient.js中;
  • 视图的样式拷贝了一个开源的charisma模板(Free HTML5 Bootstrap Admin Template);
  • 数据表使用了开源的Bootstrap Table模板(https://github.com/wenzhixin/bootstrap-table/)。
  • 服务端appsettings.json无需配置。

部署完成通过localhost访问即可,此时对于客户端需要配置NebuLogHub的地址为http://localhost/NebuLogHub。如果是调试运行,示例代码使用了5999端口。

客户端

  • 安装nebulog包或者在solution中直接引用imady.NebuLog.csproj项目源码:
PM> install-package imady.NebuLog

  • 代码添加一下引用:
using imady.NebuLog;

  • 在appsettings.json中配置NebuLog相关参数:
{"Logging": {"LogLevel": {"Default": "Debug","System": "Information","Microsoft": "Information"}},"NebuLogOption": {"ProjectName": "NebuLogTest","NebuLogHubUrl": "http://localhost:5999/NebuLogHub","LogLevel": "Trace"//需要发送log的最低级别,可以减少无效日志数量},"AllowedHosts": "*"
}

与一般的http://asp.net core MVC项目一样,在startup.cs的ConfigureServices和Configure方法中配置services和运行管道。与NebuLog相关的配置代码如下:

public void ConfigureServices(IServiceCollection services){... ...//获取NebuLog配置参数Services.Configure<NebuLogOption>(Configuration.GetSection("NebuLogOption"));//如果想使用INebuLog的扩展则通过使用AddNebuLogServices.AddNebuLog();//设置系统日志输出的最小级别Services.AddLogging(builder =>{builder.AddFilter<NebuLogProvider>("Microsoft", LogLevel.Trace).AddConsole().AddDebug();});}public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory){//通过asp.net core管道中间件的方式截取exception,以免显示error页面。//这段代码在前几个git更新中丢失了,从其他项目里找回来的。未进行测试。var myLogger = Services.BuildServiceProvider().GetService<INebuLogger<NebuLogExceptionMiddleWare>>();app.UseNebuLogException(new NebuLogExceptionMiddleWareOption(errorHandingPath: "/home/error"),myLogger);... ... //如果想开启系统日志输出到INebuLog则使用以下代码var option = Services.BuildServiceProvider().GetService<IOptions<NebuLogOption>>();loggerFactory.UseNebuLog(Services);//extension方式添加NebuLog,两种写法效果等同//loggerFactory.AddProvider(new NebuLogProvider(option));... ...}

好了。配置、部署通过后,调试运行(server需要先启动,然后启动client),无需自己写任何log的代码,就会在NebuLog服务端的web界面中收到http://asp.net core应用级别的日志输出了:

知乎视频​www.zhihu.com

自定义日志

前面演示了如何将http://asp.net core MVC运行时的应用日志通过NebuLog输出到远端。那么如果要输出自己的日志(比如调试的提示信息等)怎么办呢?

这时候我们可以利用http://asp.net core的依赖注入在需要的地方获取一个ILogger实例:

public HomeController(ILogger<HomeController> logger)

然后通过这个实例像以往一样输出日志即可。

public IActionResult Index(){_logger.LogTrace("LogTrace.");_logger.LogDebug("LogDebug.");_logger.LogInformation("LogInformation.");_logger.LogWarning("LogWarning.");_logger.LogError("LogError.");_logger.LogCritical("LogCritical.");return View();}

如果我们已经写了很多代码,并且在代码中包含了很多日志的输出(例如输出到文件),这时并不需要去逐条改写日志输出代码,这些输出的日志会自动通过NebuLog输出到远端监控界面。

值得一提的是http://asp.net core的日志系统的改良设计。首先日志并非仅限于单一的日志记录器(logger),而是由用户在startup中根据需要自行定义,例如在前面ConfigureServices中:

            Services.AddLogging(builder =>{builder.AddFilter<NebuLogProvider>("Microsoft", LogLevel.Trace).AddConsole().AddDebug();});

上述代码是对不同的日志进行了过滤选项的配置。而你甚至可以把Console的日志除去。具体可以搜索网上很多关于ILogger的教程,解释得比我更详尽。

NebuLog就是利用了这种机制,通过LoggerFactory注册了一个新的LoggerProvider:

public static class LoggerFactoryExtensions{public static void UseNebuLog(this ILoggerFactory factory, IServiceCollection services){factory.AddProvider(new NebuLogProvider(services.BuildServiceProvider().GetService<IOptions<NebuLogOption>>()));}}

注意 LoggerFactory并没有立即为http://asp.net core进程创建一个INebuLogger的实例,而是一直等到用户代码像依赖注入框架(DI)请求ILogger或者INebuLogger的时候才调用ILoggerProvider来生成新的实例。这种操作方式与直接从IServiceCollertion中获取相应服务的注册信息并创建新实例的方式相比,provider模式允许带参构造器,这样就可以在构造时进行配置参数注入、创建hubConnection等操作。而AddScoped<T>通常只能针对无参构造的类。

Web错误的截获(中间件模式)

通常我们的网页代码不可避免的会出现一些bug(不可避免地会被扣奖金吗?)按照前面的介绍,出错时的exception信息已经会被输出到服务端进行处理了,比如显示、存储。但是在用户视图上往往会显示一个error的画面。这是http://asp.net core MVC默认的处理方式(其实微软的模板是非常简单粗糙的)。我们知道,可以通过Configure来配置这个错误信息页面的路由:

            if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");... ...}

NebuLog基于http://Asp.net core的中间件模式写了一个错误处理的中间过程NebuLogExceptionMiddleWare,可以对错误信息进行输出,然后再把context信息丢给管道的下一个环节继续处理。

var myLogger = Services.BuildServiceProvider().GetService<INebuLogger<NebuLogExceptionMiddleWare>>();
app.UseNebuLogException(new NebuLogExceptionMiddleWareOption(errorHandingPath: "/home/error"),myLogger);

NebuLog日志功能的扩展

根据前面介绍的NebuLog实现原理,我们其实可以想到对其进行扩展。下面的例子,就是对一个固定的状态参数进行跟踪刷新显示,而不是像一般的日志在datatable中滚动添加。

void AddCustomStats(string statId, string statTitle, string color);
void LogCustomStats(string statId, string message);

由于上述两个方法并不是Microsoft.Extensions.Logging.ILogging接口中规定的方法,我们不能通过依赖注入提供的ILogger实例来调用,而是必须在需要的地方去请求INebuLogger:

public HomeController(INebuLogger<HomeController> _logger)
{_logger.AddCustomStats( statID, statTitle, "green", "oldValue");_logger.LogCustomStats( statID, "newValue");... ...
}

此外,微软现在推广的gRPC技术,应该结构性比SignalR更强,也许会更适合做功能复杂的分布式日志工具软件。

需改进之处

NebuLog并非一个正式的项目,而仅仅是进行技术学习、探索的一个小插曲,自然问题多多。例如,前端datatable的刷新受限于我小白级别的前端知识,日志达到1000条时web浏览器就基本吃不消了。虽然这个问题通过js进行缓存、分页等方式应该可以轻松解决,但对于我来说又需要去问询大量度娘和谷哥了。鉴于NebuLog的性质,而且并不确定这个项目是否具有实用价值,因此目前做到这个程度暂时不打算再写了。

如果有朋友有兴趣,可以留言进行交流。

由于本人属于超大龄业余编程面包员的性质,在实战方面没有什么经验,所以对于日志工具的需求基本出于自己的臆想。希望各位朋友留言聊聊,大厂在开发时调试用什么工具?一般需要什么功能?也许能够为NebuLog找到它的位置,使其能往前走多一步。

鸣谢

服务端页面视图模板 by Charisma

数据表格 by Bootstrap Table

以下大佬的博客在开发NebuLog过程中解释了很多疑惑或者提供了方向,甚为感谢(不确定具体每篇讲的内容了,均摘自我的印象笔记记录):

.Net架构篇:思考如何设计一款实用的分布式监控系统?

.Net架构篇:思考如何设计一款实用的分布式监控系统? - 从此启程 - 博客园​www.cnblogs.com

.Net架构篇:思考如何设计一款实用的分布式监控系统?从入门到放弃之路

https://www.cnblogs.com/fancunwei/p/9637247.html​www.cnblogs.com

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

玩转ASP.NET Core中的日志组件​www.cnblogs.com

.NET Core下的日志(2):日志模型详解 (Artech)

.NET Core下的日志(2):日志模型详解​www.cnblogs.com

.net core 日志引擎(简书) 李浩的博客

.net core 日志引擎​www.jianshu.com

How to add custom logging in http://ASP.NET Core

How to add custom logging in ASP.NET Core​asp.net-hacker.rocks

How to enable Trace logging in http://ASP.NET Core?

How to enable Trace logging in ASP.NET Core?​stackoverflow.com

可通过http获取远端服务信息_(二)NebuLogMvcSample如何获取应用日志并定制输出...相关推荐

  1. 可通过http获取远端服务信息_微服务基础——厉害了!API网关

    微服务刚刚诞生的时候,人们将服务进行拆分,实现服务之间的松耦合,并且每个服务有专门的团队维护,然后客户端直接和各个子服务进行交互.比如,订单,商品,会员服务. 那么这种客户端直接和后端服务交互的方式会 ...

  2. 叮叮获取所有用户信息_钉钉如何获取员工位置?

    展开全部 钉钉通过32313133353236313431303231363533e4b893e5b19e31333365666331"签到功能获取位置,最新版本即便你屏蔽了WIFI和GPS ...

  3. java获取ua浏览器指纹_头条:如何获取浏览器指纹信息

    ❝ 本文收录于 GitHub 日问: DailyQuestion,内含大厂内推机会.面经大全及若干面试题,每天学习五分钟,一年进入大厂中. 大厂面经大全 大厂内推 ❞ 由于不同的系统显卡绘制 canv ...

  4. 公证服务信息_使用多个公证员提高网络吞吐量

    公证服务信息 您是否需要高吞吐量的Corda网络? 网络的吞吐量是否稳定? 您是否已经从其他领域挤出了所有可能的表现? 如果您对这些问题的回答是"是",那么我可能会为您提供一些有用 ...

  5. c++ 如何获取移动硬盘型号信息_工程销售,如何高效快速获取项目信息

    怎么获取工程信息,对于做建筑工程的销售来说,基本都知道,无非就是通过扫街.网上 搜索.购买第三方工程信息服务.或者他人介绍(亲朋好友.客户.同事.设计师等).在怎 么找项目信息方面?每个人都有自己的方 ...

  6. 叮叮获取所有用户信息_钉钉小程序获取用户信息

    1.钉钉小程序只允许开发办公类的程序,不能开发娱乐型的程序. 2.钉钉小程序审核需要产品说明书,最大大小不能超过30M(文档). 3.貌似可以用IP,暂时没有看到有关https的限制. (业务提供商( ...

  7. 浏览器js 获取手机标识信息_手机软件多次要求获取手机信息,习惯性让其通过有安全隐患?...

    大家在平常用手机新安装一个手机软件时,第一次打开该软件都会提示需要你允许该软件获取你的信息,为了方便我们一般都不会仔细去看究竟是哪一项权限,大多数的APP只是申请要麦克风或者摄像头的权限而已.但是总是 ...

  8. file对象怎样获取文件的长度?_使用FSO对象获取整个文件夹的信息

    大家好,我们今日讲解"VBA信息获取与处理"教程中第十八个专题"FSO对象对文件及文件夹的处理"的第三节"使用FSO对象获取整个文件夹的信息" ...

  9. sql 获取数据库字段信息_使用DBATools获取SQL数据库详细信息

    sql 获取数据库字段信息 In the series of articles on DBATools, (see TOC at the bottom) we are exploring useful ...

  10. java获取支付宝实名信息_获取支付宝授权用户信息

    登录 支付宝开放平台,创建应用 进入应用 在应用信息里设置两处,授权回调只需要到域名即可. 接口加签方式如下图 使用"支付宝密钥生成器"生成,如下图 将公钥复制到 接口加签方式 的 ...

最新文章

  1. 未来的信息安全管理人员应当具备哪些技能
  2. UI之UI View--属性及用法
  3. fatal error LNK1123: 转换到 COFF 期间失败
  4. Pearson收购PowerSchool iPod播教育内容
  5. iOS之深入解析保证线程安全的“锁”的使用和性能分析
  6. LeetCode 658. 找到 K 个最接近的元素(二分查找)
  7. extjs 月份选择控件_ExtJs日期控件案例(可控制时间的选择) | 学步园
  8. mysql高级查询面试_高级MySQL数据库面试问题 附答案
  9. Java 的混合执行模式
  10. Web development mistakes
  11. 组态王bitset用法_关于STEP7在组态王里定义I/O离散变量
  12. 为什么阿里巴巴的市值比京东高,世界500排名比京东靠后?
  13. Mysql常用操作2
  14. 华为数通笔记-DHCP
  15. Java虚拟机类加载器及双亲委派机制
  16. Ubuntu安装wps,切换中文版,以及解决无法输入汉字的问题
  17. 三维数据入库发布流程之3dMAX数据
  18. PyQt5开发桌面程序二(获取公网ip)
  19. mysql取第一行数据_select取第一行数据
  20. mac更改launchpad图标大小

热门文章

  1. 精英讲师培训笔记01-提升口才的三个心法
  2. sklearn.metrics.roc_curve使用说明
  3. 设置DIV块元素在浏览器页面中垂直居中
  4. 081 Search in Rotated Sorted Array II
  5. 被监控机上安装nagios插件和nrpe(nrpe添加为xinetd服务)
  6. STP重新收敛过程和补充内容
  7. Linux Apache服务详解——Apache服务访问控制
  8. 家庭记事本开发进度6
  9. 【译】你不知道的 Chrome 调试工具技巧 第二十三天:Drawer tips 后续
  10. Android开发过程中的坑及解决方法收录