集成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下的各种应用的 ...
随机推荐
- 在DreamView中支持一辆新车
Support a new Vehicle in DreamView In order to support a new vehicle in DreamView, please follow the ...
- mongo中游标
1.手动循环访问游标 mongo中我们常用的查询方式db.collection.find()方法其实返回的就是游标,只不过我们并未给返回的游标分配变量,我们所看到的的查询数据也就是游标自动迭代得出的( ...
- C#获取指定IP地址的数据库所有数据库实例名
/// <summary> /// 获取指定IP地址的数据库所有数据库实例名. /// </summary> /// <param name="ip" ...
- 朱晔的互联网架构实践心得S1E6:给飞机换引擎和安全意识十原则
朱晔的互联网架构实践心得S1E6:给飞机换引擎和安全意识十原则 [下载本文PDF进行阅读] 本文有两个部分,先介绍一下给飞机换引擎这个事情我的一些经验,因为篇幅较短然后介绍一下安全意识方面的一些心得. ...
- configure: error: cannot guess build type; you must specify one解决方法
原文地址:https://blog.csdn.net/hebbely/article/details/53993141 1.configure: error: cannot guess build t ...
- c++ 入门之深入探讨拷贝函数和内存分配
在c++入门之深入探讨类的一些行为时,说明了拷贝函数即复制构造函数运用于如下场景: 对象作为函数的参数,以值传递的方式传给函数. 对象作为函数的返回值,以值的方式从函数返回 使用一个对象给另一个对象初 ...
- Python_动态参数、名称空间、作用域、作用域链、加载顺序、函数的嵌套、global、nonlocal
1.动态参数 当实参数量与形参数量相等时,参数传递正常. def func1(a, b, c): pass func1(1, 2, 3) 当实参数量与形参数量不相等时,则会报错. def func1( ...
- stark组件之pop页面,按钮,url,页面
1.Window open() 方法 2.admin的pop添加按钮 3.stark之pop功能 3.知识点总结 4.coding代码 1.Window open() 方法 效果图 2.adm ...
- docker redis 多个实例
Docker运维笔记-Docker端口映射 - 恶性佛 - CSDN博客https://blog.csdn.net/qq_29994609/article/details/51730640 利用 Do ...
- FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (112503036) exceeds the configured
Message: FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUpload ...