集成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下的各种应用的 ...
随机推荐
- FIFO队列算法的C程序实现
头文件:Queue.h #ifndef _Queue_H #define _Queue_H typedef struct QueueDef_ //队列对象定义 { u16 front; //队列头部 ...
- Python3 tkinter基础 Checkbutton variable 多选钮是否被选中
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- samba故障:protocol negotiation failed: NT_STATUS_IO_TIMEOUT
windows下无法访问samba共享目录,若无任何提示则需要到linux服务器上访问samba共享,看下是否有问题提示 故障解决过程:(保证网络通畅) 1.查看samba服务器是否正常,smb服务器 ...
- Log4J.xml配置详解
原文地址:https://blog.csdn.net/genyizha/article/details/74502812 Appender Appender:日志输出器,配置日志的输出级别.输出位置等 ...
- c++入门之 再话类
对于类,其结构并不难,但要理解其设计思想也并不容易,在此,我们可以通过下面的代码进一步理解和使用类: # ifndef VECTOR_H_ # define VECTOR_H_ # include & ...
- Python学习第十篇——函数初步
def make_album(name,album_name,song_nums = 1): dict_album = {name:[album_name]} if int(song_nums) &g ...
- 使用publisher模式控制频繁的UI输出,避免Winform界面假死
http://www.cnblogs.com/Charltsing/p/publisher.html 最近测试task并发任务的效率与线程池的区别,发现了另外一个问题.task建立任务的速度很快,输出 ...
- PT与PX区别
字体大小的设置单位,常用的有2种:px.pt.这两个有什么区别呢? 先搞清基本概念:px就是表示pixel,像素,是屏幕上显示数据的最基本的点: pt就是point,是印刷行业常用单位,等于1/72英 ...
- centos7下安装python3.6
一.wget 官网下载到本地 进入家目录: cd ~ wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz下载到本地 解压移动到/ ...
- Python之缩进块
pycharm编辑器识别冒号,当换行后下一行默认是缩进块的位置: