集成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下的各种应用的 ...
随机推荐
- 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)
参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...
- [Spark][Python][DataFrame][RDD]从DataFrame得到RDD的例子
[Spark][Python][DataFrame][RDD]从DataFrame得到RDD的例子 $ hdfs dfs -cat people.json {"name":&quo ...
- 使用sklearn做文本特征提取
提取文本的特征,把文本用特征表示出来,是文本分类的前提,使用sklearn做文本的特征提取,需要导入TfidfVectorizer模块. from sklearn.feature_extraction ...
- nodejs源码编译-mipse64el架构
下载nodejs,node-v6.1.0.tar.gz 链接: https://pan.baidu.com/s/1eCtNBWD5yaKiQIHp3pRKew 提取码: faun 注意对应版本的gcc ...
- Beta阶段团队成员贡献分分配规则
Beta阶段团队成员贡献分分配规则 Alpha阶段贡献分分配有些负责,在这里进行一些修改: 对任务完成得分部分进行了简化 对发现bug的惩罚措施进行了修改 移除了优化得分,不鼓励修改他人代码 移除了帮 ...
- shell 小工具
1.打印进度条(待完善) #!/bin/sh printf -- 'Performing asynchronous action..'; DONE=; printf -- '............. ...
- UVA-10375 唯一分解定理
#include<iostream> #include<string.h> #include<algorithm> #include<math.h> # ...
- 三次握手复习TCP
临近下班,突然想起三次握手的概念有点模糊. 大学时候的<计算机网络>是英语版的,那时候学习迷迷糊糊的.大概记得一个模型罢了. 幸好,大学基本所有的书都卖了,就是计算机网络没卖.待会回去看看 ...
- adb通过wifi连接android设备
问题背景 近期的项目测试中,需要将移动设备与厂商机器进行usb连接视频传输(投屏).测试过程中需要定位问题,经常需要查看实时日志,移动设备已经和厂商机器usb连接投屏,无法用usb连接到PC,那么有什 ...
- Python之参数类型、变量
一.参数类型 (一)形参与实参 要使用局部变量时,只能通过return的方式返回 def my(name): #函数体 return name my('lrx') #name是形参,lrx是实参 不写 ...