IvanJosipovic / BlazorApplicationInsights

Application Insights for Blazor web applications

Home Page:https://BlazorApplicationInsights.netlify.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug when combining Serilog

vertonghenb opened this issue ยท comments

  • Blazor Type: Blazor WASM Standalone
  • .NET 8

When combining BlazorApplicationInsights with Serilog in a Blazor WASM Standalone, the module is loaded too late and results in an exception on load. A full reproduction can be found here: https://github.com/vertonghenb/AnalyticsBug based on the steps below.

Possible solution:
Use JavaScript initializers so that the module is always loaded and initialised before Blazor even starts. The first thing we want to do is track the analytics, since when something goes wrong we have an exception for it in the logs. I think it's worthwhile to consider initialising BlazorAnalytics before the App actually starts. This can be done based on the article:
https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/startup?view=aspnetcore-8.0#javascript-initializers
and using a BlazorApplicationInsights.lib.module.js in the wwwroot folder in the base package

Steps to reproduce

Create a new Blazor WASM Standalone (.NET8)

dotnet new blazorwasm

Adding Serilog.BrowserConsole

dotnet add package Serilog.Sinks.BrowserConsole --version 2.0.0

Program.cs

Log.Logger = new LoggerConfiguration()
    .WriteTo.BrowserConsole()
    .CreateLogger();

Log.Information("Hello, browser!");

Adding BlazorApplicationInsights

dotnet add package BlazorApplicationInsights --version 3.0.4

Program.cs

Key is the same as the WASM Example is this repo.

dotnet add package BlazorApplicationInsights
builder.Services.AddBlazorApplicationInsights(config =>
{
    config.ConnectionString = "InstrumentationKey=219f9af4-0842-42c8-a5b1-578f09d2ee27;IngestionEndpoint=https://westus2-0.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/";
},
async applicationInsights =>
{
    var telemetryItem = new TelemetryItem()
    {
        Tags = new Dictionary<string, object?>()
        {
            { "ai.cloud.role", "SPA" },
            { "ai.cloud.roleInstance", "Blazor Wasm" },
        }
    };

    await applicationInsights.AddTelemetryInitializer(telemetryItem);
});

_imports.razor

@using BlazorApplicationInsights;

App.razor (top of file)

<ApplicationInsightsInit IsWasmStandalone="true" />

index.htnl (head)

<script type="text/javascript">
  !(function (cfg){function e(){cfg.onInit&&cfg.onInit(i)}var S,u,D,t,n,i,C=window,x=document,w=C.location,I="script",b="ingestionendpoint",E="disableExceptionTracking",A="ai.device.";"instrumentationKey"[S="toLowerCase"](),u="crossOrigin",D="POST",t="appInsightsSDK",n=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=n),i=C[n]||function(l){var d=!1,g=!1,f={initialize:!0,queue:[],sv:"7",version:2,config:l};function m(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[A+"id"]=i[S](),n[A+"type"]=i,n["ai.operation.name"]=w&&w.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(f.sv||f.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:4,seq:"1",aiDataContract:undefined}}var h=-1,v=0,y=["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"],k=l.url||cfg.src;if(k){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~k.indexOf("ai.3")&&(k=k.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<y.length;e++)if(0<k.indexOf(y[e])){h=e;break}var i=function(e){var a,t,n,i,o,r,s,c,p,u;f.queue=[],g||(0<=h&&v+1<y.length?(a=(h+v+1)%y.length,T(k.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+y[a]+i})),v+=1):(d=g=!0,o=k,c=(p=function(){var e,t={},n=l.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][S]()]=o[1])}return t[b]||(e=(n=t.endpointsuffix)?t.location:null,t[b]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||l.instrumentationKey||"",p=(p=p[b])?p+"/v2/track":l.endpointUrl,(u=[]).push((t="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",n=o,r=p,(s=(i=m(c,"Exception")).data).baseType="ExceptionData",s.baseData.exceptions=[{typeName:"SDKLoadFailed",message:t.replace(/\./g,"-"),hasFullStack:!1,stack:t+"\nSnippet failed to load ["+n+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(w&&w.pathname||"_unknown_")+"\nEndpoint: "+r,parsedStack:[]}],i)),u.push((s=o,t=p,(r=(n=m(c,"Message")).data).baseType="MessageData",(i=r.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+s+")").replace(/\"/g,"")+'"',i.properties={endpoint:t},n)),o=u,c=p,JSON&&((r=C.fetch)&&!cfg.useXhr?r(c,{method:D,body:JSON.stringify(o),mode:"cors"}):XMLHttpRequest&&((s=new XMLHttpRequest).open(D,c),s.setRequestHeader("Content-type","application/json"),s.send(JSON.stringify(o))))))},a=function(e,t){g||setTimeout(function(){!t&&f.core||i()},500),d=!1},T=function(e){var n=x.createElement(I),e=(n.src=e,cfg[u]);return!e&&""!==e||"undefined"==n[u]||(n[u]=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?x.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){x.getElementsByTagName(I)[0].parentNode.appendChild(n)},cfg.ld||0),n};T(k)}try{f.cookie=x.cookie}catch(p){}function t(e){for(;e.length;)!function(t){f[t]=function(){var e=arguments;d||f.queue.push(function(){f[t].apply(f,e)})}}(e.pop())}var r,s,n="track",o="TrackPage",c="TrackEvent",n=(t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+o,"stop"+o,"start"+c,"stop"+c,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),f.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(l.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==l[E]&&!0!==n[E]&&(t(["_"+(r="onerror")]),s=C[r],C[r]=function(e,t,n,i,a){var o=s&&s(e,t,n,i,a);return!0!==o&&f["_"+r]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},l.autoExceptionInstrumented=!0),f}(cfg.cfg),(C[n]=i).queue&&0===i.queue.length?(i.queue.push(e),i.trackPageView({})):e();})({
      src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
      ld: -1,
      crossOrigin: "anonymous",
      cfg: {
          instrumentationKey: "00000000-0000-0000-0000-000000000000",
          disableTelemetry: true
      }
  });
</script>

Add Logger on page

Home.razor.cs

    [Inject] public required IApplicationInsights AppInsights { get; set; }

    protected override void OnInitialized()
    {
        Log.Information("Hello from Home");
        Log.Warning("Warning");
        Log.Error("Error");
        Log.Fatal("Fatal");
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {
            await AppInsights.TrackEvent(new EventTelemetry { Name = "FeaturePage" });
            await AppInsights.TrackMetric(new MetricTelemetry { Name = "FeaturePage", Average = 1 });
        }
    }

Run the project shows the exception

blazor.webassembly.js:1 
 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not find 'blazorApplicationInsights.addTelemetryInitializer' ('blazorApplicationInsights' was undefined).
      Error: Could not find 'blazorApplicationInsights.addTelemetryInitializer' ('blazorApplicationInsights' was undefined).
          at https://localhost:7115/_framework/blazor.webassembly.js:1:368
          at Array.forEach (<anonymous>)
          at l.findFunction (https://localhost:7115/_framework/blazor.webassembly.js:1:336)
          at w (https://localhost:7115/_framework/blazor.webassembly.js:1:5079)
          at https://localhost:7115/_framework/blazor.webassembly.js:1:2872
          at new Promise (<anonymous>)
          at b.beginInvokeJSFromDotNet (https://localhost:7115/_framework/blazor.webassembly.js:1:2835)
          at Object.gn [as invokeJSJson] (https://localhost:7115/_framework/blazor.webassembly.js:1:58932)
          at https://localhost:7115/_framework/dotnet.runtime.8.0.2.gggw4qpwdt.js:3:177853
          at Ul (https://localhost:7115/_framework/dotnet.runtime.8.0.2.gggw4qpwdt.js:3:178687)
Microsoft.JSInterop.JSException: Could not find 'blazorApplicationInsights.addTelemetryInitializer' ('blazorApplicationInsights' was undefined).
Error: Could not find 'blazorApplicationInsights.addTelemetryInitializer' ('blazorApplicationInsights' was undefined).
    at https://localhost:7115/_framework/blazor.webassembly.js:1:368
    at Array.forEach (<anonymous>)
    at l.findFunction (https://localhost:7115/_framework/blazor.webassembly.js:1:336)
    at w (https://localhost:7115/_framework/blazor.webassembly.js:1:5079)
    at https://localhost:7115/_framework/blazor.webassembly.js:1:2872
    at new Promise (<anonymous>)
    at b.beginInvokeJSFromDotNet (https://localhost:7115/_framework/blazor.webassembly.js:1:2835)
    at Object.gn [as invokeJSJson] (https://localhost:7115/_framework/blazor.webassembly.js:1:58932)
    at https://localhost:7115/_framework/dotnet.runtime.8.0.2.gggw4qpwdt.js:3:177853
    at Ul (https://localhost:7115/_framework/dotnet.runtime.8.0.2.gggw4qpwdt.js:3:178687)
   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[Microsoft.JSInterop.Infrastructure.IJSVoidResult, Microsoft.JSInterop, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
   at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
   at BlazorApplicationInsights.ApplicationInsights.AddTelemetryInitializer(TelemetryItem telemetryItem)
   at Program.<>c.<<<Main>$>b__0_2>d.MoveNext() in /Users/benjamin/Desktop/AnalyticsBug/Program.cs:line 28
--- End of stack trace from previous location ---
   at BlazorApplicationInsights.ApplicationInsightsInit.OnAfterRenderAsync(Boolean firstRender)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

๐ŸŽ‰ This issue has been resolved in version 3.0.5 ๐ŸŽ‰

The release is available on GitHub release

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€