Monitoraggio e telemetria (compilazione di app cloud Real-World con Azure)

di Rick Anderson, Tom Dykstra

Scaricare Fix It Project o Scaricare E-book

L'e-book Building Real World Cloud Apps with Azure si basa su una presentazione sviluppata da Scott Guthrie. Illustra 13 modelli e procedure che consentono di sviluppare correttamente app Web per il cloud. Per informazioni sull'e-book, vedere il primo capitolo.

Un sacco di persone si affidano ai clienti per comunicare loro quando l'applicazione è inattiva. Questa non è una procedura consigliata ovunque, e soprattutto non nel cloud. Non esiste alcuna garanzia di notifica rapida e, quando si riceve una notifica, spesso si ottengono dati minimi o fuorvianti su ciò che è successo. Con buoni sistemi di telemetria e registrazione puoi essere a conoscenza di ciò che sta succedendo con la tua app e quando qualcosa va storto, scopri subito e hai informazioni utili per la risoluzione dei problemi con cui lavorare.

Acquistare o noleggiare una soluzione di telemetria

Nota

Questo articolo è stato scritto prima del rilascio di Application Insights . Application Insights è l'approccio preferito per le soluzioni di telemetria in Azure. Per altre informazioni, vedere Configurare Application Insights per il sito Web di ASP.NET .

Una delle cose importanti per l'ambiente cloud è che è davvero facile acquistare o affittare il tuo modo di vincere. La telemetria è un esempio. Senza un sacco di sforzo è possibile ottenere un sistema di telemetria davvero buono in esecuzione, molto conveniente. Esistono numerosi partner che si integrano con Azure e alcuni di essi hanno livelli gratuiti, per cui è possibile ottenere dati di telemetria di base per nulla. Di seguito sono riportati solo alcuni di quelli attualmente disponibili in Azure:

Microsoft System Center include anche funzionalità di monitoraggio.

Verrà illustrata rapidamente la configurazione di New Relic per mostrare quanto sia facile usare un sistema di telemetria.

Nel portale di gestione di Azure iscriversi al servizio. Fare clic su Nuovo e quindi su Store. Viene visualizzata la finestra di dialogo Scegli componente aggiuntivo . Scorrere verso il basso e fare clic su New Relic.

Scegliere un componente aggiuntivo

Fare clic sulla freccia destra e scegliere il livello di servizio desiderato. Per questa demo verrà usato il livello gratuito.

Personalizzare il componente aggiuntivo

Fare clic sulla freccia destra, confermare l'acquisto e New Relic ora viene visualizzato come componente aggiuntivo nel portale.

Esaminare l'acquisto

Portale di gestione del componente aggiuntivo New Relic

Fare clic su Informazioni di connessione e copiare il codice di licenza.

Informazioni di connessione

Passare alla scheda Configura per l'app Web nel portale, impostare Monitoraggio prestazioni su Componente aggiuntivo e impostare l'elenco a discesa Scegli componente aggiuntivo su New Relic. Fare quindi clic su Salva.

New Relic nella scheda Configura

In Visual Studio installare il pacchetto NuGet New Relic nell'app.

Analisi per sviluppatori nella scheda Configura

Distribuire l'app in Azure e iniziare a usarla. Creare alcune attività Fix It per fornire alcune attività per il monitoraggio di New Relic.

Tornare quindi alla pagina New Relic nella scheda Componenti aggiuntivi del portale e fare clic su Gestisci. Il portale invia l'utente al portale di gestione di New Relic usando l'accesso Single Sign-On per l'autenticazione, in modo da non dover immettere nuovamente le credenziali. La pagina Panoramica presenta un'ampia gamma di statistiche sulle prestazioni. Fare clic sull'immagine per visualizzare le dimensioni intere della pagina di panoramica.

Scheda Monitoraggio di New Relic

Ecco alcune delle statistiche che è possibile visualizzare:

  • Tempo medio di risposta in orari diversi del giorno.

    Tempo di risposta

  • Velocità effettiva (in richieste al minuto) in orari diversi del giorno.

    Velocità effettiva

  • Tempo cpu server dedicato alla gestione di richieste HTTP diverse.

    Orari delle transazioni Web

  • Tempo cpu impiegato in parti diverse del codice dell'applicazione:

    Dettagli traccia

  • Statistiche cronologiche delle prestazioni.

    Prestazioni cronologiche

  • Chiamate a servizi esterni, ad esempio il servizio BLOB e le statistiche su come è stato affidabile e reattivo il servizio.

    Servizi esterni

    Servizi esterni2

    Servizio esterno

  • Informazioni su dove proviene il traffico delle app Web negli Stati Uniti o dove proviene il traffico delle app Web negli Stati Uniti.

    Geografia

È anche possibile configurare report ed eventi. Ad esempio, è possibile pronunciare ogni volta che si inizia a visualizzare gli errori, inviare un messaggio di posta elettronica per avvisare il personale di supporto al problema.

Report

New Relic è solo un esempio di sistema di telemetria; è possibile ottenere tutto questo anche da altri servizi. La bellezza del cloud è che, senza dover scrivere codice e per costi minimi o nulli, improvvisamente è possibile ottenere molte più informazioni su come viene usata l'applicazione e su ciò che i clienti stanno effettivamente vivendo.

Log per informazioni dettagliate

Un pacchetto di telemetria è un buon primo passaggio, ma è comunque necessario instrumentare il proprio codice. Il servizio di telemetria indica quando si verifica un problema e indica cosa stanno riscontrando i clienti, ma potrebbe non fornire molte informazioni dettagliate su cosa sta succedendo nel codice.

Non è necessario eseguire la connessione remota in un server di produzione per vedere le operazioni dell'app. Questo potrebbe essere pratico quando si dispone di un server, ma cosa accade quando si è ridimensionato a centinaia di server e non si sa in quali server è necessario connettersi in remoto? La registrazione deve fornire informazioni sufficienti che non è mai necessario eseguire in remoto nei server di produzione per analizzare ed eseguire il debug dei problemi. È consigliabile registrare informazioni sufficienti in modo che sia possibile isolare i problemi esclusivamente tramite i log.

Accedere all'ambiente di produzione

Molte persone attivano la traccia nell'ambiente di produzione solo quando si verifica un problema e vogliono eseguire il debug. Ciò può comportare un notevole ritardo tra il momento in cui si è a conoscenza di un problema e il momento in cui si ottengono informazioni utili sulla risoluzione dei problemi. E le informazioni che si ottengono potrebbero non essere utili per errori intermittenti.

Ciò che è consigliabile nell'ambiente cloud in cui l'archiviazione è economica è che si lascia sempre l'accesso nell'ambiente di produzione. In questo modo, quando si verificano errori, sono già stati registrati e si dispone di dati cronologici che consentono di analizzare i problemi che si sviluppano nel tempo o si verificano regolarmente in momenti diversi. È possibile automatizzare un processo di eliminazione per eliminare i log precedenti, ma potrebbe risultare più costoso configurare un processo di questo tipo rispetto a quello di mantenere i log.

La spesa aggiuntiva per la registrazione è semplice rispetto alla quantità di tempo di risoluzione dei problemi e denaro che è possibile risparmiare avendo tutte le informazioni necessarie già disponibili quando qualcosa va storto. Quando qualcuno ti dice che si è verificato un errore casuale qualche volta intorno alle 8:00 della notte scorsa, ma non ricordano l'errore, puoi facilmente scoprire qual era il problema.

Per meno di 4 dollari al mese è possibile mantenere a portata di mano 50 gigabyte di log e l'impatto sulle prestazioni della registrazione è semplice, purché si tenga presente un aspetto, per evitare colli di bottiglia delle prestazioni, assicurarsi che la libreria di registrazione sia asincrona.

Distinguere i log che informano dai log che richiedono un'azione

I log sono destinati a INFORM (voglio che tu sappia qualcosa) o ACT (voglio che tu faccia qualcosa). Prestare attenzione a scrivere solo i log ACT per i problemi che richiedono veramente una persona o un processo automatizzato per intervenire. Troppi log ACT creeranno rumore, richiedendo troppo lavoro per setacciare tutto per trovare problemi reali. E se i log ACT attivano automaticamente alcune azioni, ad esempio l'invio di messaggi di posta elettronica al personale di supporto, evitare di consentire l'attivazione di migliaia di tali azioni da un singolo problema.

Nella traccia di System.Diagnostics .NET è possibile assegnare i log a livello di errore, avviso, informazioni e debug/dettagliato. È possibile distinguere ACT dai log INFORM riservando il livello di errore per i log ACT e usando i livelli inferiori per i log INFORM.

Livelli di registrazione

Configurare i livelli di registrazione in fase di esecuzione

Anche se è utile avere la registrazione sempre attiva nell'ambiente di produzione, un'altra procedura consigliata consiste nell'implementare un framework di registrazione che consente di modificare in fase di esecuzione il livello di dettaglio che si sta registrando, senza ridistribuire o riavviare l'applicazione. Ad esempio, quando si usa la funzionalità di traccia in System.Diagnostics è possibile creare log di errore, avviso, informazioni e debug/dettagliato. È consigliabile registrare sempre i log degli errori, degli avvisi e delle informazioni nell'ambiente di produzione e si vuole poter aggiungere dinamicamente la registrazione di debug/dettaglio per la risoluzione dei problemi caso per caso.

App Web in Servizio app di Azure supportano la scrittura System.Diagnostics di log nel file system, nell'archiviazione tabelle o nell'archiviazione BLOB. È possibile selezionare diversi livelli di registrazione per ogni destinazione di archiviazione ed è possibile modificare il livello di registrazione in tempo reale senza riavviare l'applicazione. Il supporto dell'archiviazione BLOB semplifica l'esecuzione dei processi di analisi di HDInsight nei log dell'applicazione, perché HDInsight sa come usare direttamente l'archiviazione BLOB.

Registrare eccezioni

Non inserire solo eccezioni. ToString() nel codice di registrazione. Ciò lascia le informazioni contestuali. In caso di errori SQL, esce dal numero di errore SQL. Per tutte le eccezioni, includere le informazioni sul contesto, l'eccezione stessa e le eccezioni interne per assicurarsi di fornire tutto ciò che sarà necessario per la risoluzione dei problemi. Ad esempio, le informazioni di contesto possono includere il nome del server, un identificatore di transazione e un nome utente (ma non la password o i segreti).

Se ci si affida a ogni sviluppatore per eseguire la procedura corretta con la registrazione delle eccezioni, alcune di esse non verranno eseguite. Per assicurarsi che venga eseguita la procedura corretta ogni volta, compilare la gestione delle eccezioni direttamente nell'interfaccia del logger: passare l'oggetto eccezione alla classe logger e registrare correttamente i dati delle eccezioni nella classe logger.

Registrare le chiamate ai servizi

È consigliabile scrivere un log ogni volta che l'app chiama un servizio, sia che si tratti di un database o di un'API REST o di qualsiasi servizio esterno. Includere nei log non solo un'indicazione dell'esito positivo o negativo, ma del tempo necessario per ogni richiesta. Nell'ambiente cloud si noteranno spesso problemi correlati a rallentamenti anziché a interruzioni complete. Un elemento che normalmente richiede 10 millisecondi potrebbe iniziare improvvisamente a prendere un secondo. Quando qualcuno indica che l'app è lenta, si vuole essere in grado di esaminare New Relic o il servizio di telemetria che si ha e convalidare l'esperienza e quindi si vuole essere in grado di esaminare i propri log per approfondire i dettagli del motivo per cui è lento.

Usare un'interfaccia ILogger

Quando si crea un'applicazione di produzione, è consigliabile creare una semplice interfaccia ILogger e attenersi ad alcuni metodi. In questo modo è facile modificare l'implementazione della registrazione in un secondo momento e non è necessario scorrere tutto il codice per farlo. È possibile usare la System.Diagnostics.Trace classe in tutta l'app Fix It, ma viene usata sotto le quinte in una classe di registrazione che implementa ILogger e si effettuano chiamate al metodo ILogger in tutta l'app.

In questo modo, se si vuole rendere la registrazione più completa, è possibile sostituire System.Diagnostics.Trace con qualsiasi meccanismo di registrazione desiderato. Ad esempio, man mano che l'app aumenta, potresti decidere di usare un pacchetto di registrazione più completo, ad esempio NLog o Enterprise Library Logging Application Block. Log4Net è un altro framework di registrazione diffuso, ma non esegue la registrazione asincrona.

Un motivo possibile per usare un framework come NLog è facilitare la divisione dell'output della registrazione in archivi dati di alto volume e valore elevato separati. Ciò consente di archiviare in modo efficiente grandi volumi di dati INFORM su cui non è necessario eseguire query veloci, mantenendo al contempo l'accesso rapido ai dati ACT.

Registrazione semantica

Per un modo relativamente nuovo di eseguire la registrazione che può produrre informazioni di diagnostica più utili, vedere Enterprise Library Semantic Logging Application Block (SLAB). SLAB usa event tracing for Windows (ETW) e il supporto eventSource in .NET 4.5 per consentire di creare log più strutturati ed eseguibili da query. Si definisce un metodo diverso per ogni tipo di evento registrato, che consente di personalizzare le informazioni scritte. Ad esempio, per registrare un errore di database SQL è possibile chiamare un LogSQLDatabaseError metodo . Per tale tipo di eccezione, si sa che una parte chiave di informazioni è il numero di errore, quindi è possibile includere un parametro di numero di errore nella firma del metodo e registrare il numero di errore come campo separato nel record di log scritto. Poiché il numero si trova in un campo separato, è possibile ottenere report in modo più semplice e affidabile in base ai numeri di errore SQL rispetto a quanto possibile se si concatenasse semplicemente il numero di errore in una stringa di messaggio.

Accesso all'app Fix It

Interfaccia ILogger

Ecco l'interfaccia ILogger nell'app Correggi.

public interface ILogger
{
    void Information(string message);
    void Information(string fmt, params object[] vars);
    void Information(Exception exception, string fmt, params object[] vars);

    void Warning(string message);
    void Warning(string fmt, params object[] vars);
    void Warning(Exception exception, string fmt, params object[] vars);

    void Error(string message);
    void Error(string fmt, params object[] vars);
    void Error(Exception exception, string fmt, params object[] vars);

    void TraceApi(string componentName, string method, TimeSpan timespan);
    void TraceApi(string componentName, string method, TimeSpan timespan, string properties);
    void TraceApi(string componentName, string method, TimeSpan timespan, string fmt, params object[] vars);
}

Questi metodi consentono di scrivere log con gli stessi quattro livelli supportati da System.Diagnostics. I metodi TraceApi consentono di registrare chiamate al servizio esterno con informazioni sulla latenza. È anche possibile aggiungere un set di metodi per il livello Debug/Dettagliato.

Implementazione del Logger dell'interfaccia ILogger

L'implementazione dell'interfaccia è davvero semplice. Fondamentalmente chiama solo i metodi System.Diagnostics standard. Il frammento di codice seguente mostra tutti e tre i metodi Information e uno degli altri.

public class Logger : ILogger
{
    public void Information(string message)
    {
        Trace.TraceInformation(message);
    }

    public void Information(string fmt, params object[] vars)
    {
        Trace.TraceInformation(fmt, vars);
    }

    public void Information(Exception exception, string fmt, params object[] vars)
    {
        var msg = String.Format(fmt, vars);
        Trace.TraceInformation(string.Format(fmt, vars) + ";Exception Details={0}", exception.ToString());
    }

    public void Warning(string message)
    {
        Trace.TraceWarning(message);
    }

    public void Error(string message)
    {
        Trace.TraceError(message);
    }

    public void TraceApi(string componentName, string method, TimeSpan timespan, string properties)
    {
        string message = String.Concat("component:", componentName, ";method:", method, ";timespan:", timespan.ToString(), ";properties:", properties);
        Trace.TraceInformation(message);
    }
}

Chiamata dei metodi ILogger

Ogni volta che il codice nell'app Fix It rileva un'eccezione, chiama un metodo ILogger per registrare i dettagli dell'eccezione. Ogni volta che effettua una chiamata al database, al servizio BLOB o a un'API REST, avvia un controllo di arresto prima della chiamata, arresta il controllo di arresto quando il servizio viene restituito e registra il tempo trascorso insieme alle informazioni sull'esito positivo o negativo.

Si noti che il messaggio di log include il nome della classe e il nome del metodo. È consigliabile assicurarsi che i messaggi di log identifichino la parte del codice dell'applicazione che li ha scritti.

public class FixItTaskRepository : IFixItTaskRepository
{
    private MyFixItContext db = new MyFixItContext();
    private ILogger log = null;

    public FixItTaskRepository(ILogger logger)
    {
        log = logger;
    }

    public async Task<FixItTask> FindTaskByIdAsync(int id)
    {
        FixItTask fixItTask = null;
        Stopwatch timespan = Stopwatch.StartNew();

        try
        {
            fixItTask = await db.FixItTasks.FindAsync(id);
            
            timespan.Stop();
            log.TraceApi("SQL Database", "FixItTaskRepository.FindTaskByIdAsync", timespan.Elapsed, "id={0}", id);
        }
        catch(Exception e)
        {
            log.Error(e, "Error in FixItTaskRepository.FindTaskByIdAsynx(id={0})", id);
        }

        return fixItTask;
    }

Quindi ora per ogni volta che l'app Fix It ha effettuato una chiamata a database SQL, è possibile visualizzare la chiamata, il metodo che lo ha chiamato e esattamente il tempo impiegato.

database SQL query nei log

Screenshot che mostra l'opzione Edit Entity Properties (Modifica proprietà entità) e l'aspetto di ogni proprietà per un aggiornamento riuscito con il tempo necessario.

Se si esplorano i log, è possibile notare che il tempo chiamato dalle chiamate al database è variabile. Queste informazioni potrebbero essere utili: poiché l'app registra tutto questo è possibile analizzare le tendenze cronologiche nel modo in cui il servizio di database viene eseguito nel tempo. Ad esempio, un servizio potrebbe essere veloce per la maggior parte del tempo, ma le richieste potrebbero non riuscire o le risposte potrebbero rallentare in determinati orari del giorno.

È possibile eseguire la stessa operazione per il servizio BLOB: per ogni volta che l'app carica un nuovo file, è presente un log ed è possibile visualizzare esattamente il tempo necessario per caricare ogni file.

Log di caricamento BLOB

È solo un paio di righe di codice aggiuntive da scrivere ogni volta che si chiama un servizio, e ora ogni volta che qualcuno dice che si è verificato un problema, si sa esattamente quale fosse il problema, se si trattasse di un errore o anche se era solo lento. È possibile individuare l'origine del problema senza dover eseguire la connessione remota in un server o attivare la registrazione dopo che si verifica l'errore e sperare di ricrearla.

Inserimento di dipendenze nell'app Fix It

Ci si potrebbe chiedere come il costruttore del repository nell'esempio illustrato sopra ottiene l'implementazione dell'interfaccia del logger:

public class FixItTaskRepository : IFixItTaskRepository
{
    private MyFixItContext db = new MyFixItContext();
    private ILogger log = null;

    public FixItTaskRepository(ILogger logger)
    {
        log = logger;
    }

Per collegare l'interfaccia all'implementazione, l'app usa dependency injection(DI) con AutoFac. L'inserimento delle dipendenze consente di usare un oggetto basato su un'interfaccia in molte posizioni nel codice e di specificare solo in un'unica posizione l'implementazione che viene usata quando viene creata un'istanza dell'interfaccia. In questo modo è più semplice modificare l'implementazione: ad esempio, è possibile sostituire il logger System.Diagnostics con un logger NLog. Oppure per i test automatizzati è possibile sostituire una versione fittizia del logger.

L'applicazione Fix It usa l'inserimento delle dipendenze in tutti i repository e in tutti i controller. I costruttori delle classi controller ottengono un'interfaccia ITaskRepository allo stesso modo in cui il repository ottiene un'interfaccia logger:

public class DashboardController : Controller
{
    private IFixItTaskRepository fixItRepository = null;

    public DashboardController(IFixItTaskRepository repository)
    {
        fixItRepository = repository;
    }

L'app usa la libreria AutoFac DI per fornire automaticamente istanze taskRepository e Logger per questi costruttori.

public class DependenciesConfig
{
    public static void RegisterDependencies()
    {
        var builder = new ContainerBuilder();

        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        builder.RegisterType<Logger>().As<ILogger>().SingleInstance();

        builder.RegisterType<FixItTaskRepository>().As<IFixItTaskRepository>();
        builder.RegisterType<PhotoService>().As<IPhotoService>().SingleInstance();
        builder.RegisterType<FixItQueueManager>().As<IFixItQueueManager>();

        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}

Questo codice indica fondamentalmente che in qualsiasi punto di un costruttore è necessaria un'interfaccia ILogger , passare un'istanza della classe Logger e ogni volta che richiede un'interfaccia IFixItTaskRepository , passare un'istanza della classe FixItTaskRepository .

AutoFac è uno dei numerosi framework di inserimento delle dipendenze che è possibile usare. Un altro comune è Unity, consigliato e supportato da Microsoft Patterns and Practices.

Supporto per la registrazione predefinita in Azure

Azure supporta i tipi di registrazione seguenti per App Web in Servizio app di Azure:

  • Traccia System.Diagnostics (è possibile attivare e disattivare e impostare i livelli in tempo reale senza riavviare il sito).
  • Eventi di Windows.
  • Log IIS (HTTP/FREB).

Azure supporta i tipi di accesso seguenti in Servizi cloud:

  • Traccia System.Diagnostics.
  • Contatori delle prestazioni.
  • Eventi di Windows.
  • Log IIS (HTTP/FREB).
  • Monitoraggio della directory personalizzato.

L'app Fix It usa la traccia System.Diagnostics. È sufficiente abilitare la registrazione di System.Diagnostics in un'app Web. In alternativa, chiamare l'API REST nel portale. Nel portale fare clic sulla scheda Configurazione per il sito e scorrere verso il basso per visualizzare la sezione Diagnostica applicazioni . È possibile attivare o disattivare la registrazione e selezionare il livello di registrazione desiderato. È possibile che Azure scriva i log nel file system o in un account di archiviazione.

Diagnostica dell'app e diagnostica del sito nella scheda Configura

Dopo aver abilitato la registrazione in Azure, è possibile visualizzare i log nella finestra Output di Visual Studio durante la creazione.

Menu Log di streaming

Menu Dei log di streaming2

È anche possibile avere i log scritti nell'account di archiviazione e visualizzarli con qualsiasi strumento in grado di accedere al servizio tabelle di Archiviazione di Azure, ad esempio Esplora server in Visual Studio o Azure Storage Explorer.

Log in Esplora server

Riepilogo

È davvero semplice implementare un sistema di telemetria risolto, instrumentare la registrazione nel codice personalizzato e configurare la registrazione in Azure. Quando si verificano problemi di produzione, la combinazione di un sistema di telemetria e dei log personalizzati consente di risolvere rapidamente i problemi prima che diventino problemi principali per i clienti.

Nel capitolo successivo verrà illustrato come gestire gli errori temporanei in modo che non diventino problemi di produzione che è necessario analizzare.

Risorse

Per ulteriori informazioni, vedere le risorse seguenti.

Documentazione principalmente sui dati di telemetria:

Documentazione principalmente sulla registrazione:

Documentazione principalmente sulla risoluzione dei problemi:

Video:

  • FailSafe: creazione di Servizi cloud scalabili e resilienti. Serie in nove parti di Esegue homann, Marc Mercuri e Mark Simms. Presenta concetti di alto livello e principi architetturali in modo molto accessibile e interessante, con storie tratte dall'esperienza cat (Customer Advisory Team) microsoft con i clienti effettivi. Gli episodi 4 e 9 riguardano il monitoraggio e la telemetria. L'episodio 9 include una panoramica dei servizi di monitoraggio MetricsHub, AppDynamics, New Relic e PagerDuty.
  • Creazione di grandi dimensioni: lezioni apprese dai clienti di Azure - Parte II. Mark Simms parla di progettazione per errori e strumentazione di tutto. Analogamente alla serie Failsafe, ma vengono fornite altre procedure.

Esempio di codice: