Usando New Relic Custom Metrics per monitorare tutte le cose

Quando si viene introdotti per la prima volta a New Relic, è facile essere sopraffatti da tutte le funzionalità. Ma come con la maggior parte degli strumenti, mentre salivi lentamente la curva di apprendimento e prendi confidenza con le funzioni fornite fuori dalla scatola, inizi a chiedermi come tutto si blocca insieme sotto il cofano e se c'è più che puoi fare con quello che hai a mano.

Oggi vedrò come New Relic monitora effettivamente le transazioni e come ci si può collegare al processo. Daremo una rapida occhiata al supporto fornito da New Relic per il monitoraggio dei lavori in background e analizzeremo anche le metriche personalizzate di New Relic, come le userete e i vantaggi che otterrete. Alla fine avrete una comprensione più profonda di come funziona New Relic ed essere in grado di utilizzarlo più pienamente. In altre parole, avremo una conoscenza più approfondita dei nostri strumenti, qualcosa a cui ogni sviluppatore dovrebbe mirare.

Iniziamo dando una rapida occhiata a come New Relic si aggancia effettivamente per tenere traccia delle prestazioni della tua applicazione.

Contenuto sponsorizzato

Questo contenuto è stato commissionato da New Relic ed è stato scritto e / o modificato dal team Tuts +. Il nostro obiettivo con i contenuti sponsorizzati è quello di pubblicare tutorial pertinenti e obiettivi, case study e interviste ispiratrici che offrono un vero valore educativo ai nostri lettori e ci consentono di finanziare la creazione di contenuti più utili.


In che modo la nuova reliquia traccia le transazioni e come si può fare lo stesso

Potrebbe sembrare un po 'magico, includi una gemma nel tuo Gemfile:

gem 'newrelic_rpm'

E in qualche modo New Relic monitora tutto il tuo codice. Ovviamente si tratta solo di codice, quindi vediamo come New Relic è effettivamente in grado di far funzionare l'app in modo che possa iniziare a monitorarlo quando è richiesta la gem dell'agent. Lo faremo nel contesto di un'app Rails 4.

Il primo posto dove guardare è newrelic_rpm.rb, che ha il seguente codice rilevante in esso:

... se Rails :: VERSION :: MAJOR.to_i> = 3 moduli NewRelic class Railtie < Rails::Railtie initializer "newrelic_rpm.start_plugin" do |app| NewRelic::Control.instance.init_plugin(:config => app.config) end end end else ... 

Quindi una Railtie viene creata quando la versione di Rails è superiore a tre, questo ottiene a NewRelic :: Controllo istanza singleton (quando è inizializzata) e chiama init_plugin. Quando il NewRelic :: Controllo l'istanza viene creata per capire quale framework è in esecuzione (Rails 4 nel nostro caso) e carica un codice rilevante; possiamo vedere questo in new_relic / Controllo / class_methods # load_framework_class. Il init_plugin il metodo che viene eseguito vive dentro new_relic / controllo / instance_methods. Il codice interessante qui è:

... se Agent.config [: agent_enabled] &&! NewRelic :: Agent.instance.started? start_agent install_instrumentation load_samplers unless Agent.config [: disable_samplers] ... 

Il install_instrumentation la chiamata è importante. L'implementazione vive dentro new_relic / controllo / strumentazione. Saltando sopra i bit boilerplate, questo risolve i file di strumentazione che deve caricare e quindi li richiede uno per uno. Nel nostro caso, caricherà i file sotto new_relic / agente / strumenti / rails4. Uno dei file qui è action_controller.rb, quando questo viene richiesto, alla fine esegue il seguente codice tramite una magia metaprogrammatica:

esegue la classe ActionController :: Base include NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation include NewRelic :: Agent :: Instrumentation :: Rails4 :: ActionController end NewRelic :: Agent :: Instrumentation :: ActionControllerSubscriber \ .subscribe (/ ^ process_action .action_controller $ /) end

E qui arriviamo al punto cruciale: ActionController :: Base (da cui ereditano tutti i controller) contiene un paio di moduli inclusi, il più importante dei quali è NewRelic :: Agente :: :: Strumentazione ControllerInstrumentation. Questo è l'inizio di come New Relic inizia a monitorare tutte le azioni del controller come 'transazioni'. Certo, è una visione un po 'semplificata e stiamo tracciando molti dettagli, ma ti dà un'idea di come New Relic monitora il tuo codice. La domanda è, come puoi usare queste informazioni?

Monitoraggio di framework personalizzati e lavori in background

È altamente improbabile trovarti in una situazione in cui stai utilizzando un framework web a cui New Relic non dispone già di strumentazione (nel mondo Ruby), ma diciamo che l'hai fatto. Sapendo ciò che sappiamo ora, possiamo facilmente configurare manualmente le azioni del controller di questo framework personalizzato. Se abbiamo un controller come questo:

class CustomController def custom_action ... end end

Possiamo strumentarlo in questo modo:

class CustomController include NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation def custom_action ... end add_transaction_tracer: custom_action end

Ora il tuo metodo di controllo verrà tracciato come una transazione nello stesso modo in cui vengono tracciate le azioni di Rails. Ovviamente, se hai creato il tuo framework web che include il codice di gestione del database, dovrai svolgere un lavoro extra per strumentare gran parte di quel codice, per consentire a New Relic di monitorare più di semplici azioni del controller. Ma l'idea generale rimane sana.

Il motivo sopra riportato diventa più utile quando vuoi che New Relic tenga traccia dei processi in background nell'applicazione. È molto più probabile che si sia ottenuto un codice di gestione dei lavori in background personalizzato piuttosto che aver scritto il proprio framework web. In effetti, abbiamo fatto solo questo con Tuts + inizialmente, anche se ora stiamo migrando su Sidekiq. Se stai usando uno dei ben noti sistemi di lavori in background come Sidekiq, Resque o Delayed Job, New Relic ha già una strumentazione incorporata, ma se hai fatto da solo, lo schema sopra è tutto ciò che ti serve per monitorare le tue attività.

Ad esempio, i nostri Tuts personalizzati + processi in background erano classi ruby ​​regolari che rispondevano al eseguire metodo, quindi tutto ciò che dobbiamo fare è questo:

class SomeBackgroundJob include NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation def execute ... end add_transaction_tracer: custom_action, categoria:: task end

L'ultimo bit, categoria: compito, è quello di garantire che New Relic non la segua come una transazione web, ma invece la tratti come un'attività in background e la faccia apparire nella scheda delle attività in background nell'interfaccia utente di New Relic. Se creiamo una classe base per tutti i nostri lavori, possiamo mettere la strumentazione lì e le classi figlio la erediteranno, quindi non dobbiamo preoccuparci di fare quanto sopra in ogni classe di lavoro.

Personalizzazione di una transazione ancora di più

È interessante notare che anche le transazioni Web che New Relic monitora automaticamente non sono sacrosanti. Ad esempio, puoi aggiungere alcuni parametri personalizzati da inviare a New Relic per la transazione attualmente in esecuzione (se hai attivato i parametri di acquisizione).

Puoi farlo in qualsiasi momento durante la transazione. Tutto ciò che devi fare è chiamare :: NewRelic :: Agent.add_custom_parameters (: key => 'value') in qualsiasi momento e i parametri che si passano verranno aggiunti ai dati dei parametri che si vedono all'interno di New Relic. Ad esempio, se avessimo un controller simile a questo:

classe HelloController < ApplicationController def index ::NewRelic::Agent.add_custom_parameters(:hello => "mondo") end end

Le transazioni lente ci darebbero le seguenti:

Questo non è tutto quello che possiamo fare. Possiamo segmentare una transazione mentre è in esecuzione rinominandola. Diciamo che vogliamo trattare una transazione come speciale quando viene eseguita da un particolare utente. Puoi fare qualcosa del genere:

classe HelloController < ApplicationController def index new_relic_name = NewRelic::Agent.get_transaction_name if current_user.name == 'Joe Customer' NewRelic::Agent.set_transaction_name("#new_relic_name - Joe Customer") end end end

Ora questa transazione verrà considerata come una transazione separata nell'interfaccia utente di New Relic:

Anche la strumentazione New Relic di default ha un po 'di spazio per la personalizzazione, ma a volte, proprio come Capitan Kirk, hai solo bisogno di più potenza. È qui che arrivano le metriche personalizzate.


Nuove metriche personalizzate della reliquia e come sono utili

Durante il giorno, avresti usato le metriche personalizzate per monitorare cose come la comunicazione di servizi esterni e l'uso di vari strumenti comuni come Redis. In questi giorni, New Relic ha modi migliori per monitorare quella roba, quindi a cosa servono le metriche personalizzate? Ho trovato che le metriche personalizzate sono utili in quattro situazioni:

  • monitoraggio del codice che New Relic non può vedere
  • codice di monitoraggio che non controlli
  • script di monitoraggio
  • monitoraggio di eventi totalmente personalizzati

Diamo una rapida occhiata a ciascuno di essi.

Codice di monitoraggio La nuova reliquia non può vedere

New Relic è abbastanza bravo a scomporre le prestazioni dei vari metodi applicativi in ​​una traccia di transazione, ma a volte vedrai qualcosa di simile in una traccia:

Sembra che ci sia un codice applicativo che New Relic non potrebbe essere strumentale per qualche motivo. Quello che possiamo fare è aiutare New Relic (e noi stessi) con alcune metriche personalizzate. Abbiamo bisogno di capire quale metodo New Relic ha avuto problemi di monitoraggio e collegare alcune metriche personalizzate per tenere traccia del tempo impiegato da questo metodo per eseguire. Questo apparirà in tutte le tracce successive. Diciamo che abbiamo una classe con un metodo che vogliamo monitorare tramite metriche personalizzate:

classe Order def amount ... end end

Possiamo iniziare a monitorare il quantità metodo in questo modo:

richiede la classe 'new_relic / agent / method_tracer' Ordine include :: NewRelic :: Agent :: MethodTracer def amount ... end add_method_tracer: amount, fine 'Custom / amount'

Il secondo parametro a add_method_tracer è il nome che questa metrica personalizzata otterrà nell'interfaccia utente di New Relic. I nomi delle metriche sono stringhe separate dalla barra e tutte le metriche personalizzate dovrebbero iniziare con "Personalizzato /". Ad esempio, potresti indicare la metrica personalizzata come "Personalizzata //'. A questo punto inizierai a vedere il quantità metodo nelle tracce della transazione, nell'interfaccia utente di New Relic. Ma cosa succede se il nostro quantità il metodo è molto complesso e vogliamo monitorarne alcune parti che sospettiamo siano lente? Il mio consiglio è che dovresti rifattorizzare il tuo metodo: è troppo grande, ma se non puoi farlo, puoi assegnare uno strumento al codice casuale in questo modo:

class Order extend :: NewRelic :: Agent :: MethodTracer def amount ... self.class.trace_execution_scoped (['Custom / amount / complex_code']) do ... codice complesso ... fine ... fine fine

Ora la parte strumentata del metodo verrà segnalata separatamente nelle tracce della transazione. Se in precedenza hai strumentato il metodo stesso, la tua nuova metrica "interiore" verrà raggruppata sotto quella precedente.

Questo è di gran lunga il modo più comune in cui finirai per utilizzare le metriche personalizzate nel tuo codice, ma guardiamo comunque gli altri.

Codice di monitoraggio che non controlli

Spesso potresti usare una libreria che, sospetti, sta rallentando la tua applicazione. Per impostazione predefinita, New Relic non sarà in grado di assegnare automaticamente una gemma casuale, quindi cosa puoi fare? Puoi lanciare la gemma e aggiungere alcuni strumenti usando il metodo che abbiamo visto sopra, ma esiste anche una soluzione ancora più semplice: utilizza gli inizializzatori. Diciamo che stai usando il foobar biblioteca che ha una classe foo con un metodo bar che si sospetta abbia un codice lento. Tutto quello che devi fare è creare un inizializzatore foobar_instrumentation.rb, e metti il ​​seguente in esso:

richiede 'new_relic / agent / method_tracer' Foo.class_eval include: NewRelic :: Agent :: MethodTracer add_method_tracer: bar end

Come puoi vedere il codice è molto simile a quello che avevamo sopra, New Relic elaborerà un nome ragionevole per la tua nuova metrica personalizzata in base al nome della classe e del metodo e inizierai a vederlo nelle tracce della transazione. Usalo per capire se quella libreria sospetta sta effettivamente facendo funzionare male il tuo codice, ma non mantenere questa strumentazione in modo permanente. Sparge inizializzatori non necessari nell'app Rails e inquina l'interfaccia utente Nuova Relic con metriche personalizzate che non è necessario monitorare in modo permanente.

Script di monitoraggio

Una parte delle applicazioni Web che viene spesso trascurata sono gli script. Per parafrasare una presentazione che ho fatto di recente, sono ancora codice di produzione e dovrebbero essere trattati come tali. Non si desidera che il codice di produzione si comporti male, soprattutto se lo si esegue in modo continuativo tramite cron jobs (o un metodo simile che non è un processo in background nel sistema), quindi è possibile utilizzare New Relic per capire se i tuoi script sono lenti.

Puoi instrumentare il tuo codice di script usando le metriche personalizzate come descritto sopra. Non verrà visualizzato nelle tracce di transazione in quanto non farà parte di una transazione. Ciò che sarete in grado di fare, però, è creare una dashboard personalizzata dalle metriche che raccolgono, che dovrebbe darvi un'idea se il vostro script ha un rendimento scarso.

L'altra cosa che puoi fare è trattare il tuo script come un tipo di lavoro in background e strumentarlo di conseguenza (includere NewRelic :: Agente :: :: Strumentazione ControllerInstrumentation e così via). Sarà acculturato insieme ad altri lavori in background nell'interfaccia utente, ma non dovrai preoccuparti dei cruscotti personalizzati.

L'unica avvertenza con gli script è questa: New Relic invia solo dati sul filo periodicamente. Con uno script unico che viene eseguito rapidamente, è necessario assicurarsi che i dati raccolti vengano effettivamente inviati, quindi potrebbe essere necessario arrestare manualmente l'agente New Relic. Una buona regola empirica è avviare manualmente l'agente all'inizio di ogni script e chiuderlo alla fine:

richiede 'newrelic_rpm' :: NewRelic :: Agent.manual_start ... codez ... :: NewRelic :: Agent.shutdown

In questo modo non avrai mai bisogno di chiedermi perché i tuoi dati non compaiono nell'interfaccia utente.

Monitoraggio di eventi completamente personalizzati

Una delle cose interessanti di New Relic è che ti consente di sfruttare la sua interfaccia utente e le strutture di aggregazione dei dati per metriche che non hanno nulla a che fare con le prestazioni (in teoria). Ad esempio, potresti avere una certa visibilità sulla frequenza con cui gli utenti si iscrivono alla tua domanda, sulla frequenza delle vendite o sull'ammontare totale che gli utenti pagano quando effettuano acquisti. Queste sono più metriche di business di quelle di performance, ma se è troppo difficile tenerle tracciabili separatamente puoi usare New Relic per farlo.

New Relic ti consente di registrare metriche personalizzate direttamente tramite due chiamate API:

  • record_metric
  • increment_metric

Puoi usare record_metric per tracciare qualsiasi metrica che ha un importo e increment_metric è abbastanza auto esplicativo. Quindi possiamo, per esempio, fare questo:

... acquisto (importo) ... :: NewRelic :: Agent.record_metric ('Custom / purchase_amount', amount) :: NewRelic :: Agent.increment_metric ('Custom / purchase_count') ... end ... 

L'unico modo in cui puoi visualizzare queste metriche nell'interfaccia utente consiste nel creare alcuni dashboard personalizzati. Devo dire che questo sarebbe un uso un po '"creativo" dell'API di New Relic dato che è stato progettato con i dati sulle prestazioni in mente, ma è certamente una cosa utile sapere quando è necessario gettare un dashboard veloce insieme e non voglio creare un sacco di infrastrutture extra.


I pericoli del monitoraggio troppo

Certo, tutto questo potere ha un costo. Se raccogli troppe metriche personalizzate, può iniziare a rallentare la tua applicazione. Può anche rallentare l'interfaccia utente di New Relic e rendere difficile l'interpretazione dei dati poiché New Relic collasserà metriche simili in una sintesi. New Relic consiglia di mantenere il numero di metriche personalizzate raccolte al di sotto del 2000. Ho trovato che le metriche personalizzate sono utilizzate al meglio periodicamente. Strumenti il ​​codice che ti serve, usa la strumentazione per risolvere il problema che stai avendo e quindi rimuovi la strumentazione. In questo modo puoi risolvere i tuoi problemi di rendimento e il numero di metriche personalizzate che utilizzi è improbabile che diventi troppo alto.


Conclusione

Abbiamo scavato negli interni del newrelic_rpm gem e hai imparato come dire a New Relic del codice che consideri una transazione web. Abbiamo esaminato come modificare le transazioni al volo, come monitorare i processi in background e le varie situazioni in cui è opportuno utilizzare le metriche personalizzate. C'è molto che puoi fare con New Relic al di là delle funzionalità che ti fornisce fuori dagli schemi e ora sei molto più in grado di sfruttarlo al massimo delle sue potenzialità. Tuttavia, c'è sempre molto altro da imparare, ad esempio come creare cruscotti personalizzati dalle metriche acquisite o come monitorare l'infrastruttura con i plug-in. Copriremo questi argomenti e altri in articoli successivi, quindi assicurati di controllare spesso. E come sempre se hai una domanda, vuoi condividere la tua storia di New Relic o semplicemente vuoi dire ciao, non dimenticare di lasciare un commento.