Skip to content

Instantly share code, notes, and snippets.

@bradyclifford
Last active August 25, 2021 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradyclifford/ef76b94a0f8edc9bef914935824d5c82 to your computer and use it in GitHub Desktop.
Save bradyclifford/ef76b94a0f8edc9bef914935824d5c82 to your computer and use it in GitHub Desktop.
Application Insights
<% if (htmlWebpackPlugin.options.applicationInsightsInstrumentationKey) { %>
<!-- AppInsights -->
<!-- Intended to be blocking, don't defer or load async -->
<script type="text/javascript">
<%
// https://docs.microsoft.com/en-us/azure/azure-monitor/app/javascript
const {applicationInsightsInstrumentationKey: instrumentationKey, appInsights: props = {}} = htmlWebpackPlugin.options;
const { role, roleInstance, version, onInit, onAfterInit, cfg, ...rest} = props;
if (!instrumentationKey)
throw new TypeError('Application Insights Instrumentation key required');
const setup = {
src: 'https://js.monitor.azure.com/scripts/b/ai.2.min.js',
ld: -1, // block page load and add to head
crossOrigin: 'anonymous',
cfg: {
instrumentationKey,
// Setup Distributed Tracing
// https://docs.microsoft.com/en-us/azure/azure-monitor/app/javascript#enable-correlation
distributedTracingMode: 2, // DistributedTracingModes.W3C
disableFetchTracking: false,
enableCorsCorrelation: true,
enableRequestHeaderTracking: true,
enableResponseHeaderTracking: true,
// https://docs.microsoft.com/en-us/azure/azure-monitor/app/javascript#enable-time-on-page-tracking
autoTrackPageVisitTime: true,
// https://docs.microsoft.com/en-us/azure/azure-monitor/app/javascript#single-page-applications
// Disable if React npm solution implemented
enableAutoRouteTracking: true,
...(cfg || {})
},
...(rest || {})
};
%>
(function() {
var setup = <%= JSON.stringify(setup) %>;
var instrumentationKey = setup.cfg.instrumentationKey;
if(!instrumentationKey || /^#{.*}$/gs.test(instrumentationKey)) {
(console || {error: function () {}}).error('%cAppInsights:\n%c instrumentation key missing or not substituted [%s] ',
'font-weight: bold; font-size: 1.5em; line-height: 2em;',
'font-weight: normal', instrumentationKey);
return;
}
function defaultInitHandler(instance) {
(console || {debug: function () {}}).debug('AppInsights Initialized: Distributed Tracing enabled for domains [%s]',
instance.config.correlationHeaderDomains && instance.config.correlationHeaderDomains.join(','));
instance.addTelemetryInitializer(function (envelope) {
envelope.tags['ai.cloud.role'] = '<%= role %>';
<% if (version) { %>
envelope.tags['ai.application.ver'] = '<%= version %>';
<% } %>
<% if (roleInstance) { %>
envelope.tags['ai.cloud.roleInstance'] = '<%= roleInstance %>';
<% } %>
});
try {
<% if (onAfterInit) { %>
(<%= require('@mktp/screen/templates/webpack/fragment-loader.js')(onAfterInit, { htmlWebpackPlugin }) %>)(instance);
<% } %>
}
catch(error) {
console.verbose('AppInsights: onAfterInit error', error);
}
}
setup.onInit = <%= onInit ? require('@mktp/screen/templates/webpack/fragment-loader.js')(onInit, { htmlWebpackPlugin }) : 'defaultInitHandler' %>;
setup.cfg.correlationHeaderDomains = <%
const { correlationHeaderDomains } = setup.cfg || {};
if (!correlationHeaderDomains) { %>
[window.location.hostname]
<% } else { %>
<%= Array.isArray(correlationHeaderDomains) ? JSON.stringify(correlationHeaderDomains) : correlationHeaderDomains %>
<% } %>;
<% if (!setup.cfg.cookieDomain ) { %>
setup.cfg.cookieDomain = window.location.hostname.split('.')
.slice(-2)
.join('.');
<% } %>
// Snippet Version 5
// https://docs.microsoft.com/en-us/azure/azure-monitor/app/javascript#snippet-based-setup
!(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, setup);
})();
</script>
<!-- End AppInsights -->
<% } %>

Add the template to the webpack extraHeadContent property exposed by im-screens template.

Note that the Customization team will be creating a webpack plugin instead https://github.com/im-client/participant-guidance/issues/37

new HtmlWebpackPlugin(
  {
    ...
    appInsights: {
      role: clientCode,
      version,
      cfg: {
        // Not required
        loggingLevelConsole: isModeDev ? 2 : 0,
        loggingLevelTelemetry: isModeDev ? 2 : 1,
        maxBatchSizeInBytes: isModeDev ? 0 : 10000
      },
      
      // Adds content to the onInit method provided by Application Insights
      onAfterInit: readFileSync(
        resolve(publicDir, './fragments/preload-household.js')
      ).toString()
    },
    
    applicationInsightsInstrumentationKey: enableLogging
      ? applicationInsightsInstrumentationKey
      : undefined,
      
    /* 
       Inject App Insights snippet into head, at the top.  
       It's important to be at the top because it will track all loads.
    */
    extraHeadContent: readFileSync(resolve(publicDir, './fragments/app-insights.ejs'))
      .toString(),
    ...
  }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment