Pular para o conteúdo principal
Quando o AppSignal recebe dados do seu aplicativo, os traces/transações são agrupados pela combinação de namespace e nome de ação. Por padrão, esses nomes de ação são determinados automaticamente com base no seu framework (por exemplo, Controller#action_name, BackgroundWorker#perform, etc.). Quando o nome de ação determinado automaticamente não é bom o suficiente, você pode personalizar o nome da ação. Este guia explica como personalizar nomes de ação em diferentes integrações de linguagem.
Nomes de ações não devem ser únicos! Não use variáveis para personalizar os nomes de ação, pois isso criará um novo incidente por ocorrência. Isso torna a visão geral de incidentes difícil de usar e impede o agrupamento adequado e a análise de tendências.Sempre use strings estáticas para nomes de ação. Nunca interpole variáveis, entradas de usuário ou dados dinâmicos em nomes de ação.

Por que personalizar nomes de ação?

  • Clareza aprimorada: forneça nomes mais descritivos para operações complexas.
  • Agrupamento personalizado: controle como os dados do aplicativo são organizados no AppSignal.

Quando os nomes de ação automáticos não são suficientes

Aqui estão alguns exemplos em que os nomes de ação gerados automaticamente podem não ser bons o suficiente:
  1. Rotas catch-all: em aplicativos que usam rotas catch-all ou roteamento dinâmico (como /api/:entity/:action), o nome de ação padrão pode ser algo genérico como ApiController#dispatch.
  2. Tarefas multipropósito: workers em segundo plano e scripts que lidam com diferentes tipos de trabalho com base em parâmetros que seriam todos agrupados sob o mesmo nome de ação (por exemplo, GenericWorker#perform).
  3. Resolvers GraphQL: estes podem ser todos agrupados sob um único nome de ação (por exemplo, POST /graphql), apesar de lidar com muitos tipos diferentes de operações.

Personalizando ações por linguagem

Ruby

Em aplicativos Ruby, você pode usar o helper Appsignal.set_action para personalizar o nome da ação:
# Em um controller Rails
class PaymentsController < ApplicationController
  def process_payment
    provider = params[:payment][:provider]

    # BOM: altera o nome da ação de "PaymentsController#process_payment"
    # para algo mais específico sobre a operação
    if provider == "creditcard"
      Appsignal.set_action("PaymentsController#process_payment (creditcard)")
    end

    # RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
    # Appsignal.set_action("PaymentsController#process_#{provider}")

    # Resto do seu código
  end
end
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma com o helper Appsignal.set_action. Também é possível configurar o nome da ação ao criar uma transação usando o helper Appsignal.monitor. Ele aceita o nome da ação como um argumento de palavra-chave.
# Ao criar uma nova transação
Appsignal.monitor(action: "script/custom_script") do
  # Seu código a ser instrumentado
end

Elixir

Em aplicativos Elixir, você pode usar a função Appsignal.Span.set_name/2 para personalizar o nome da ação no root span:
# Em um controller Phoenix
defmodule MyAppWeb.PaymentController do
  use MyAppWeb, :controller

  def process(conn, params) do
    # BOM: define um nome de ação estático personalizado com base no tipo de pagamento
    payment_type = Map.get(params, "type", "unknown")

    if payment_type == "creditcard" do
      Appsignal.Span.set_name(
        Appsignal.Tracer.root_span(),
        "PaymentController#process_payment (creditcard)"
      )
    end

    # RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
    # Appsignal.Span.set_name(
    #   Appsignal.Tracer.root_span(),
    #   "PaymentController#process_#{payment_type}"
    # )

    # Resto do seu código

    render(conn, "success.html")
  end
end
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma com a função Appsignal.Span.set_name/2.

Node.js

Em aplicativos Node.js, você pode usar o helper setRootName do pacote AppSignal para personalizar nomes de ação:
import { setRootName } from "@appsignal/nodejs";

// Em um manipulador de rota do Express.js
app.post("/payments", (req, res) => {
  const paymentType = req.body.type || "unknown";

  // BOM: define um nome de ação personalizado com base no tipo de pagamento
  if (paymentType === "creditcard") {
    setRootName("PaymentsController#process_payment (creditcard)");
  }

  // RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
  // setRootName(`PaymentsController#process_${paymentType}`);

  // Resto do seu código

  res.send("Payment processed");
});
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma com o helper setRootName.

Python

Em aplicativos Python, você pode usar o helper set_root_name do pacote AppSignal para personalizar nomes de ação:
from appsignal import set_root_name

# Em uma view Django
def process_payment(request):
    payment_type = request.POST.get('type', 'unknown')

    # BOM: define um nome de ação personalizado com base no tipo de pagamento
    if payment_type == "creditcard":
        set_root_name("PaymentsView#process_payment (creditcard)")

    # RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
    # set_root_name(f"PaymentsView#process_{payment_type}")

    # Resto do seu código

    return HttpResponse("Payment processed")
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma com o helper set_root_name.

JavaScript de front-end

Em aplicativos JavaScript de front-end, você pode usar o helper setAction do pacote AppSignal para personalizar nomes de ação:
const span = appsignal.createSpan((span) => {
  const formType = getFormType();

  // BOM: define um nome de ação personalizado com base no tipo de formulário
  if (formType === "checkout") {
    span.setAction("CheckoutPage#submit_form (checkout)");
  }

  // RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
  // span.setAction(`CheckoutPage#submit_${formType}_form`);

  // Resto do seu código
});
Como alternativa, você pode atualizar o nome de ação de um span existente:
// Obtém o span ativo atual
const span = appsignal.getActiveSpan();

function handlePaymentMethodSelection(method) {
  // BOM: define um nome de ação personalizado com base no método de pagamento
  if (method === "creditcard") {
    span.setAction("PaymentForm#select_method (creditcard)");
  }

  // RUIM: não faça isso - usar uma variável cria muitos nomes de ação
  // span.setAction(`PaymentForm#select_${method}`);

  // Resto do seu código
}

Go

Em aplicativos Go, o AppSignal funciona com o OpenTelemetry, que usa spans para rastrear metadados, como o nome da ação. Em qualquer span no trace, defina um atributo appsignal.action_name com um valor String para personalizar o nome da ação:
package main

import (
	"context"
	"net/http"

	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
)

func processPaymentHandler(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	span := trace.SpanFromContext(ctx)

	paymentType := r.FormValue("type")

	// BOM: define um nome de ação personalizado com base no tipo de pagamento
	if paymentType == "creditcard" {
		span.SetAttributes(attribute.String("appsignal.action_name", "PaymentHandler#process_payment (creditcard)"))
	}

	// RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
	// span.SetAttributes(attribute.String("appsignal.action_name", fmt.Sprintf("PaymentHandler#process_%s", paymentType)))

	// Resto do seu código

	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Payment processed"))
}
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma, definindo o atributo appsignal.action_name no span ativo.

Java

Em aplicativos Java, o AppSignal funciona com o OpenTelemetry, que usa spans para rastrear metadados, como o nome da ação. Em qualquer span no trace, defina um atributo appsignal.action_name com um valor String para personalizar o nome da ação:
import io.opentelemetry.api.trace.Span;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentController {

    @PostMapping("/payments")
    public String processPayment(@RequestParam String type) {
        Span span = Span.current();

        // BOM: define um nome de ação personalizado com base no tipo de pagamento
        if ("creditcard".equals(type)) {
            span.setAttribute("appsignal.action_name", "PaymentController#processPayment (creditcard)");
        }

        // RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
        // span.setAttribute("appsignal.action_name", "PaymentController#process_" + type);

        // Resto do seu código

        return "Payment processed";
    }
}
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma, definindo o atributo appsignal.action_name no span ativo.

PHP

Em aplicativos PHP, você pode usar o método helper Appsignal::setAction() do pacote AppSignal para personalizar nomes de ação:
<?php

use Appsignal\Appsignal;

class PaymentController
{
    public function processPayment()
    {
        $paymentType = $_POST['type'] ?? 'unknown';

        // BOM: define um nome de ação personalizado com base no tipo de pagamento
        if ($paymentType === 'creditcard') {
            Appsignal::setAction('PaymentController::processPayment (creditcard)');
        }

        // RUIM: não use um valor dinâmico, ele cria muitos nomes de ação
        // Appsignal::setAction("PaymentController::process_{$paymentType}");

        // Resto do seu código

        return 'Payment processed';
    }
}
Para jobs em segundo plano, tarefas e scripts, você pode definir o nome da ação da mesma forma, definindo o atributo appsignal.action_name no span ativo.

Melhores práticas

Ao personalizar nomes de ação, siga estas diretrizes:
  1. Seja consistente: use um padrão de nomenclatura consistente em todo o seu aplicativo.
  2. Seja específico: inclua informações relevantes que ajudem a identificar a operação.
  3. Evite alta cardinalidade: não inclua IDs ou valores únicos que criariam nomes de ação únicos por execução.
  4. Use strings estáticas: nunca interpole variáveis ou dados dinâmicos em nomes de ação.
  5. Siga a nomenclatura do código: use padrões de nomenclatura como Controller#action que correspondem à estrutura do seu aplicativo, para que a localização no código possa ser encontrada.
  6. Use tags ou metadados: para rastrear informações variáveis, como provedores de pagamento ou tipos de usuário, use tags e metadados em vez de incorporá-los aos nomes de ação.

Como lidar com diferentes operações com o mesmo nome de ação

Em vez de criar nomes de ação dinâmicos, use uma combinação de:
  1. Nomes de ação estáticos: use nomes de ação descritivos, mas estáticos.
  2. Tags: adicione tags com as informações variáveis (por exemplo, provider: stripe, operation_type: refund).
  3. Atributos personalizados: adicione metadados adicionais ao trace/transação.
Exemplo:
# Em vez disso:
# Appsignal.set_action("PaymentController#process_#{provider}")

# Faça isto:
Appsignal.set_action("PaymentController#process_payment")
Appsignal.add_tags(
  provider: provider,
  operation: operation
)
Essa abordagem permite que você:
  • Agrupe operações relacionadas sob um único nome de ação.
  • Filtre e pesquise com base em tags.
  • Mantenha uma visão geral de incidentes limpa.

Deploy

Depois de implementar nomes de ação personalizados, faça o deploy do seu aplicativo. Os novos traces/transações usarão seus nomes de ação personalizados nos dashboards do AppSignal.
Os dados históricos ainda usarão os nomes de ação originais. Apenas ações recém-relatadas usarão os nomes personalizados que você definiu.
Os nomes de ação personalizados não estão aparecendo corretamente? Não hesite em entrar em contato com nossa equipe de suporte para obter ajuda!

Leitura adicional