Para descobrir quais trechos específicos de código estão causando problemas de desempenho, é útil adicionar instrumentação personalizada à sua aplicação. Isso nos permite criar detalhamentos melhores sobre qual código roda mais lentamente e em que tipo de action mais tempo foi gasto.
Quando você visualizar amostras salvas de requisições lentas no AppSignal, poderá ver toda a instrumentação que sua aplicação usa internamente. Renderização de templates, queries do ActiveRecord e caching são instrumentados e serão mostrados na amostra.
Isso já é muito útil, mas não seria ótimo se pudéssemos ver
medições de trechos específicos de código que você suspeita que possam influenciar o
desempenho? Bem, você pode!
Ao adicionar instrumentação personalizada, podemos criar detalhamentos mais detalhados de uma requisição e background job. Existem duas formas de instrumentar seu código. Com os helpers de instrumentação do AppSignal ou com a instrumentação do ActiveSupport Notifications, como é usada pelo Rails.
Nota: Esta página descreve apenas como adicionar instrumentação de desempenho
ao seu código. Para rastrear erros, leia nosso guia de tratamento de
exceções.
Helpers de instrumentação
Quando você adiciona instrumentação personalizada ao seu código, poderá receber ainda
mais insights sobre sua aplicação. Por exemplo, você precisa trabalhar com uma
API externa que busca artigos para sua página inicial:
class ArticleFetcher
def self.fetch(category)
Appsignal.instrument('fetch.article_fetcher') do
# Download and process the articles
end
end
end
ArticleFetcher.fetch('Latest news')
Uma vez que você adiciona instrumentações personalizadas como essa, o AppSignal começará a captá-las
e mostrará quanto tempo tanto um grupo de eventos (article_fetcher neste
caso) quanto eventos individuais levaram.
Neste caso, você notará que essa chamada de API tem uma grande influência no
desempenho da nossa página inicial, o que estava oculto antes. Podemos querer considerar
fazer cache dos artigos.
Nota: O nome do evento que você está instrumentando é importante para nosso
processador. Leia mais sobre nomenclatura de eventos.
Aninhando instrumentação
Você pode usar quantas instrumentações quiser, em qualquer combinação. Você pode
aninhar chamadas de instrument, e o AppSignal lidará com o aninhamento e as agregações das
medições de forma adequada. Você só precisa manter o segmento final (após o último
ponto) da chave consistente.
Appsignal.instrument('fetch.article_fetcher') do
10.times do
Appsignal.instrument('fetch_single_article.article_fetcher') do
# Fetch single article
end
end
end
Coletando mais dados por evento
Por padrão, o AppSignal coletará a duração de um evento e a enviará para nossos
servidores. Como a instrumentação personalizada não está conectada a nenhum interno de framework,
você pode precisar passar mais dados se quiser que os detalhes do evento
apareçam no AppSignal. Pode ser um título descritivo ou informações mais específicas
como a query de uma chamada de banco de dados. Já fazemos isso para
ActiveRecord, Sequel, Redis, MongoDB, Sinatra, Grape,
e mais.
Existem dois helpers para permitir que você instrumente seu código com o AppSignal.
Appsignal.instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT, &block)
# and
Appsignal.instrument_sql(name, title = nil, body = nil, &block)
Argumento name
O nome do evento que aparecerá na árvore de eventos no AppSignal.
Leia mais sobre nomenclatura de chaves de eventos.
Argumento title
Um título mais descritivo de um evento, como "Fetch current user" ou "Fetch blog post comments". Ele aparecerá ao lado do nome do evento na árvore de eventos
na página de amostra de desempenho para fornecer um pouco mais de contexto sobre o que está
acontecendo.
Appsignal.instrument('fetch.custom_database', 'Fetch current user') do
# ...
end
Argumento body
Mais detalhes, como uma query de banco de dados usada pelo evento.
sql = 'SELECT * FROM posts ORDER BY created_at DESC LIMIT 1'
Appsignal.instrument('fetch.custom_database', 'Fetch latest post', sql) do
# ...
end
Aviso: Por favor, certifique-se de que os payloads do body estão sanitizados
(dados sensíveis/dinâmicos foram removidos). Eventos com body não sanitizados serão
descartados se atingirem um certo limite.
Bom:
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do
# ...
end
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do
# ...
end
Ruim:
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/123') do
# ...
end
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/234') do
# ...
end
Ao passar uma query SQL como body, você pode usar body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT para isso.
Argumento body_format
O formato do body suporta formatadores para sanitizar os dados fornecidos no argumento body
para remover quaisquer dados sensíveis do valor. Atualmente, há dois valores suportados
para o argumento body_format.
Valor Appsignal::EventFormatter::DEFAULT
O Appsignal::EventFormatter::DEFAULT é o valor padrão deste
argumento. Por padrão, o AppSignal deixará o valor intacto e não sanitizará nenhum
dado dele.
Valor Appsignal::EventFormatter::SQL_BODY_FORMAT
O valor Appsignal::EventFormatter::SQL_BODY_FORMAT passará seus dados
pelo sanitizador de SQL e sanitizará quaisquer valores em queries SQL.
Recomendamos que você use o helper Appsignal.instrument_sql para isso.
SELECT * FROM users WHERE email = 'hector@appsignal.com' AND password = 'iamabot'
-- becomes
SELECT * FROM users WHERE email = ? AND password = ?
ActiveSupport::Notifications
Em versões mais antigas da gem do AppSignal (1.2 e anteriores), o
Appsignal.instrument não está disponível. Se você não puder atualizar, ainda é
possível usar ActiveSupport::Notifications em vez disso. Se você não quiser
usar o helper Appsignal.instrument, mas sim usar
ActiveSupport::Notifications, você ainda pode fazê-lo na gem AppSignal para Ruby
1.3 e versões superiores.
O método para instrumentar seu código usando ActiveSupport::Notifications
é muito semelhante a como o AppSignal faz isso. Usando o exemplo do article fetcher
novamente, você pode ver que as diferenças são bastante pequenas.
Veja também nossa documentação sobre formatadores de eventos do AppSignal ao usar ActiveSupport::Notifications.
Para mais informações sobre a instrumentação ActiveSupport::Notifications, consulte a documentação oficial do Rails ActiveSupport::Notifications.
require "active_support"
class ArticleFetcher
def self.fetch(category)
ActiveSupport::Notifications.instrument("fetch.article_fetcher") do
# Download and process the articles
end
end
end
ArticleFetcher.fetch("Latest news")
Funciona para chamadas de instrumentação aninhadas também.
require "active_support"
ActiveSupport::Notifications.instrument("fetch.article_fetcher") do
10.times do
ActiveSupport::Notifications.instrument("fetch_single_article.article_fetcher") do
# Fetch single article
end
end
end
ActiveSupport::Notifications é altamente flexível, você pode instrumentar seu código
da maneira que quiser. Mais informações sobre ActiveSupport::Notifications podem ser
encontradas na
documentação da API do Rails.
Aviso: Não rastreamos eventos privados do ActiveSupport::Notifications
que começam com um ponto de exclamação (!). Esses eventos incluem principalmente eventos privados
gerados pelo Rails.