zoukankan      html  css  js  c++  java
  • InspectIT_EUM 实现原理概述

    在Git上查看 InspectIT

    实现原理概述:

    实现原理详解:

           1.jsAgent如何注入到浏览器

        通过ASM框架修改HttpService.service()方法,加入相关逻辑,对每一个Http请求进行过滤:

        A:如果是自身上报采集到数据的Http请求,将将请求转到自身数据处理的方法。

        B:如果是自身的获取jsAgent资源文件的Http请求,则将请求转发到对应的处理逻辑中,根据请求信息,动态的生成对应js文件,并写入到浏览器中。

        C:对于其它的正常的业务请求,则在正常响应的基础上,加上注入相关的逻辑

        注入的基本步骤:

        通过ASM框架动态生成HttpResponse,以及HttpResponse中的输出流 PrintWrite和OutputStream的包装类,在包装类的write方法中增加 StreamedHtmlScriptInjector.performInjection(CharSequence htmlData),在该方法中解析要输出的Html代码,找到<head>标签作为插入点,插入<script>标签:

        浏览器解析html,根据<script>标签中的src属性的值,发起Http请求从服务端获取jsAgent,这个请求会分发到EUMInstrumentatoinHook.sendScript(WHttpservletResponse res, String activeModules),该方法会根据配置信息生成js文件,并 写入到浏览器,至此js注入完成。

      2.如何采集数据:

        jsAgent写入浏览器后,会直接开始执行采集的方法,主要的方式为调用浏览器线相关的API来获取对应的信息,以请求响应时间为例:

                    //force the beacon service to wait until we have collected the data
                    inspectIT.pageLoadRequest.require("navigationTimings");
                    
                    
                    var onLoadCallback = inspectIT.instrumentation.disableFor(function(){
    
                        //setTimeout is necessary as the load event also impacts the navigation and resource timings
                        setTimeout(inspectIT.instrumentation.disableFor(function(){
                            
                            inspectIT.pageLoadRequest.navigationTimings = inspectIT.pageLoadRequest.navigationTimings || {};
                            
                            inspectIT.pageLoadRequest.setEnterTimestamp(window.performance.timing.navigationStart);
                            inspectIT.pageLoadRequest.setDuration(window.performance.timing.loadEventEnd - window.performance.timing.navigationStart);
                            for (var key in window.performance.timing) {
                                // this is really sad but otherwise toJSON doesn't work in all browsers
                                inspectIT.pageLoadRequest.navigationTimings[String(key) + "W"] = window.performance.timing[key];
                            }    
                            
                            inspectIT.pageLoadRequest.markComplete("navigationTimings");
                        }), 100);
                    });
                    
                    window.addEventListener("load", onLoadCallback);
                    
                });

    调用了浏览器Navigation Timing系列中的属性,获取到对应的信息,其它指标的采集也是类似的通过调用浏览器对应的API获取基本信息后进行一定的整合。

      

      3.采集哪些指标

    /**
         * Enum values for all existing JS modules.
         */
        BROWSERINFO_MODULE('m', "plugins/browsermetainfo.js", "Browser Meta-Info Capturing", "When enabled, the browser alongside with additional meta information of users is captured."),
    
        /**
         * Module for tracking AJAX requests.
         */
        AJAX_MODULE('a', "plugins/ajax.js", "AJAX Capturing Module", "This module is responsible for capturing AJAX requests."),
        /**
         * Module for instrumenting asynchronous JS functions.
         */
        ASYNC_MODULE('b', "plugins/async.js", "Async Module", "This module instruments asynchronous Javascrpt functions like setTimeout. This helps the JS Agent to be more precise with bundling user actions. This module has no impact on other Scripts using such functions."),
        /**
         * Module for instrumenting listener functions on HTML Elements.
         */
        LISTENER_MODULE('l',
                "plugins/listener.js",
                "Listener Instrumentation Module",
                "This module instruments the addListener functions for DOM elements and therefore is able to capture User actions like a Click or something similar. Like the asynchronous module this one also has no impact on your own Scripts."),
        /**
         * Speedindex module.
         */
        SPEEDINDEX_MODULE('r', "plugins/rum-speedindex.js", "Speed Index Module",
                "This module handles the calculation of the RUM speed index. See: https://github.com/WPO-Foundation/RUM-SpeedIndex/"),
        /**
         * Navigation timings API module.
         */
        NAVTIMINGS_MODULE('1', "plugins/navtimings.js",
                "Navigation Timings Module",
                "This module deals with the collection of data captured by the Navigation Timings API. See: https://www.w3.org/TR/navigation-timing/ for further information."),
        /**
         * Resource timings API module.
         */
        RESTIMINGS_MODULE(
                '2', "plugins/restimings.js", "Resource Timings Module",
                "This module deals with collecting Resource timings provided by the Resource Timings API. See: https://www.w3.org/TR/resource-timing/ for further information.");

      Navigation timing中的属性:

      Navigation timing中属性的含义:

      4.数据是如何上报的:

      jsAgent采集到的数据,通过 Ajax异步请求发送到InspectIT的Agent端,这个请求在HttpServlet.service()方法中被识别,注入到处理数据上报的逻辑中来,最终发送到CMR。

      数据上报的格式:

      具体格式:

     

    (以上,祝愉快!)

  • 相关阅读:
    2015年个人记录
    Win10如何新建用户怎么添加新账户
    快速搭建一个本地的FTP服务器
    天气接口
    一张图搞定OAuth2.0
    PHP TS 和 NTS 版本选择
    如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)
    Npm vs Yarn 之备忘详单
    浅谈CSRF
    值得看的cookie详解
  • 原文地址:https://www.cnblogs.com/LionheartCGJ/p/7606833.html
Copyright © 2011-2022 走看看