一、背景
最近看到关于浏览器监控相关的东西,顺带着就记录一下其实现的大致原理过程。
在我们没对web应用做浏览器监控的时候,我们其实无法感知到用户对我们应用页面的使用习惯、使用中是否遇到问题,例如白屏情况出现多少次、请求失败情况、js代码有bug导致报错次数等等。 为了提高我们产品的一个良好迭代以及可持续运营,打磨体验感更好产品给客户,自然我们需要对客户的页面端进行有效监控,从而从中进行分析,哪些页面存在问题、什么时候出现的问题,这样方便我们运维和开发第一时间知道,并且做出处置。
二、实现原理与方式
1、基本原理
实现方式大致逻辑如下:
1、怎么让客户端浏览器执行我们的监控程序?
既然是客户端浏览器页面的相关监控,那么肯定是将一些我们写好的监控程序(js脚本)注入到用户的访问页面html中,因为注入<script src="http://xxx.com/agent.js"></script>例如我们选择注入在<head></head>标签之间,用户的展示界面是不会有任何问题的,因为这个script标签脚本只会在浏览器后台默默执行,不影响页面展示
2、那怎么在每个页面注入一段我们的<script src="http://xxx.com/agent.js"></script>脚本呢?
第1种很笨的方法: 每个html页面都去在<head></head>标签手动加入, 缺点就是工作量大,并且随着页面越多,漏加的情况肯定是有的,并且这种方式过于人工化,浪费时间。
第2种本质和第一种相似,但是稍微聪明一点,可以<head></head>共同的这些页面抽离出来作为公共页面, 然后每个页面去嵌入。 优点就是以后如果有更改,只改一个模板就行,其它页面不用改。缺点就是,第一次要全部页面都要加,工作量也是太大。
第3种是比较推荐的一种, 在nginx做手脚,统一使用例如正则替换的方式, 将<script>注入到<head></head>标签中。 只需要在nginx配置一次,所有经过nginx的页面或者URL都能按照这种方式进行内容替换。 优点: 工作量小,统一修改 缺点: 这个配置维护在nginx, 研发人员如果不是很清楚 的话,会比较懵逼。但是这种情况一般都是运维和研发有共同意识的,所以基本上这个也不算问题。
第4种,自己在业务代码的html响应或者接口全局拦截器自己做一个内容替换的动作,反正最终的目的就是把<script></script>的内容注入到原始html页面中,实现客户端浏览器自动执行这段监控代码。
2、难点与挑战点
既然你要在每个用户页面嵌入你的监控js代码片段,那么有几个问题你必须要注意:
1、监控是一种手段,优先级要小于业务的正常运行,所有监控的前提就是不能影响业务的正常运行或者是尽量很少的影响到业务的正常运行
2、监控代码片段不能占用太大的资源、例如大量占用客户的浏览器内存、cpu等等,给用户带来新的困扰
3、最差的情况下,监控js代码片段可以丢弃这些监控数据,不影响业务正常运行。即使采集程序崩溃也是如此
4、对于插入监控js代码片段,要覆盖各种能想到的异常情况,否则某些情况下导致用户页面无法渲染、白屏等情况
5、尽量做到用户对监控js代码片段或者程序无感知、透明化
三、Nginx使用sub_filter指令进行注入
1、nginx必须包含http_sub_module模块
nginx -V查看:
2、配置内容参考如下
sub_filter '</head>' '<script async src="http://xx.com/agent.js"></script></head>';sub_filter_once on;
3、验证一下
1、没有包含<head>标签的页面,正常访问,没有注入js脚本
服务器查看源文件内容:
浏览器显示:
源代码页面:
2、包含<head>标签页面,正常注入js脚本
服务器查看源文件内容:
浏览器显示:
源代码页面: 配置在nginx的sub_filter已经起作用,将监控的js代码片段注入到页面的head标签中