ApplicationInsights-JS icon indicating copy to clipboard operation
ApplicationInsights-JS copied to clipboard

Multiple Application Insights with different connection strings using JavaScript(Web) SDK v3 giving warnings

Open rubiks-cube opened this issue 1 year ago • 18 comments

I am trying to have multiple Application Insights(vesrion 3) with different connection strings using JavaScript(Web) SDK Loader Script on the same HTML page. I have also given different name in the configuration. But I am getting in this warning in console:

Two extensions have same priority

WhatsApp Image 2024-05-28 at 6 22 55 PM

How can I fix this? or is there any different way to have multiple instances using loader script? In the docs, it is mentioned that we can use "name" if you need to initialize two different SDKs at the same time.

rubiks-cube avatar May 28 '24 12:05 rubiks-cube

The SDK loaded does not support loading / initializing (directly) multiple SDK instances as (by default) it will always set (and sometimes (race condition) replace the global appInsights instance).

So I suspect that the (not often used) config that will help with what you are trying to achieve is the name (https://github.com/microsoft/ApplicationInsights-JS/blob/1f3dee13cd3019b68a70f027eea8cbdadfb8484d/tools/applicationinsights-web-snippet/src/snippet-config.js#L3) configuration, this is the name of the global window.appInsights (by default) where the SDK instance is registered. It's also has some additional documentation in the table in this section https://github.com/microsoft/ApplicationInsights-JS?tab=readme-ov-file#reporting-script-load-exceptions

This will require 3 separate SDK Loader instances with the 3 separate SDK Loader configs, you can't do it with a single SDK Loader config. The other option is via npm where you can load the SDK code once (in your own bundle) and then initialize multiple instances.

MSNev avatar May 28 '24 15:05 MSNev

I am already using the name property in the config and getting the issue as above. Loading 2 separate SDK configs using Script Loader separately with different name. I don't want to use npm package since I am not using any bundler.

rubiks-cube avatar May 28 '24 15:05 rubiks-cube

Hmm, that is a little odd, its sounding like the multiple versions are "sharing" the same config object and therefore as each one is initialized it keeps "adding" to the existing values.

By default, when the SDK initializes (for version 3+) it uses the "provided" config as a template and effective clones the objects / arrays (to avoid this exact issue) as internally it "adds" objects that are being listed as duplicates... The only time it doesn't do this is if the config has already been converted into a dynamic config (it's already undergone the initialization process)...

This is the code that uses the name config, and the sdk loader doesn't use the createDynamicConfig() so this (shouldn't) be occurring... I'll need to have someone investigate this a little more, however, the person I would get to do this is currently on Leave, so it might be a while before they get to it....

If you have some time if you could do some initial debugging that would be helpful, the issue sounds like it would revolve around the handling / initializing of the SDK. One simple approach (assuming the issue is not in the SDK loader itself) is that if you change the "src" to https://js.monitor.azure.com/scripts/b/ai.3.gbl.js this will use download and use the unminified version of the SDK (although the minified one also includes the map file which is publically available) and trace into the AppInsightsCore initialize function this should be the line of code that "clones" the config while this is where we "add" the standard extensions to the provided config (which is calling the AppInsightsCore config)

MSNev avatar May 28 '24 16:05 MSNev

Any update on this issue?

rubiks-cube avatar Jun 03 '24 22:06 rubiks-cube

Hi @rubiks-cube, apologies for the delay - I've just returned from vacation and am taking a look at the issue now. Thank you for your patience!

siyuniu-ms avatar Jun 04 '24 15:06 siyuniu-ms

Hello @rubiks-cube, thank you for bringing this issue to our attention. We were able to reproduce the problem and have identified that it is caused by a race condition. To address this, we will be releasing a new version of the snippet and SDK. Please note that this solution will not support IE and Opera Mini. However, you won't need to make any changes on your end. Thank you for your patience as we work to resolve this issue.

siyuniu-ms avatar Jun 06 '24 20:06 siyuniu-ms

@siyuniu-ms thanks for the update.

rubiks-cube avatar Jun 07 '24 10:06 rubiks-cube

@siyuniu-ms I see v3.2.2 is released and through npm it is installing this latest version but script loader is still loading 3.2.1

rubiks-cube avatar Jun 12 '24 06:06 rubiks-cube

Hi, our cdn release (where our snippet live) will take around 5 days after our npm is released to make sure we didn't break anything.

siyuniu-ms avatar Jun 12 '24 16:06 siyuniu-ms

any update on script loader v3.2.2? still it is fetching old version file.

rubiks-cube avatar Jun 20 '24 21:06 rubiks-cube

@rubiks-cube It would be released early next week. Thanks for waiting.

siyuniu-ms avatar Jun 21 '24 21:06 siyuniu-ms

@rubiks-cube Both snippet package and AI 3.2.2 CDN is published which contains the newest changes.

siyuniu-ms avatar Jun 24 '24 17:06 siyuniu-ms

@siyuniu-ms I am still facing the above same issue of warnings with updated version and also onInit callback function is getting called for the last appinisghts one only and not for every appInsights instance added by script loader in the html. Also there is another error I see in console: Screenshot 2024-06-25 024255

rubiks-cube avatar Jun 24 '24 21:06 rubiks-cube

Hi, could you provide more error details? I just did a local test with two snippet inited at the same time wtih two different ikey and both track message is delivered successfully.

siyuniu-ms avatar Jun 24 '24 21:06 siyuniu-ms

and below is my test code for reference

<!DOCTYPE html>

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>AISKU Sample</title>
    <link rel="stylesheet" href="style/style.css"/>
<script type="text/javascript">
!(function (cfg){function e(){cfg.onInit&&cfg.onInit(n)}var x,w,D,t,E,n,C=window,O=document,b=C.location,q="script",I="ingestionendpoint",L="disableExceptionTracking",j="ai.device.";"instrumentationKey"[x="toLowerCase"](),w="crossOrigin",D="POST",t="appInsightsSDK",E=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=E),n=C[E]||function(g){var f=!1,m=!1,h={initialize:!0,queue:[],sv:"8",version:2,config:g};function v(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[j+"id"]=i[x](),n[j+"type"]=i,n["ai.operation.name"]=b&&b.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(h.sv||h.version),{time:(i=new Date).getUTCFullYear()+"-"+a(1+i.getUTCMonth())+"-"+a(i.getUTCDate())+"T"+a(i.getUTCHours())+":"+a(i.getUTCMinutes())+":"+a(i.getUTCSeconds())+"."+(i.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z",iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}},ver:undefined,seq:"1",aiDataContract:undefined}}var n,i,t,a,y=-1,T=0,S=["js.monitor.azure.com","js.cdn.applicationinsights.io","js.cdn.monitor.azure.com","js0.cdn.applicationinsights.io","js0.cdn.monitor.azure.com","js2.cdn.applicationinsights.io","js2.cdn.monitor.azure.com","az416426.vo.msecnd.net"],o=g.url||cfg.src,r=function(){return s(o,null)};function s(d,t){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~d.indexOf("ai.3")&&(d=d.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<S.length;e++)if(0<d.indexOf(S[e])){y=e;break}var n,i=function(e){var a,t,n,i,o,r,s,c,u,l;h.queue=[],m||(0<=y&&T+1<S.length?(a=(y+T+1)%S.length,p(d.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+S[a]+i})),T+=1):(f=m=!0,s=d,!0!==cfg.dle&&(c=(t=function(){var e,t={},n=g.connectionString;if(n)for(var i=n.split(";"),a=0;a<i.length;a++){var o=i[a].split("=");2===o.length&&(t[o[0][x]()]=o[1])}return t[I]||(e=(n=t.endpointsuffix)?t.location:null,t[I]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||g.instrumentationKey||"",t=(t=(t=t[I])&&"/"===t.slice(-1)?t.slice(0,-1):t)?t+"/v2/track":g.endpointUrl,t=g.userOverrideEndpointUrl||t,(n=[]).push((i="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",o=s,u=t,(l=(r=v(c,"Exception")).data).baseType="ExceptionData",l.baseData.exceptions=[{typeName:"SDKLoadFailed",message:i.replace(/\./g,"-"),hasFullStack:!1,stack:i+"\nSnippet failed to load ["+o+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(b&&b.pathname||"_unknown_")+"\nEndpoint: "+u,parsedStack:[]}],r)),n.push((l=s,i=t,(u=(o=v(c,"Message")).data).baseType="MessageData",(r=u.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+l+")").replace(/\"/g,"")+'"',r.properties={endpoint:i},o)),s=n,c=t,JSON&&((u=C.fetch)&&!cfg.useXhr?u(c,{method:D,body:JSON.stringify(s),mode:"cors"}):XMLHttpRequest&&((l=new XMLHttpRequest).open(D,c),l.setRequestHeader("Content-type","application/json"),l.send(JSON.stringify(s)))))))},a=function(e,t){m||setTimeout(function(){!t&&h.core||i()},500),f=!1},p=function(e){var n=O.createElement(q),e=(n.src=e,t&&(n.integrity=t),n.setAttribute("data-ai-name",E),cfg[w]);return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=a,n.onerror=i,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||a(0,t)},cfg.ld&&cfg.ld<0?O.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){O.getElementsByTagName(q)[0].parentNode.appendChild(n)},cfg.ld||0),n};p(d)}cfg.sri&&(n=o.match(/^((http[s]?:\/\/.*\/)\w+(\.\d+){1,5})\.(([\w]+\.){0,2}js)$/))&&6===n.length?(d="".concat(n[1],".integrity.json"),i="@".concat(n[4]),l=window.fetch,t=function(e){if(!e.ext||!e.ext[i]||!e.ext[i].file)throw Error("Error Loading JSON response");var t=e.ext[i].integrity||null;s(o=n[2]+e.ext[i].file,t)},l&&!cfg.useXhr?l(d,{method:"GET",mode:"cors"}).then(function(e){return e.json()["catch"](function(){return{}})}).then(t)["catch"](r):XMLHttpRequest&&((a=new XMLHttpRequest).open("GET",d),a.onreadystatechange=function(){if(a.readyState===XMLHttpRequest.DONE)if(200===a.status)try{t(JSON.parse(a.responseText))}catch(e){r()}else r()},a.send())):o&&r();try{h.cookie=O.cookie}catch(k){}function e(e){for(;e.length;)!function(t){h[t]=function(){var e=arguments;f||h.queue.push(function(){h[t].apply(h,e)})}}(e.pop())}var c,u,l="track",d="TrackPage",p="TrackEvent",l=(e([l+"Event",l+"PageView",l+"Exception",l+"Trace",l+"DependencyData",l+"Metric",l+"PageViewPerformance","start"+d,"stop"+d,"start"+p,"stop"+p,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),h.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(g.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==g[L]&&!0!==l[L]&&(e(["_"+(c="onerror")]),u=C[c],C[c]=function(e,t,n,i,a){var o=u&&u(e,t,n,i,a);return!0!==o&&h["_"+c]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},g.autoExceptionInstrumented=!0),h}(cfg.cfg),(C[E]=n).queue&&0===n.queue.length?(n.queue.push(e),n.trackPageView({})):e();})({
    src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
    name: "appInsights",
    crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
    sri: true, // Custom optional value to specify whether fetching the snippet from integrity file and do integrity check 
    cfg: { // Application Insights Configuration
        connectionString: ""
    }
});
  </script>
  <script type="text/javascript">
    !(function (cfg){function e(){cfg.onInit&&cfg.onInit(n)}var x,w,D,t,E,n,C=window,O=document,b=C.location,q="script",I="ingestionendpoint",L="disableExceptionTracking",j="ai.device.";"instrumentationKey"[x="toLowerCase"](),w="crossOrigin",D="POST",t="appInsightsSDK",E=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=E),n=C[E]||function(g){var f=!1,m=!1,h={initialize:!0,queue:[],sv:"8",version:2,config:g};function v(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[j+"id"]=i[x](),n[j+"type"]=i,n["ai.operation.name"]=b&&b.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(h.sv||h.version),{time:(i=new Date).getUTCFullYear()+"-"+a(1+i.getUTCMonth())+"-"+a(i.getUTCDate())+"T"+a(i.getUTCHours())+":"+a(i.getUTCMinutes())+":"+a(i.getUTCSeconds())+"."+(i.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z",iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}},ver:undefined,seq:"1",aiDataContract:undefined}}var n,i,t,a,y=-1,T=0,S=["js.monitor.azure.com","js.cdn.applicationinsights.io","js.cdn.monitor.azure.com","js0.cdn.applicationinsights.io","js0.cdn.monitor.azure.com","js2.cdn.applicationinsights.io","js2.cdn.monitor.azure.com","az416426.vo.msecnd.net"],o=g.url||cfg.src,r=function(){return s(o,null)};function s(d,t){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~d.indexOf("ai.3")&&(d=d.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<S.length;e++)if(0<d.indexOf(S[e])){y=e;break}var n,i=function(e){var a,t,n,i,o,r,s,c,u,l;h.queue=[],m||(0<=y&&T+1<S.length?(a=(y+T+1)%S.length,p(d.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+S[a]+i})),T+=1):(f=m=!0,s=d,!0!==cfg.dle&&(c=(t=function(){var e,t={},n=g.connectionString;if(n)for(var i=n.split(";"),a=0;a<i.length;a++){var o=i[a].split("=");2===o.length&&(t[o[0][x]()]=o[1])}return t[I]||(e=(n=t.endpointsuffix)?t.location:null,t[I]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||g.instrumentationKey||"",t=(t=(t=t[I])&&"/"===t.slice(-1)?t.slice(0,-1):t)?t+"/v2/track":g.endpointUrl,t=g.userOverrideEndpointUrl||t,(n=[]).push((i="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",o=s,u=t,(l=(r=v(c,"Exception")).data).baseType="ExceptionData",l.baseData.exceptions=[{typeName:"SDKLoadFailed",message:i.replace(/\./g,"-"),hasFullStack:!1,stack:i+"\nSnippet failed to load ["+o+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(b&&b.pathname||"_unknown_")+"\nEndpoint: "+u,parsedStack:[]}],r)),n.push((l=s,i=t,(u=(o=v(c,"Message")).data).baseType="MessageData",(r=u.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+l+")").replace(/\"/g,"")+'"',r.properties={endpoint:i},o)),s=n,c=t,JSON&&((u=C.fetch)&&!cfg.useXhr?u(c,{method:D,body:JSON.stringify(s),mode:"cors"}):XMLHttpRequest&&((l=new XMLHttpRequest).open(D,c),l.setRequestHeader("Content-type","application/json"),l.send(JSON.stringify(s)))))))},a=function(e,t){m||setTimeout(function(){!t&&h.core||i()},500),f=!1},p=function(e){var n=O.createElement(q),e=(n.src=e,t&&(n.integrity=t),n.setAttribute("data-ai-name",E),cfg[w]);return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=a,n.onerror=i,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||a(0,t)},cfg.ld&&cfg.ld<0?O.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){O.getElementsByTagName(q)[0].parentNode.appendChild(n)},cfg.ld||0),n};p(d)}cfg.sri&&(n=o.match(/^((http[s]?:\/\/.*\/)\w+(\.\d+){1,5})\.(([\w]+\.){0,2}js)$/))&&6===n.length?(d="".concat(n[1],".integrity.json"),i="@".concat(n[4]),l=window.fetch,t=function(e){if(!e.ext||!e.ext[i]||!e.ext[i].file)throw Error("Error Loading JSON response");var t=e.ext[i].integrity||null;s(o=n[2]+e.ext[i].file,t)},l&&!cfg.useXhr?l(d,{method:"GET",mode:"cors"}).then(function(e){return e.json()["catch"](function(){return{}})}).then(t)["catch"](r):XMLHttpRequest&&((a=new XMLHttpRequest).open("GET",d),a.onreadystatechange=function(){if(a.readyState===XMLHttpRequest.DONE)if(200===a.status)try{t(JSON.parse(a.responseText))}catch(e){r()}else r()},a.send())):o&&r();try{h.cookie=O.cookie}catch(k){}function e(e){for(;e.length;)!function(t){h[t]=function(){var e=arguments;f||h.queue.push(function(){h[t].apply(h,e)})}}(e.pop())}var c,u,l="track",d="TrackPage",p="TrackEvent",l=(e([l+"Event",l+"PageView",l+"Exception",l+"Trace",l+"DependencyData",l+"Metric",l+"PageViewPerformance","start"+d,"stop"+d,"start"+p,"stop"+p,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),h.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(g.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==g[L]&&!0!==l[L]&&(e(["_"+(c="onerror")]),u=C[c],C[c]=function(e,t,n,i,a){var o=u&&u(e,t,n,i,a);return!0!==o&&h["_"+c]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},g.autoExceptionInstrumented=!0),h}(cfg.cfg),(C[E]=n).queue&&0===n.queue.length?(n.queue.push(e),n.trackPageView({})):e();})({
        src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
        name: "appInsights2",
        crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
        sri: true, // Custom optional value to specify whether fetching the snippet from integrity file and do integrity check 
        cfg: { // Application Insights Configuration
          connectionString: ""
        }
    });
      </script>
  </head>
  <body>
    <h1>Microsoft Application Insights JavaScript SDK - AISKU</h1>
    <script>
      let appInsights = new ApplicationInsights.ApplicationInsights({ config: {connectionString: "InstrumentationKey=88888888", disableInstrumentationKeyValidation: true}});
      appInsights.loadAppInsights();
      window.appInsights = appInsights;
    </script>
  </body>
</html>

siyuniu-ms avatar Jun 24 '24 21:06 siyuniu-ms

For some context, you will need both the new version "8" (see "sv": "8") of the SDK Loader AND version 3.2.2 of the SDK, if either version does not match (or greater) then the identifed race condition causing SDK A to use Loader B and Vica-versa configuration may still occur. This is because v3.2.2 is now (optionally) using the data-tag to identify the "global" instance name (this also requires that you runtime supports the document.currentScript (as this is what it uses to get access to any passed attribute on the script tag). And only v8 onwards will add this new data attribute to the script tag.

MSNev avatar Jun 24 '24 21:06 MSNev

The script loader mentioned in docs is different : Script Loader. Using the above snippet doesn't have this issue.

rubiks-cube avatar Jun 24 '24 21:06 rubiks-cube

Yeah, not all of the documentation has been updated yet, it is included on the main readme https://github.com/microsoft/ApplicationInsights-JS/blob/main/tools/grunt-tasks/minifyNames.js and it is included in v1.2.0 of the web-snippet package https://www.npmjs.com/package/@microsoft/applicationinsights-web-snippet (which we published on friday)

MSNev avatar Jun 24 '24 22:06 MSNev

Closing as released

MSNev avatar Nov 07 '24 22:11 MSNev

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Nov 08 '25 00:11 github-actions[bot]