ApplicationInsights真的是一款非常强大的应用监控利器。 它可以为你记录下站点接口的请求数量与性能,依赖项性能,调用链的异常以及堆栈跟踪信息等等。ApplicationInsights不仅可以用于服务端监控,还可以用于记录浏览器信息。
省去了开发人员繁琐的日志记录以及遇到Bug时的无端猜测,科技是第一生产力。
在此,我主要讲述ApplicationInsights在Blazor中的应用方法。
很简单,首先在wwwroot文件夹中的index.html页面中,添加JavaScript SDK
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>ClientSideTemplate</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss"></a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script type="text/javascript">
function insightInit(object) {
var S = window.location, u = "script", k = "instrumentationKey", D = "ingestionendpoint", C = "disableExceptionTracking", E = "ai.device.", I = "toLowerCase", b = "crossOrigin", w = "POST", e = "appInsightsSDK", t = object.name || "appInsights";
(object.name || window[e]) && (window[e] = t);
var n = window[t] || function (d) { var g = !1, f = !1, m = { initialize: !0, queue: [], sv: "4", version: 2, config: d }; function v(e, t) { var n = {}, a = "Browser"; return n[E + "id"] = a[I](), 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 || object.src; if (h) { function a(e) { var t, n, a, i, r, o, s, c, p, l, u; 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][I]()] = i[1]) } if (!e[D]) { var r = e.endpointsuffix, o = r ? e.location : null; e[D] = "https://" + (o ? o + "." : "") + "dc." + (r || "services.visualstudio.com") } return e }(), c = s[k] || d[k] || "", p = s[D], l = p ? p + "/v2/track" : config.endpointUrl, (u = []).push((n = "SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)", a = t, i = l, (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)), u.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, l)), function (e, t) { if (JSON) { var n = window.fetch; if (n && !object.useXhr) n(t, { method: w, body: JSON.stringify(e), mode: "cors" }); else if (XMLHttpRequest) { var a = new XMLHttpRequest; a.open(w, t), a.setRequestHeader("Content-type", "application/json"), a.send(JSON.stringify(e)) } } }(u, l)) } function i(e, t) { f || setTimeout(function () { !t && m.core || a() }, 500) } var e = function () { var n = document.createElement(u); n.src = h; var e = object[b]; return !e && "" !== e || "undefined" == n[b] || (n[b] = e), n.onload = i, n.onerror = a, n.onreadystatechange = function (e, t) { "loaded" !== n.readyState && "complete" !== n.readyState || i(0, t) }, n }(); object.ld < 0 ? document.getElementsByTagName("head")[0].appendChild(e) : setTimeout(function () { document.getElementsByTagName(u)[0].parentNode.appendChild(e) }, object.ld || 0) } try { m.cookie = document.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[C] && !0 !== s[C]) { method = "onerror", t(["_" + method]); var c = window[method]; window[method] = function (e, t, n, a, i) { var r = c && c(e, t, n, a, i); return !0 !== r && m["_" + method]({ message: e, url: t, lineNumber: n, columnNumber: a, error: i }), r }, d.autoExceptionInstrumented = !0 } return m }(object.cfg); (window[t] = n).queue && 0 === n.queue.length && n.trackPageView({})
}
</script>
</body>
</html>
与官网上介绍的方式不同,在此我并没有直接加载并执行该javascript脚本,而是将其定义为了一个函数insightInit
。因为,通常ApplicationInsights所需的key是区分运行环境的,也就是不同的运行环境需要使用不同的key。因此,我们需要通过一个服务来获取它,并在程序运行时,调用该顶部js方法。
在此给出一个示例:
public interface IApplicationInsightKeyProvider
{
Task<string> GetApplicationInsightKeyAsync();
}
``
public class DefaultApplicationInsightKeyProvider : IApplicationInsightKeyProvider
{
private readonly IWebAssemblyHostEnvironment _hostEnvironment;
public DefaultApplicationInsightKeyProvider(IWebAssemblyHostEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
}
public Task<string> GetApplicationInsightKeyAsync()
{
//添加你自己的实现
return Task.FromResult(string.Empty);
}
}`
然后在App.razor中添加以下代码:
@code
{
[Inject]
IJSRuntime JsRuntime { get; set; }
[Inject]
IApplicationInsightKeyProvider InsightKeyProvider { get; set; }
protected override async Task OnInitializedAsync()
{
var connStr = await InsightKeyProvider.GetApplicationInsightKeyAsync();
await JsRuntime.InvokeVoidAsync("insightInit", new
{
src = "https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js",
cfg = new { connectionString = connStr }
});
}
}
至此,已完成blazor客户端 Azure ApplicationInsights集成。它会记录下浏览器中页面访问情况,资源加载情况,以及组件异常等。你可以到azure门户中,选择你希望的指标进行查看,切记,需要切换到浏览器模式。https://docs.microsoft.com/zh-cn/azure/azure-monitor/app/javascript#explore-browserclient-side-data