Separare sviluppo e produzione su Application Insights

Abbiamo anticipato in un precedente post che avremmo parlato di questo argomento.

Le problematiche che affronteremo (e risolveremo) sono le seguenti:

  • qualora dovessimo cambiare la risorsa Application Insights da utilizzare in un progetto, dovremmo cambiare la Instrumentation Key sia nel file ApplicationInsights.config che nella _Layout.cshtml
  • i dati inviati in fase di sviluppo e debug su Application Insights saranno “fasulli”, e influenzeranno quindi i dati reali della produzione

Per risolvere entrambi questi problemi, faremo ricorso a due cose:

  • più risorse di Application Insights, quindi nel caso di “sviluppo” e “produzione” avremo bisogno di due risorse
  • codice Razor per caricare, in base allo scenario, la Instrumentation Key giusta

Cominciamo.

Andiamo a creare più risorse Application Insights su Azure

Prima di tutto creiamo tutte le risorse necessarie su Azure, e per farlo andiamo al seguente indirizzo:

https://portal.azure.com

Dal portale di Azure selezioniamo la voce “Resource Groups” e quindi usiamo il tasto “+ Add” per inserire un nuovo gruppo:

IMG09

Assegniamo il nome al gruppo e scegliamo la sottoscrizione Azure da utilizzare, come zona geografica di Application Insights per il momento è possibile scegliere solo “Central US”, dato che questo servizio è ancora in “preview” (anche se di preview ormai non si può più parlare di fatto).

IMG

Nel nostro esempio abbiamo messo il suffisso “_GROUP” al nome del nostro gruppo per una questione di nomenclatura, non è necessario né richiesto da alcuna policy del servizio.

Con lo stesso criterio, userò i suffissi “_DEV” e “_PROD” per indicare i nomi dei profili che saranno destinati, rispettivamente, a “sviluppo e test” e “produzione”.

Per farlo procediamo con la selezione a sinistra della voce “Application Insights” e quindi con il pulsante “+ Add” ancora una volta procediamo con l’inserimento:

IMG

Facciamo attenzione ad assegnare la risorsa che andiamo a creare al gruppo che abbiamo poc’anzi creato:

IMG

Una volta creato la prima risorsa “_DEV”, ripetiamo la stessa operazione per la creazione della seconda risorsa “_PROD”.

Da notare che il gruppo di risorse, seppure non  necessario, ci aiuterà a recuperare velocemente le risorse create per quello specifico progetto per cui, seppure non sia documentato come linea guida, l’approccio indicato è fortemente consigliato (da me).

A questo punto prendiamo nota (ad esempio su un “blocco note”) delle due Instrumentation Key delle due risorse in modo da poterle ricopiare e incollare tra poco nel nostro progetto web.

Utilizziamo le risorse Application Insights in Visual Studio

Che si tratti di un nuovo progetto o di un progetto esistente poco cambia, come avevamo già detto in precedenti post, perché in entrambi i casi le informazioni richieste saranno le stesse.

Nel nostro esempio procediamo con la creazione di un nuovo progetto e scegliamo la risorsa Application Insights denominata “_DEV”.

IMG.png

A questo punto procediamo all’aggiunta dello script JavaScript necessario ad Application Insights, così come spiegato in questo post.

Ci troveremo quindi nella situazione di avere un file ApplicationInsights.config e un file _Layout.cshtml che fanno riferimento alla stessa Instrumentation Key, nel caso specifico quella con il suffisso “_DEV”.

<InstrumentationKey>fca7eaf9-717d-4d86-8d7c-70c7914880b4</InstrumentationKey>
    var appInsights=window.appInsights||function(config){
    function r(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o="script",s=u.createElement(o),i,f;for(s.src=config.url||"//az416426.vo.msecnd.net/scripts/a/ai.0.js",u.getElementsByTagName(o)[0].parentNode.appendChild(s),t.cookie=u.cookie,t.queue=[],i=["Event","Exception","Metric","PageView","Trace"];i.length;)r("track"+i.pop());return r("setAuthenticatedUserContext"),r("clearAuthenticatedUserContext"),config.disableExceptionTracking||(i="onerror",r("_"+i),f=e[i],e[i]=function(config,r,u,e,o){var s=f&&f(config,r,u,e,o);return s!==!0&&t["_"+i](config,r,u,e,o),s}),t
    }({
    instrumentationKey:"fca7eaf9-717d-4d86-8d7c-70c7914880b4"
    });
    window.appInsights=appInsights;
    appInsights.trackPageView();


La strategia che andremo a perseguire sarà la seguente:

  • aggiungere un setting nel Web.config che rappresenti la Instrumentation Key
  • aggiungere lo stesso setting nel file Web.Release.config in maniera tale da poter sostituire nel momento del deploy in produzione il setting del Web.config con questo
  • andare a dichiarare una variabile che possa, tramite Razor, arrivare fino allo script JavaScript

Procediamo con ordine.

Nel Web.config dichiariamo la seguente variabile che identifica la Instrumentation Key:

<appSettings>
    <!-- Application Insights -DEVELOPMENT- Instrumentation Key -->
    <add key="ApplicationInsightsInstrumentationKey" 
         value="fca7eaf9-717d-4d86-8d7c-70c7914880b4" />
 </appSettings>

come valore andremo a mettere la chiave “_DEV”.
Nel file Web.Release.config andremo a mettere quindi la chiave “trasformata” che rappresenta la risorsa “_PROD”:

<appSettings>
    <!-- Application Insights -PRODUCTION- Instrumentation Key -->
 <add key="ApplicationInsightsInstrumentationKey" 
      value="95e74185-b456-48e4-9e69-f586ffeeb0b1"
      xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
 </appSettings>

Utilizzando questa modalità che ci viene offerta da Visual Studio, avremo quindi il risultato di “portare” nel Web.config presente nel deploy fatto in produzione la chiave giusta (a patto ovviamente che nel nostro package di deploy indichiamo la configurazione di “Release”).

A questo punto dobbiamo procedere alla “lettura” di questo valore dal file Web.config che il codice troverà in esecuzione.
Per far questo possiamo procedere alla lettura all’interno del file Global.asax, e più precisamente nel metodo di Application_Start:

protected void Application_Start()
{
    // altro codice
    //...
    // lettura della instrumentation key in base alla configurazione
    Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey = System.Web.Configuration.WebConfigurationManager.AppSettings["ApplicationInsightsInstrumentationKey"];
}

Con questa istruzione abbiamo impostato che la Instrumentation Key venga “letta” dal file Web.config ogni volta che viene avviata l’applicazione.
Ovviamente, in funzione dell’ambiente in cui ci si troverà, grazie alla trasformazione applicata precedentemente nei file di config, troveremo la chiave giusta, quindi “_DEV” in ambiente di sviluppo e “_PROD” nell’ambiente di produzione.

Ora i nostri dati saranno puliti?
Ancora non del tutto. Con quanto fatto finora abbiamo infatti garantito che lato server abbiamo discriminato le due chiavi, ma abbiamo ancora una chiave “cablata” nel JavaScript di Application Insights, e questo lo risolviamo facilmente con una sostituzione della chiave stessa con una variabile caricata a “runtime” tramite Razor, il risultato è il seguente:

    var appInsights=window.appInsights||function(config){
    function r(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o="script",s=u.createElement(o),i,f;for(s.src=config.url||"//az416426.vo.msecnd.net/scripts/a/ai.0.js",u.getElementsByTagName(o)[0].parentNode.appendChild(s),t.cookie=u.cookie,t.queue=[],i=["Event","Exception","Metric","PageView","Trace"];i.length;)r("track"+i.pop());return r("setAuthenticatedUserContext"),r("clearAuthenticatedUserContext"),config.disableExceptionTracking||(i="onerror",r("_"+i),f=e[i],e[i]=function(config,r,u,e,o){var s=f&&f(config,r,u,e,o);return s!==!0&&t["_"+i](config,r,u,e,o),s}),t
    }({
    instrumentationKey: "@(Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey)"
    });
    window.appInsights=appInsights;
    appInsights.trackPageView();

Ora sì che possiamo dire di aver risolto tutti i possibili conflitti delle chiavi. Infatti, con questa “semplice” sostituzione del valore con una variabile letta dal server, e che nel nostro caso è proprio la stessa Instrumentation Key che abbiamo impostato durante la fase di “application start”, possiamo essere sicuri che anche nelle pagine del frontend troveremo le giuste chiavi per i due ambienti diversi.

Fra “qualche post” spiegheremo cos’è e a cosa serve la classe TelemetryClient, e come invocare le varie API messe a disposizione da Application Insights.

Per ora divertitevi a fare delle prove con questo codice.

Separare sviluppo e produzione su Application Insights

Un pensiero su “Separare sviluppo e produzione su Application Insights

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...