集成Javascript Logging on MVC or Core
ASP.NET Core provides us a rich Logging APIs which have a set of logger providers including: ConsoleLoggerPtovider, AzureAppServicesDiagnosticsLoggerProvider, EventLogLoggerProvider and much more.
This let C# developers happy than before, because you need to implement them loggers yourself in the past, however a lot of us writing JavaScript code in almost web applications which is little hard, but find the client-side exceptions & errors are even harder.
There are many client-side loggers that you can name it, which are fit our needs, but today I wanna talk about the client-side logging from different angle. Me and you as developers suffer a lot from unexpected javascript error that happen occasionally, sometimes the reason is silly such missing a curly braces or broke a link .. etc.
With that I was thinking last few days that it would be nice to integrate the client-side & server-side logs, so all the logs will be logged from the ASP.NET Core logger providers that we like and love instead of managing two different logger providers for both client-side & server-side.
Logging JavaScript Events
Basically the idea is very simple, I need to inject the client-side logging APIs script into our view, after that I need the JavaScriptLoggingMiddleware to listening to the upcoming script logs and forward them to ASP.NET Core logger providers.
With that we're ready to show some code, but before that I need to mention that I didn't introduce a new logging APIs, but I could, so the javascript console object is enough for logging. In both cases we need to intercept the console logs as the following:
(function () {
var trace = console.trace;
var debug = console.debug;
var info = console.info;
var warn = console.warn;
var error = console.error;
console.trace = function (message) {
log(logLevel.Trace, message);
trace.call(this, arguments);
};
console.debug = function (message) {
log(logLevel.Debug, message);
debug.call(this, arguments);
};
console.info = function (message) {
log(logLevel.Information, message);
info.call(this, arguments);
};
console.warn = function (message) {
log(logLevel.Warning, message);
warn.call(this, arguments);
};
console.error = function (message) {
log(logLevel.Error, message);
error.call(this, arguments);
};
})();
The log is a method that I created to post the actual logs to the server, which will handled by the JavaScriptLoggingMiddleware that shown below.
At this point I was wondering whether to store jsLogger script into the disk and render it using a tag helper or not!! after awhile I inspired by Application Insights and decided to store it into a resx file and retrieve them later using JavaScriptLoggingSnippet.
public class JavaScriptLoggingMiddleware
{
private readonly ILogger _logger;
private readonly RequestDelegate _next; public JavaScriptLoggingMiddleware(ILoggerFactory loggerFactory, RequestDelegate next)
{
_logger = loggerFactory.CreateLogger<JavaScriptLoggingMiddleware>();
_next = next;
} public async Task Invoke(HttpContext context)
{
if (context.Request.Path == "/log" && context.Request.Method == "POST" && context.Request.HasFormContentType)
{
var form = await context.Request.ReadFormAsync();
var level = Convert.ToInt32(form["level"].First());
var message = form["message"].First(); switch ((LogLevel)level)
{
case LogLevel.Trace:
_logger.LogTrace(message);
break;
case LogLevel.Debug:
_logger.LogDebug(message);
break;
case LogLevel.Information:
_logger.LogInformation(message);
break;
case LogLevel.Warning:
_logger.LogWarning(message);
break;
case LogLevel.Error:
_logger.LogError(message);
break;
default:
return;
}
}
else
{
await _next(context);
}
}
}
If you look closely to the code above, you will notice that the middleware listening for specific url, when it hit I need to map the client-side log levels with the server-side once, after that I log them normally.
I can finally log JavaScript Exceptions!
Last but not least, sometimes we come up to a situation that we need to catch the global javascript exception that may occur for whatever reason could be. window.onerror is a good place to catch such exception.
I added a JavaScriptLoggingOptions which is shown below to make things configurable in the way that you want.
public class JavaScriptLoggingOptions
{
public bool HandleGlobalExceptions { get; set; }
}
By adding this simple property, the JavaScriptLoggingSnippet is now able to choose the proper script to render in the view.
public class JavaScriptLoggingSnippet
{
private readonly JavaScriptLoggingOptions _loggingOptions; private static readonly HtmlString JavaScriptLoggingScript = new HtmlString(Resources.Script); private static readonly HtmlString JavaScriptLoggingGlobalExceptionHandlingScript = new HtmlString(Resources.GlobalExceptionHandlingScript); public JavaScriptLoggingSnippet(IOptions<JavaScriptLoggingOptions> loggingOptions)
{
_loggingOptions = loggingOptions.Value;
} public HtmlString Script =>
_loggingOptions.HandleGlobalExceptions ? FullScript : JavaScriptLoggingScript; private static HtmlString FullScript => JavaScriptLoggingScript.Concat(HtmlString.NewLine,
JavaScriptLoggingGlobalExceptionHandlingScript);
}
What it takes to make everything happen?
We need few steps to make this happen:
First we need to configure the JavaScriptLogging service in the ConfigureServices method
services.AddJavaScriptLogging(options =>
{
options.HandleGlobalExceptions = true;
});
After that adding the JavaScriptLoggingMiddleware to the Configure method
app.UseJavaScriptLogging();
Finally add the following line into your view or layout page to render the jsLogger script.
@Html.Raw(JavaScriptLoggingSnippet.Script)
You can download the source code for this post from my jsLogger repository on GitHub.
集成Javascript Logging on MVC or Core的更多相关文章
- 国产化之路-统信UOS + Nginx + Asp.Net MVC + EF Core 3.1 + 达梦DM8实现简单增删改查操作
专题目录 国产化之路-统信UOS操作系统安装 国产化之路-国产操作系统安装.net core 3.1 sdk 国产化之路-安装WEB服务器 国产化之路-安装达梦DM8数据库 国产化之路-统信UOS + ...
- 【干货理解】理解javascript中实现MVC的原理
理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程 ...
- javascript widget ui mvc
MVC只是javascript的一个UI模式 JavaScript UI----UI, Template, MVC(View)----Backbone, Angular RequireJS------ ...
- 开源题材征集 + MVC&EF Core 完整教程小结
到目前为止,我们的MVC+EF Core 完整教程的理论部分就全部结束了,共20篇,覆盖了核心的主要知识点. 下一阶段是实战部分,我们将会把这些知识点串联起来,用10篇(天)来完成一个开源项目. 现向 ...
- FineUIPro/Mvc/Core/JS v4.2.0 发布了(老牌ASP.NET控件库,WebForms,ASP.NET MVC,Core,JavaScript)!
还记得 10 年前那个稍微青涩的 ExtAspNet 吗,如今她已脱胎换骨,变成了如下 4 款产品: FineUIPro:基于jQuery的经典款ASP.NET WebForms控件,之前的FineU ...
- 30行代码实现Javascript中的MVC
从09年左右开始,MVC逐渐在前端领域大放异彩,并终于在刚刚过去的2015年随着React Native的推出而迎来大爆发:AngularJS.EmberJS.Backbone.ReactJS.Rio ...
- JavaScript富应用MVC MVVM框架
对框架的挑选 Ember.js.Backbone.js.Knockout.js.Spine.js.Batman.js , Angular.js 1. 轻量级的应用选择哪一个会比较好?2. 那一个比较简 ...
- 改造继续之eclipse集成tomcat开发spring mvc项目配置一览
在上一篇的环境配置中,你还只能基于maven开发一个javase的项目,本篇来看如果开发一个web项目,所以还得配置一下tomcat和spring mvc. 一:Tomcat安装 在.net web开 ...
- ASP.NET Core MVC+EF Core从开发到部署
笔记本电脑装了双系统(Windows 10和Ubuntu16.04)快半年了,平时有时间就喜欢切换到Ubuntu系统下耍耍Linux,熟悉熟悉Linux命令.Shell脚本以及Linux下的各种应用的 ...
随机推荐
- [MicroPython]TPYBoard智能小车“飞奔的TPYBoard装甲一号”
智能小车作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途.智能小车能够实时显示时间.速度.里程,具有自动寻迹.寻光.避障 ...
- 串行FLASH文件系统FatFs---转自野火论坛
为了支持长文件名,需要用到FATFS源码中的cc936.c的两个函数ff_convert,ff_wtoupper:这里面直接用了两个大数组(127KB)来做unicode转gbk(OEM)的对照表,这 ...
- 大数据不就是写SQL吗?
应届生小祖参加了个需求分析会回来后跟我说被产品怼了一句: "不就是写SQL吗,要那么久吗" 我去,欺负我小弟,这我肯定不能忍呀,于是我写了一篇文章发在了公司的wiki 贴出来给大家 ...
- .Net业务搭配实用技术栈
前言 昨天有篇文章在讨论webform的设计思路,我已经四五年不用webform了,虽然它也提供了HttpModule和httphandle来处理请求,提供了一般处理程序ashx来简化处理流程,但依然 ...
- webpack打包经验——处理打包文件体积过大的问题
前言 最近对一个比较老的公司项目做了一次优化,处理的主要是webpack打包文件体积过大的问题. 这里就写一下对于webpack打包优化的一些经验. 主要分为以下几个方面: 去掉开发环境下的配置 Ex ...
- Linux 的系统目录介绍
/bin 二进制可执行命令 /dev 设备特殊文件/etc 系统管理和配置文件/etc/rc.d 启动的配置文件和脚本/home 用户主目录的基点,比如用户user的主目录就是/home/user,可 ...
- AndroidManifest.xml文件解析
一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...
- # 【Python3练习题 008】判断101-200之间有多少个素数,并输出所有素数。
lst = []for i in range(100): #建立 101-200 的列表 lst.append(101+i) for i in range(101, 201): #除数为 101-20 ...
- Oracle如何扩展表空间
一: --查看表空间的名字及文件所在位置 select tablespace_name, file_id, file_name, ), ) total_space from sys.dba_data_ ...
- redux模块化demo
store.js 在redux中 store 是唯一的. import {createStore} from 'redux'; import reducer from './reducer' // 引 ...