このページでは、SPA のモニタリングに関する問題のトラブルシューティング方法について説明します。

JavaScript エージェントを動的にロードする際の問題

Angular では AppdInitServlet を使用してモジュールを動的にロードできるため、adrum.js を動的にロードしたくなることがあります。ただし、adrum.js を動的にロードする場合の問題は、adrum.js の評価の時間と angular.js のブートストラップの時間との間で競合状態が発生する可能性があることです。この競合状態によって、JavaScript エージェントが仮想ページまたは XHR イベントを検出しない場合があります。

この競合状態を回避するには、次の手順を実行します。

Angular と JavaScript エージェントのロード

ここで重要なのは、次に示すように、最初に angular.js をロードし、すぐに adrum.js をロードすることです。

<script src="angular.js"/>
<script src="adrum.js"/>
XML

Angular のブートストラップ

手動(推奨)

adrum.js のロード後は、手動による初期化によって Angular をブートストラップできます。JavaScript エージェントがページロードと HTML DOM 待機時間/構築時間に関するより正確なメトリックを取得できるように、angular.jsadrum.js の両方をすぐにロードする必要があります。次の例では、最初の angular.js と、次の adrum.js のロードと、angular.js のブートストラップに関する推奨手順に従っています

<!doctype html>
<html>
    <head>
        <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
        <script charset='UTF-8'>
            window['adrum-start-time'] = new Date().getTime();
            (function(config){
                config.appKey = '<EUM_APP_KEY>';
                config.adrumExtUrlHttp = 'http://cdn.appdynamics.com';
                config.adrumExtUrlHttps = 'https://cdn.appdynamics.com';
                config.beaconUrlHttp = 'http://col.eum-appdynamics.com ';
                config.beaconUrlHttps = 'https://col.eum-appdynamics.com';
                config.xd = {enable : false};
            })(window['adrum-config'] || (window['adrum-config'] = {}));
            
        </script>
        <script src='//cdn.appdynamics.com/adrum/adrum-latest.js' type='text/javascript' charset='UTF-8'></script>
    </head>
    <body>
        <div ng-controller="TestController">
        It's {{currentTime}}!
        </div>
        <script>
            angular.module('angularApp', [])
            .controller('TestController', ['$scope', function ($scope) {
                $scope.currentTime = new Date().toLocaleString();
            }]);
            angular.element(document).ready(function() {
                angular.bootstrap(document, ['angularApp']);
            });
        </script>
    </body>
</html>
XML
<!doctype html>
<html>
    <head>
        <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
        <script charset='UTF-8'>
            window['adrum-start-time'] = new Date().getTime();
            (function(config){
                config.appKey = '<EUM_APP_KEY>';
                config.adrumExtUrlHttp = 'http://<your-cdn.com>';
                config.adrumExtUrlHttps = 'https://<your-cdn.com>';
                config.beaconUrlHttp = 'http://col.eum-appdynamics.com';
                config.beaconUrlHttps = 'https://col.eum-appdynamics.com';
                config.xd = {enable : false};
            })(window['adrum-config'] || (window['adrum-config'] = {}));
        </script>
        <script src='//<your-cdn.com>/adrum/adrum.js' type='text/javascript' charset='UTF-8'></script>
    </head>
    <body>
        <div ng-controller="TestController">
        It's {{currentTime}}!
        </div>
        <script>
            angular.module('angularApp', [])
            .controller('TestController', ['$scope', function ($scope) {
                $scope.currentTime = new Date().toLocaleString();
            }]);
            angular.element(document).ready(function() {
                angular.bootstrap(document, ['angularApp']);
            });
        </script>
    </body>
</html>
XML
<!doctype html>
<html>
    <head>
        <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
        <script>
            // Assumes that you downloaded the JS Agent and copied it to the 'js' directory of your app root.
            (function(config){
                config.appKey = '<EUM_APP_KEY>';
                config.adrumExtUrlHttp = 'http://cdn.appdynamics.com';
                config.adrumExtUrlHttps = 'https://cdn.appdynamics.com';
                config.beaconUrlHttp = 'http://col.eum-appdynamics.com';
                config.beaconUrlHttps = 'https://col.eum-appdynamics.com';
                config.xd = {enable : false};
           })(window['adrum-config'] || (window['adrum-config'] = {}));
        </script>
        <script src='//<your-cdn.com>/adrum/adrum.js' type='text/javascript' charset='UTF-8'/>
    </head>
   <body>
       <div ng-controller="TestController">
       It's {{currentTime}}!
       </div>
       <script>
           angular.module('angularApp', [])
           .controller('TestController', ['$scope', function ($scope) {
               $scope.currentTime = new Date().toLocaleString();
           }]);
           angular.element(document).ready(function() {
               angular.bootstrap(document, ['angularApp']);
           });
       </script>
       <script src="js/adrum.js"></script>
    </body>
</html>
XML

遅延(オプション)

手動ブートストラップが不可能な場合は、遅延ブートストラップを使用できます。これは、adrum.js が正常にロードされるまでブートストラップを一時停止することを意味します。その時点で、次の例に示すように angular.resumeBootstrap() を使用してブートストラップを再開します。

<!doctype html>
<html>
    <head>
        <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
        <script>
            // This defers the bootstrap.
            window.name = 'NG_DEFER_BOOTSTRAP!';
            angular.module('angularApp', [])
            .controller('TestController', ['$scope', function ($scope) {
                $scope.currentTime = new Date().toLocaleString();
            }]);
            angular.element(document).ready(function() {
                angular.bootstrap(document, ['angularApp']);
            });
        </script>
        // For simplicity, we're just showing the injection snippet using the Cisco AppDynamics CDN.
        <script charset='UTF-8'>
            window['adrum-start-time'] = new Date().getTime();
            (function(config){
                config.appKey = '<EUM_APP_KEY>';
                config.adrumExtUrlHttp = 'http://cdn.appdynamics.com';
                config.adrumExtUrlHttps = 'https://cdn.appdynamics.com';
                config.beaconUrlHttp = 'http://col.eum-appdynamics.com';
                config.beaconUrlHttps = 'https://col.eum-appdynamics.com';
                config.xd = {enable : false};
            })(window['adrum-config'] || (window['adrum-config'] = {}));
        </script>
        <script src='//cdn.appdynamics.com/adrum/adrum-latest.js' type='text/javascript' charset='UTF-8'></script>
  </head>
<body>
  <div ng-controller="TestController">
    It's {{currentTime}}!
  </div>
  <script>
    // Resume the bootstrapping.
    angular.resumeBootstrap()
  </script>
</body>
</html>
XML

JavaScript エージェントの手動での初期化(オプション)

adrum.js は正常にロードされるけれども、初期化されていない場合は、以下に示すように ADRUM.ng.ngMonitor.init() を呼び出して手動で初期化できます。これにより、JavaScript エージェントは、Angular ブートストラップ後も強制的に初期化されます。

 <html>
     <head>
         <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
         <script>
             // This defers the bootstrap.
             window.name = 'NG_DEFER_BOOTSTRAP!';
             angular.module('angularApp', [])
             .controller('TestController', ['$scope', function ($scope) {
                 $scope.currentTime = new Date().toLocaleString();
             }]);
             angular.element(document).ready(function() {
                 angular.bootstrap(document, ['angularApp']);
             });
         </script>
<!doctype html>
<html>
    <head>
        <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
        <script>
            // This defers the bootstrap.
            window.name = 'NG_DEFER_BOOTSTRAP!';
            angular.module('angularApp', [])
            .controller('TestController', ['$scope', function ($scope) {
                $scope.currentTime = new Date().toLocaleString();
            }]);
            angular.element(document).ready(function() {
                angular.bootstrap(document, ['angularApp']);
            });
        </script>
        // For simplicity, we're just showing the injection snippet using the Cisco AppDynamics CDN.
        <script charset='UTF-8'>
            window['adrum-start-time'] = new Date().getTime();
            (function(config){
                config.appKey = '<EUM_APP_KEY>';
                config.adrumExtUrlHttp = 'http://cdn.appdynamics.com';
                config.adrumExtUrlHttps = 'https://cdn.appdynamics.com';
                config.beaconUrlHttp = 'http://col.eum-appdynamics.com';
                config.beaconUrlHttps = 'https://col.eum-appdynamics.com ';
                config.xd = {enable : false};
            })(window['adrum-config'] || (window['adrum-config'] = {}));
        </script>
        <script src='//cdn.appdynamics.com/adrum/adrum-latest.js' type='text/javascript' charset='UTF-8'></script>
    </head>
    <body>
        <div ng-controller="TestController">
        It's {{currentTime}}!
        </div>
        <script>
            // Resume the bootstrapping.
            angular.resumeBootstrap();
            ADRUM.ng.ngMonitor.init();
        </script>
    </body>
</html>
XML

場合によっては、ADRUM.ng.ngMonitor.init()  の後に angular.resumeBootstrap(). を配置できる場合があります