> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agrupamento com nomes de ação

Quando o AppSignal recebe dados do seu aplicativo, os traces/transações são agrupados pela combinação de [namespace](/guides/namespaces) 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.

<Warning>
  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.
</Warning>

## 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](#ruby)
* [Elixir](#elixir)
* [Python](#python)
* [Node.js](#nodejs)
* [JavaScript de front-end](#front-end-javascript)
* [Go](#go)
* [Java](#java)
* [PHP](#php)

### Ruby

Em aplicativos Ruby, você pode usar o helper `Appsignal.set_action` para personalizar o nome da ação:

<CodeGroup>
  ```ruby Ruby theme={null}
  # 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
  ```
</CodeGroup>

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`](https://rubydoc.info/gems/appsignal/Appsignal/Helpers/Instrumentation#monitor-instance_method). Ele aceita o nome da ação como um argumento de palavra-chave.

<CodeGroup>
  ```ruby Ruby theme={null}
  # Ao criar uma nova transação
  Appsignal.monitor(action: "script/custom_script") do
    # Seu código a ser instrumentado
  end
  ```
</CodeGroup>

### 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**:

<CodeGroup>
  ```elixir Elixir theme={null}
  # 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
  ```
</CodeGroup>

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:

<CodeGroup>
  ```javascript Node.js theme={null}
  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");
  });
  ```
</CodeGroup>

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:

<CodeGroup>
  ```python Python theme={null}
  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")
  ```
</CodeGroup>

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:

<CodeGroup>
  ```javascript JavaScript theme={null}
  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
  });
  ```
</CodeGroup>

Como alternativa, você pode atualizar o nome de ação de um span existente:

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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
  }
  ```
</CodeGroup>

### 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:

<CodeGroup>
  ```go Go theme={null}
  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"))
  }
  ```
</CodeGroup>

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:

<CodeGroup>
  ```java Java theme={null}
  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";
      }
  }
  ```
</CodeGroup>

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:

<CodeGroup>
  ```php PHP theme={null}
  <?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';
      }
  }
  ```
</CodeGroup>

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](/guides/tagging) e [metadados](/guides/custom-data) 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](/guides/tagging) com as informações variáveis (por exemplo, `provider: stripe`, `operation_type: refund`).
3. **Atributos personalizados**: [adicione metadados adicionais](/guides/custom-data) ao trace/transação.

Exemplo:

<CodeGroup>
  ```ruby Ruby theme={null}
  # 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
  )
  ```
</CodeGroup>

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.

<Tip>
  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.
</Tip>

Os nomes de ação personalizados não estão aparecendo corretamente? Não hesite em [entrar em contato com nossa equipe de suporte](mailto:support@appsignal.com) para obter ajuda!

## Leitura adicional

* [Agrupamento com namespaces](/guides/namespaces)
* [Adicionar tags](/guides/tagging)
* [Adicionar metadados](/guides/custom-data)
* [Ignorar ações específicas](/guides/filter-data/ignore-actions)
