Application Insights not logging browser data - javascript

I am using application insights javascript sdk in my mvc application. I've copied the following snippet from here (https://learn.microsoft.com/en-us/azure/azure-monitor/app/javascript):
<script type="text/javascript">
!function(T,l,y){var S=T.location,k="script",D="instrumentationKey",C="ingestionendpoint",I="disableExceptionTracking",E="ai.device.",b="toLowerCase",w="crossOrigin",N="POST",e="appInsightsSDK",t=y.name||"appInsights";(y.name||T[e])&&(T[e]=t);var n=T[t]||function(d){var g=!1,f=!1,m={initialize:!0,queue:[],sv:"5",version:2,config:d};function v(e,t){var n={},a="Browser";return n[E+"id"]=a[b](),n[E+"type"]=a,n["ai.operation.name"]=S&&S.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(m.sv||m.version),{time:function(){var e=new Date;function t(e){var t=""+e;return 1===t.length&&(t="0"+t),t}return e.getUTCFullYear()+"-"+t(1+e.getUTCMonth())+"-"+t(e.getUTCDate())+"T"+t(e.getUTCHours())+":"+t(e.getUTCMinutes())+":"+t(e.getUTCSeconds())+"."+((e.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}}}}var h=d.url||y.src;if(h){function a(e){var t,n,a,i,r,o,s,c,u,p,l;g=!0,m.queue=[],f||(f=!0,t=h,s=function(){var e={},t=d.connectionString;if(t)for(var n=t.split(";"),a=0;a<n.length;a++){var i=n[a].split("=");2===i.length&&(e[i[0][b]()]=i[1])}if(!e[C]){var r=e.endpointsuffix,o=r?e.location:null;e[C]="https://"+(o?o+".":"")+"dc."+(r||"services.visualstudio.com")}return e}(),c=s[D]||d[D]||"",u=s[C],p=u?u+"/v2/track":d.endpointUrl,(l=[]).push((n="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",a=t,i=p,(o=(r=v(c,"Exception")).data).baseType="ExceptionData",o.baseData.exceptions=[{typeName:"SDKLoadFailed",message:n.replace(/\./g,"-"),hasFullStack:!1,stack:n+"\nSnippet failed to load ["+a+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(S&&S.pathname||"_unknown_")+"\nEndpoint: "+i,parsedStack:[]}],r)),l.push(function(e,t,n,a){var i=v(c,"Message"),r=i.data;r.baseType="MessageData";var o=r.baseData;return o.message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+n+")").replace(/\"/g,"")+'"',o.properties={endpoint:a},i}(0,0,t,p)),function(e,t){if(JSON){var n=T.fetch;if(n&&!y.useXhr)n(t,{method:N,body:JSON.stringify(e),mode:"cors"});else if(XMLHttpRequest){var a=new XMLHttpRequest;a.open(N,t),a.setRequestHeader("Content-type","application/json"),a.send(JSON.stringify(e))}}}(l,p))}function i(e,t){f||setTimeout(function(){!t&&m.core||a()},500)}var e=function(){var n=l.createElement(k);n.src=h;var e=y[w];return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=i,n.onerror=a,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||i(0,t)},n}();y.ld<0?l.getElementsByTagName("head")[0].appendChild(e):setTimeout(function(){l.getElementsByTagName(k)[0].parentNode.appendChild(e)},y.ld||0)}try{m.cookie=l.cookie}catch(p){}function t(e){for(;e.length;)!function(t){m[t]=function(){var e=arguments;g||m.queue.push(function(){m[t].apply(m,e)})}}(e.pop())}var n="track",r="TrackPage",o="TrackEvent";t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+r,"stop"+r,"start"+o,"stop"+o,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),m.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4};var s=(d.extensionConfig||{}).ApplicationInsightsAnalytics||{};if(!0!==d[I]&&!0!==s[I]){var c="onerror";t(["_"+c]);var u=T[c];T[c]=function(e,t,n,a,i){var r=u&&u(e,t,n,a,i);return!0!==r&&m["_"+c]({message:e,url:t,lineNumber:n,columnNumber:a,error:i}),r},d.autoExceptionInstrumented=!0}return m}(y.cfg);function a(){y.onInit&&y.onInit(n)}(T[t]=n).queue&&0===n.queue.length?(n.queue.push(a),n.trackPageView({})):a()}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js", // The SDK URL Source
// name: "appInsights", // Global SDK Instance name defaults to "appInsights" when not supplied
// ld: 0, // Defines the load delay (in ms) before attempting to load the sdk. -1 = block page load and add to head. (default) = 0ms load after timeout,
// useXhr: 1, // Use XHR instead of fetch to report failures (if available),
crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
// onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument -- the sdk instance (DO NOT ADD anything to the sdk.queue -- As they won't get called)
cfg: { // Application Insights Configuration
instrumentationKey: "{InstrumentationKey}"
enableDebug: true,
verboseLogging: true,
disableFetchTracking: false,
enableCorsCorrelation: true,
enableRequestHeaderTracking: true,
enableResponseHeaderTracking: true
/* ...Other Configuration Options... */
}});
</script>
Now the issue is when I browse any page of my web app I can see a track request in the network tab of chrome dev tool like the following:
Request Url: https://dc.services.visualstudio.com/v2/track
Response: {"itemsReceived":2,"itemsAccepted":0,"errors":[{"index":0,"statusCode":206,"message":"Telemetry sampled out."},{"index":1,"statusCode":206,"message":"Telemetry sampled out."}],"appId":"0bb96f1c-1feb-4191-b47c-eed8676dae68"}
In the resposne, we can see ItemsReceived are 2 but ItemsAccepted is 0 and there is an object in Errors array which says "Telemetry Sampled Out" and due to this I am unable to see any log in application insights on Azure portal.
Any idea how can I fix this?

In the resposne, we can see ItemsReceived are 2 but ItemsAccepted is 0
We have followed the documented steps , to enable client side telemetry by adding client-side JavaScript SDK configuration in my .net MVC project ( default MVC project created by visual studio 2019).
Post adding the snippet based setup(that you have shared above) in _Layoutcs.html under <head> section we are able to see the browser based client metrics without any issue.
Here is the sample output for reference:
Errors array which says "Telemetry Sampled Out" and due to this I am
unable to see any log in application insights on Azure portal.
Sampling not an error. It is turned on by default in many scenarios. For JavaScript you can configure sampling as outlined here
It could also be that you hit the daily data cap:
When you create an Application Insights resource in the Azure portal, the daily cap is set to 100 GB/day. When you create an Application Insights resource in Visual Studio, the default is small (only 32.3 MB/day).
I suspect it is the latter, as when sampling is turned on using the sdk you wouldn't see it cross the wire. Please see this doc describing how to adjust the cap.
For more information about the error Telemetry Sampled Out you can refer this SO thread.

Related

Google Auth OAuth 2.0 SvelteKit wierd behavior

I am using Google Auth OAuth 2.0 One Tap Sign and Sveltekit,
and I got some really weird behavior,
I followed this doc https://developers.google.com/identity/gsi/web/guides/overview with javascript
onMount(async () => {
const handleCredentialResponse = async (response) => {
console.log('Encoded JWT ID token: ' + response.credential);
};
google.accounts.id.initialize({
client_id: clientId,
callback: handleCredentialResponse,
});
google.accounts.id.renderButton(
document.getElementById('buttonDiv'),
{ theme: 'outline', size: 'large' } // customization attributes
);
google.accounts.id.prompt();
});
the code from the doc.
Sometimes it works everything goes well,
Sometimes I got
Uncaught (in promise) ReferenceError: google is not defined
And some mobile / mobile browsers I get
[GSI_LOGGER]: The given origin is not allowed for the given client ID.
but works on laptop
Hope someone can understand and help.
Do we have any way to check logs for investigation?
I got your code to successfully run without modification: https://google-signin-kit.vercel.app/ (This app is in "dev" mode so signin may only succeed with my Google account. If you clone my repo and set your Google client id, signin will work for you.)
I would check how my code is different from your code outside onMount(). For example, how did you include the Google javascript? I describe one major change below.
You also need to check your Google app settings. [GSI_LOGGER]: The given origin is not allowed... is fixed by adding the HTTPS app domain to your Google app "Authorized JavaScript origins." Non-HTTPS domains are not allowed. For example, these domains would not work:
https://google-signin-kit-leftium.vercel.app/ (Not added as Authorized JavaScript origin)
http://google-signin-kit.vercel.app/ (Not HTTPS, if Vercel did not automatically redirect to HTTPS)
Of course, raw IP addresses will not work, either.
localhost is a special exception, but not easy (impossible?) to access from mobile.
ReferenceError: google is not defined (sometimes) happens because onMount() runs before the Google script is loaded.
To get a consistent reproduction, USB debug/inspect Android Chrome and set "disable caching" and throttling to "Slow 3G." (I could not reproduce on desktop Chrome).
Fixed by removing defer async when including Google's script: <script src="https://accounts.google.com/gsi/client"></script>
It should also be possible to call a function after the script is loaded, but I got inconsistent results in SvelteKit. For some reason Kit doesn't always call the load function. Possibly a bug?
Ideally, the Google script should be imported, but I couldn't find a version of the Google script that was built for importing. You may be able to construct a library that you can import? Importing would compile the Google script code into your app, tree-shaking the unused portions. Thus saving a network request and bandwidth.
Another workaround is to have your onMount function check for the google variable. If google is still undefined, call your function again after a certain timeout.

Window is not defined when doing gatsby build

I'm trying to integrate amplitude-js with React and Gatsby. Everything looks good when doing gatsby developer since it's happening inside the browser, but when I try gatsby build I get the following error because Gatsby build is happening on the server where we don't have window object:
WebpackError: window is not defined
amplitude.js:2428
~/amplitude-js/amplitude.js:2428:2
Here is my amplitude module:
import amplitude from 'amplitude-js';
amplitude.getInstance().init('API-KEY', null, {
// optional configuration options
saveEvents: true,
includeUtm: true,
includeReferrer: true,
});
Gatsby build is not working: window is not defined.
If if I'm not using this part anywhere in a project error is pointing to this part:
if (windowLocalStorageAvailable()) {
localStorage = window.localStorage;
} else if (window.globalStorage) { // <- here
// Firefox 2-3 use globalStorage
// See https://developer.mozilla.org/en/dom/storage#globalStorage
try {
This error happens because Amplitude JS SDK expects to be inside browser window object and have access to window context to collect properties like IP address, OS, Browser, device_id from the cookie, etc from it.
Does your app any type of backend you could sent events from?
To send data to Amplitude you are not required to use Amplitude SDK you have REST endpoint as well.
https://help.amplitude.com/hc/en-us/articles/360032842391-HTTP-API-V2
HTTP API also has 3rd party maintained nodejs wrapper https://github.com/crookedneighbor/amplitude

localStorage access between two google app scripts deployed as web apps

I am trying to handover a string from GAS_web_app_A to GAS_web_app_B. GAS_web_app_B gets launched from a button on GAS_web_app_A's UI.
As localStorage is supposed to be accessible across the same origin, I stored 'stuff' from GAS_web_app_A and tried to read it from GAS_web_app_B - in the same browser - chrome.
But GAS_web_app_B is not able to read this 'stuff' stored by GAS_web_app_A.
1) do all google app scripts that are deployed as a web apps get resolved by browser's localStorage as being from the same origin?
step 1 : launch GAS_web_app_A via its URL - https: //script.google.com/a/macros/XXXX.com/s//dev
step 2 : localStorage.setItem("stuff", stuff);
step 3 : launch GAS_web_app_B via its URL - https: //script.google.com/a/macros/XXXX.com/s//dev (from GAS_web_app_A)
step 4 : console.log( 'stuff is ' + localStorage.getItem("stuff") );
I always get null in step 4. ( I am able to retrieve 'stuff' from GAS_web_app_A even after a reload though... )
Is this supposed to work or am I missing something trivial?
absolutely not supposed to work. it would be a huge security issue. look into passing url parameters to the 2nd script.

Chrome extensions for silent print?

I have made a silent print web application that prints a PDF file. The key was to add JavaScript to the PDF file that silently print itself.
To do this I open the PDF with acrobat reader in chrome, that allow me to execute the script (with the proper permissions).
But as it was announced this solution won't work after chrome 45 because the npapi issue.
I guess a possible solution could be to use the recently release printProvider of chrome extensions.
Nevertheless I can't imagine how to fire any of the printProvider events.
So the question is: Is ok to think in chrome extensions to make a silent print web application, and how can I fire and handle a print job for an embedded PDF of a HTML Page.
Finally I reached an acceptable solution for this problem, as I couldn't find it out there, but read to many post with the same issue I will leave my solution here.
So first you need to add your printer to the Google Cloud Print and then you will need to add a proyect to the Google Developers Console
Then add this script and any time you need to print something execute the print() function. This method will print the document indicated in the content
The application will ask for your permission once to manage your printers.
function auth() {
gapi.auth.authorize({
'client_id': 'YOUR_GOOGLE_API_CLIENT_ID',
'scope': 'https://www.googleapis.com/auth/cloudprint',
'immediate': true
});
}
function print() {
var xhr = new XMLHttpRequest();
var q = new FormData()
q.append('xsrf', gapi.auth.getToken().access_token);
q.append('printerid', 'YOUR_GOOGLE_CLOUD_PRINTER_ID');
q.append('jobid', '');
q.append('title', 'silentPrintTest');
q.append('contentType', 'url');
q.append('content',"http://www.pdf995.com/samples/pdf.pdf");
q.append('ticket', '{ "version": "1.0", "print": {}}');
xhr.open('POST', 'https://www.google.com/cloudprint/submit');
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.auth.getToken().access_token);
xhr.onload = function () {
try {
var r = JSON.parse(xhr.responseText);
console.log(r.message)
} catch (e) {
console.log(xhr.responseText)
}
}
xhr.send(q)
}
window.addEventListener('load', auth);
<script src="https://apis.google.com/js/client.js"></script>
Anyway this script throw a 'Access-Control-Allow-Origin' error, even though this appears in the documentation... I couldn't make it work :(
Google APIs support requests and responses using Cross-origin Resource Sharing (CORS). You do not need to load the complete JavaScript client library to use CORS. If you want your application to access a user's personal information, however, it must still work with Google's OAuth 2.0 mechanism. To make this possible, Google provides the standalone auth client — a subset of the JavaScript client.
So to go throw this I had to install this chrome extension CORS. I'm sure that some one will improve this script to avoid this chrome extension.
You can register an Application to a URI Scheme to trigger the local application to print silently. The setting is pretty easy and straightforward. It's a seamless experience. I have posted the solution here with full example:
https://stackoverflow.com/a/37601807/409319
After the removal of npapi, I don't believe this is possible solely programmatically. The only current way I know to get chrome to print silently is using chrome kiosk mode, which is a flag (mode) you have to set when starting chrome.
Take a look at these SO posts:
Silent printing (direct) using KIOSK mode in Google Chrome
Running Chrome with extension in kiosk mode
This used to be possible using browser plugins (e.g. Java + NPAPI, ActiveX) but has been blacklisted by most browsers for several years.
If interested in modern solutions that use similar techniques, the architecture usually requires the following:
WebSocket, HTTP or Custom URI connection back to localhost
API that talks through web transport (JavaScript or custom URI scheme) to an app running locally.
A detail of projects (several of them are open source) that leverage these technologies are available here:
https://stackoverflow.com/a/28783269/3196753
Since the source code of these projects can vary (hundreds of lines to tens-of-thousands of lines), a code snippet would be too large unless a inquiring about a specific project's API.
Side note: Some technologies offer dedicated cloud resources, which add convenience at the expense of potential latency and privacy. At the time of writing this, the most popular "free" cloud solution -- Google Cloud Print -- is slated to be retired in December 2020.

DOM exception error 11 on swapCache()

I am playing with an application cache and having problems with the swapCache function.
I have created the world's simplest cache manifest file:
CACHE MANIFEST
# Timestamp: 2013-03-01 11:28:49
CACHE:
media/myImage.png
NETWORK:
*
Running the application for the 1st time gives me this in the console:
Creating Application Cache with manifest http://blah_blah/offline.appcache
Application Cache Checking event
Application Cache Downloading event
Application Cache Progress event (0 of 1) http://blah_blah/media/myImage.png
Application Cache Progress event (1 of 1)
Application Cache Cached event
All well so far. Then I swap out the image and change the timestamp in the manifest file and get the following:
Adding master entry to Application Cache with manifest http://blah_blah/offline.appcache
Application Cache Downloading event
Application Cache Progress event (0 of 2) http://blah_blah/media/myImage.png
Application Cache Progress event (1 of 2) http://blah_blah/Widget/?invoke=myWidgetFunctionName
Application Cache Progress event (2 of 2)
Application Cache UpdateReady event
At which point the applicationCache.swapCache() function is called giving me a DOM exception 11 error.
MIME types all correctly configured on the webserver.
Anyone got any ideas / can point me in the right direction?
(I have read all the commonly linked appcache stuff online and can't see what am I doing wrong)
Thanks!
EDIT:
As I mentioned in the comments below, setting the expires headers on my web server for *.appcache files to expire immediately seems to have it working although I am still getting the DOM exception error(!?). I found the following blog entry which may help:
Possible Fix for Offline App Cache INVALIDSTATEERR
...but I have no idea how to set the MIME types client side. My google-Fu skillz have deserted me. Anyone?
I had the same issue. For a while I just disabled the cache if the browser was not chrome, but then I decided to try again, setting the mime-type as suggested. Firefox no longer throws an exception when I call swapCache(), and the whole refreshing process now works as expected. The mime-type has to be set server-side since the request isn't initiated from your web page, but the browser, so you have no control over how it reads the response. You have a couple options here. If you are using apache or IIS, you can do as koko suggested. If you are using a framework that handles routing for you and you configure the mapping of URLs to responses, such as rails or a python wsgi server, then you can typically set the content type manually. Here is my snippet of what I am using in my Python app using Bottle.py (WSGI based):
# BEFORE
#bottle.route(r"/<path:re:.+\.(manifest|appcache)>", auth=False)
def serve_cache_manifest(path):
return bottle.static_file(path, SITE_DIR)
# AFTER
#bottle.route(r"/<path:re:.+\.(manifest|appcache)>", auth=False)
def serve_cache_manifest(path):
return bottle.static_file(path, SITE_DIR, mimetype='text/cache-manifest')
Bottle comes with a utility function that handles returning static files that I am using. It has an optional parameter to set the mime-type.
tl;dr If you can't add the mime-type to your server configuration, you can almost always set it in your server side code (if you have
any).
I would suggest trying to comment out the catchall NETWORK whitelist.
NETWORK:
# *
The * would seem to require network access for all file, according to
https://developer.mozilla.org/en-US/docs/HTML/Using_the_application_cache
I commented out all NETWORK entries for now for a simple web application of mine and it works well.

Categories

Resources