skip to Main Content

I have set up NLog to work with Applicatin Insights and also log js exceptions and is working as required. However, I am struggling with making the instrumentation key dynamic so it targets the environment specific application insight instance.

NLog config target

<target name="aiTarget" xsi:type="ApplicationInsightsTarget"
     layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}">
      <instrumentationKey>"mydevappinsightinstrumentationkey"</instrumentationKey>
      <contextproperty name="threadid" layout="${threadid}" />
    </target>

Layout cshtm for JS exceptions

<script type="text/javascript">
        !function (v, y, T) { var S = v.location, k = "script", D = "instrumentationKey", C = "ingestionendpoint", I = "disableExceptionTracking", E = "ai.device.", b = "toLowerCase", w = (D[b](), "crossOrigin"), N = "POST", e = "appInsightsSDK", t = T.name || "appInsights", n = ((T.name || v[e]) && (v[e] = t), v[t] || function (l) { var u = !1, d = !1, g = { initialize: !0, queue: [], sv: "6", version: 2, config: l }; function m(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_" + (g.sv || g.version), { time: (a = new Date).getUTCFullYear() + "-" + i(1 + a.getUTCMonth()) + "-" + i(a.getUTCDate()) + "T" + i(a.getUTCHours()) + ":" + i(a.getUTCMinutes()) + ":" + i(a.getUTCSeconds()) + "." + (a.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 } } }; function i(e) { e = "" + e; return 1 === e.length ? "0" + e : e } } var e, n, f = l.url || T.src; function a(e) { var t, n, a, i, o, s, r, c, p; u = !0, g.queue = [], d || (d = !0, i = f, r = (c = function () { var e, t = {}, n = l.connectionString; if (n) for (var a = n.split(";"), i = 0; i < a.length; i++) { var o = a[i].split("="); 2 === o.length && (t[o[0][b]()] = o[1]) } return t[C] || (t[C] = "https://" + ((e = (n = t.endpointsuffix) ? t.location : null) ? e + "." : "") + "dc." + (n || "services.visualstudio.com")), t }()).instrumentationkey || l[D] || "", c = (c = c[C]) ? c + "/v2/track" : l.endpointUrl, (p = []).push((t = "SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)", n = i, o = c, (s = (a = m(r, "Exception")).data).baseType = "ExceptionData", s.baseData.exceptions = [{ typeName: "SDKLoadFailed", message: t.replace(/./g, "-"), hasFullStack: !1, stack: t + "nSnippet failed to load [" + n + "] -- Telemetry is disablednHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109nHost: " + (S && S.pathname || "_unknown_") + "nEndpoint: " + o, parsedStack: [] }], a)), p.push((s = i, t = c, (o = (n = m(r, "Message")).data).baseType = "MessageData", (a = o.baseData).message = 'AI (Internal): 99 message:"' + ("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) (" + s + ")").replace(/"/g, "") + '"', a.properties = { endpoint: t }, n)), i = p, r = c, JSON && ((o = v.fetch) && !T.useXhr ? o(r, { method: N, body: JSON.stringify(i), mode: "cors" }) : XMLHttpRequest && ((s = new XMLHttpRequest).open(N, r), s.setRequestHeader("Content-type", "application/json"), s.send(JSON.stringify(i))))) } function i(e, t) { d || setTimeout(function () { !t && g.core || a() }, 500) } f && ((n = y.createElement(k)).src = f, !(o = T[w]) && "" !== o || "undefined" == n[w] || (n[w] = o), n.onload = i, n.onerror = a, n.onreadystatechange = function (e, t) { "loaded" !== n.readyState && "complete" !== n.readyState || i(0, t) }, e = n, T.ld < 0 ? y.getElementsByTagName("head")[0].appendChild(e) : setTimeout(function () { y.getElementsByTagName(k)[0].parentNode.appendChild(e) }, T.ld || 0)); try { g.cookie = y.cookie } catch (h) { } function t(e) { for (; e.length;)!function (t) { g[t] = function () { var e = arguments; u || g.queue.push(function () { g[t].apply(g, e) }) } }(e.pop()) } var s, r, o = "track", c = "TrackPage", p = "TrackEvent", o = (t([o + "Event", o + "PageView", o + "Exception", o + "Trace", o + "DependencyData", o + "Metric", o + "PageViewPerformance", "start" + c, "stop" + c, "start" + p, "stop" + p, "addTelemetryInitializer", "setAuthenticatedUserContext", "clearAuthenticatedUserContext", "flush"]), g.SeverityLevel = { Verbose: 0, Information: 1, Warning: 2, Error: 3, Critical: 4 }, (l.extensionConfig || {}).ApplicationInsightsAnalytics || {}); return !0 !== l[I] && !0 !== o[I] && (t(["_" + (s = "onerror")]), r = v[s], v[s] = function (e, t, n, a, i) { var o = r && r(e, t, n, a, i); return !0 !== o && g["_" + s]({ message: e, url: t, lineNumber: n, columnNumber: a, error: i, evt: v.event }), o }, l.autoExceptionInstrumented = !0), g }(T.cfg)); function a() { T.onInit && T.onInit(n) } (v[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",

            crossOrigin: "anonymous",

            cfg: {
                connectionString: "InstrumentationKey=mydevappinsightinstrumentationkey;IngestionEndpoint=mydevappinsightingestionendpoint"
            }

        });

        window.appInsights = appInsights;
        appInsights.trackPageView();
        try {
            throw new Error("Logging Exception from Javascript");
        } catch (error) {
            appInsights.trackException("Logging Exception from Javascript.");
            appInsights.trackException({ error });
        }
    </script>

How do I make the instrumentation key dynamic in the above scenarios?

2

Answers


  1. Chosen as BEST ANSWER

    For Layout cshtml you can do the following:

    @using Microsoft.Extensions.Configuration
    @inject IConfiguration Configuration
    
    connectionString: @Json.Serialize(Configuration.GetSection("ApplicationInsights")["ConnectionString"])
    

    In my azure app service configuration, appsetting name is present in the following format: ApplicationInsights:ConnectionString and if reading from appsettings.json it should be in the following format:

    "ApplicationInsights": {
        "ConnectionString": "your app insight connection string here"
      }
    

    In Nlog config if you want to make the instrumentation key dynamic

    ${configsetting:item=ApplicationInsights.InstrumentationKey}

    So your target will become:

    <target name="aiTarget" xsi:type="ApplicationInsightsTarget"
         layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}">
          <instrumentationKey>${configsetting:item=ApplicationInsights.InstrumentationKey}</instrumentationKey>
          <contextproperty name="threadid" layout="${threadid}" />
        </target>
    

    Again ensure the same set up for app service configuration or appsetting json as I have shown in layout cshtml solution, only difference you will have is InstrumentationKey instead of ConnectionString


  2. The instrumentation key can be set to dynamic so it targets the environment-specific application insight instance like below.

    const config = require('config');
    const appInsights = require('applicationinsights');
    
    // Determine the environment (development, production, etc.)
    const environment = process.env.NODE_ENV || 'development';
    
    // Get the instrumentation key from the configuration based on the environment
    const instrumentationKey = config.get('appInsightsInstrumentationKey');
    
    // Initialize Application Insights with the dynamic instrumentation key
    appInsights
      .setup(instrumentationKey)
      .start();
    
    
    • Install npm install applicationinsights config
      mkdir config
    • Create a config directory within your project to store environment-specific configuration files.

    mkdir config

    Configure Application Insights

    In your Azure portal, create an Application Insights resource if you haven’t already. You’ll need the instrumentation key for this resource.

    Create Configuration Files

    Inside the config directory, create two configuration files: development.json and production.json. Replace "YOUR_DEVELOPMENT_INSTRUMENTATION_KEY" and "YOUR_PRODUCTION_INSTRUMENTATION_KEY" with your actual instrumentation keys.

    development.json

    {
    
    "appInsightsInstrumentationKey_development":  "key "
    
    }
    
    • Run set NODE_ENV=development in bash and run the code.

    In Layout cshtm for JS:

    @{
        string instrumentationKey = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");
    }
    
    <script type="text/javascript">
        !function (v, y, T) {
        
                };
    
                // Rest of your script here...
    
                function a() {
                    T.onInit && T.onInit(n)
                }
    
                (v[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",
                crossOrigin: "anonymous",
                cfg: {
                    connectionString: "InstrumentationKey=" + @instrumentationKey + ";IngestionEndpoint=mydevappinsightingestionendpoint"
                }
            });
    
            window.appInsights = appInsights;
            appInsights.trackPageView();
            try {
                throw new Error("Logging Exception from Javascript");
            } catch (error) {
                appInsights.trackException("Logging Exception from Javascript.");
                appInsights.trackException({ error });
            }
        }(window, document, {});
    </script>
    

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search