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

# Instrumentação personalizada em Python

Incluir instrumentação personalizada na sua aplicação pode ser útil para identificar as linhas específicas de código que causam problemas de performance.

O AppSignal para Python usa objetos tracer do OpenTelemetry; você pode ler mais sobre traces em Python no [Python Cookbook][cookbook] do OpenTelemetry.

Traces são compostos por uma ou mais spans. Um Trace pode ser pensado como um grafo acíclico direcionado (DAG) de spans:

<img src="https://mintcdn.com/appsignal-715f5a51/nF8c1Rwq1cS7b5hg/assets/images/abstract-trace.png?fit=max&auto=format&n=nF8c1Rwq1cS7b5hg&q=85&s=8e955df41909f6fadf6d607478d6badb" alt="Diagrama de trace" width="1826" height="650" data-path="assets/images/abstract-trace.png" />

Atributos específicos do AppSignal devem ser adicionados a uma span para que ela seja analisada com sucesso pelo AppSignal. Nosso conjunto de [métodos auxiliares](#helper-methods) pode ser usado para definir esses atributos.

Esta documentação explicará como criar instrumentações personalizadas definindo atributos específicos do AppSignal nas spans da sua aplicação Python.

## Criando uma span

Ao adicionar instrumentação personalizada, primeiro importe o módulo trace do OpenTelemetry no arquivo onde você quer adicionar a instrumentação.

<CodeGroup>
  ```python Python theme={null}
  from opentelemetry import trace
  ```
</CodeGroup>

Então, usando esse módulo trace, crie uma nova span:

<CodeGroup>
  ```python Python theme={null}
  tracer = trace.get_tracer(__name__)
  with tracer.start_as_current_span("Span name"):
      # Here you can execute your app logic

      # And set AppSignal span details:
      from appsignal import set_category

      set_category("category.name")
  ```
</CodeGroup>

Depois de obter a Span, você pode usar nossos [métodos auxiliares](#helper-method) para atribuir os atributos obrigatórios.

Mais informações sobre como criar e obter Spans estão disponíveis no [Python Cookbook do OpenTelemetry][cookbook].

## Scripts pontuais e Serverless

Ao executar scripts pontuais ou funções serverless, você precisa inicializar o AppSignal manualmente e pará-lo no final para garantir que nenhum dado seja perdido. O helper `stop` encerrará o processo do agente graciosamente e aguardará um pouco para garantir que todos os dados sejam enviados aos servidores do AppSignal.

<CodeGroup>
  ```python Python theme={null}
  appsignal = Appsignal(
      active=True,
      name="My Python App",
      push_api_key="YOUR_PUSH_API_KEY",
  )

  appsignal.start()

  # Your code here along with the instrumentation
  # ...

  appsignal.stop()
  ```
</CodeGroup>

## Métodos auxiliares

<Tip>
  Os métodos auxiliares descritos nesta seção não são compatíveis com o
  [AppSignal collector](/python/configuration/collector).
</Tip>

Os métodos auxiliares a seguir definem atributos específicos do AppSignal em spans que ajudam a agrupar spans e melhorar como elas são exibidas no AppSignal. Outros atributos não são suportados em spans pelo AppSignal.

### `set_category`

A categoria da span é o nome que aparece na linha do tempo de eventos de performance para traces. Também é usada para agrupar spans, criando um detalhamento por grupo na página de detalhes da amostra.

<CodeGroup>
  ```python Python theme={null}
  from appsignal import set_category

  set_category("category.name")
  set_category("query.users")
  set_category("update.users")
  set_category("view.users")
  ```
</CodeGroup>

A categoria é uma string contendo o evento e o grupo da span filha. A categoria deve usar um ponto (`.`) para expressar a herança hierárquica do evento, com a unidade mais alta por último. Para mais informações sobre categorias de span, consulte o [guia de nomes de eventos](/api/event-names).

### `set_name`

Mais detalhes podem ser adicionados à span que ficam visíveis ao passar o mouse sobre o evento na linha do tempo. O nome da span é usado para fornecer mais informações sobre o evento, como "Buscar usuários", o banco de dados de onde são buscados ou a URL que foi requisitada.

<CodeGroup>
  ```python Python theme={null}
  from appsignal import set_name

  set_name("Fetch users")
  ```
</CodeGroup>

Se este método não for chamado, será usado o valor com o qual `start_as_current_span` foi chamado.

### `set_body`

<Warning>
  🔐 Não envie <strong>Informações Pessoais Identificáveis (PII)</strong> para a AppSignal. Filtre PII (por exemplo, nomes, e-mails) e use um ID, hash ou identificador pseudonimizado no lugar. <br /> <br /> Para <strong>entidades cobertas pela HIPAA</strong>, mais informações sobre como assinar um Business Associate Agreement (BAA) estão disponíveis em nossa <a href="/support/business-add-ons">documentação de Business Add-Ons</a>.
</Warning>

O corpo da span pode incluir informações adicionais sobre o evento, como a requisição HTTP, o host conectado, etc. Certifique-se de sanitizar as informações antes de adicioná-las à span para que nenhuma Informação Pessoalmente Identificável seja enviada ao AppSignal. Essa informação ficará visível para a span ao passar o mouse sobre a linha do tempo de eventos.

Para armazenar consultas SQL no corpo da span, use o [helper `set_sql_body`](#set_sql_body) em vez deste.

<CodeGroup>
  ```python Python theme={null}
  from appsignal import set_body

  set_body("Span body")
  ```
</CodeGroup>

### `set_sql_body`

<Tip>
  Disponível desde o pacote Python 0.3.2.
</Tip>

Define uma consulta SQL como o corpo da span, como aparece na linha do tempo de eventos de performance na visualização de detalhes da amostra do incidente. Isso é semelhante ao [helper `set_body`](#set_body), mas é especializado para consultas SQL. Qualquer consulta SQL definida como corpo com este atributo será sanitizada para evitar enviar dados PII (Informações Pessoalmente Identificáveis) aos nossos servidores.

Consulte o [helper `set_body`](#set_body) para mais detalhes sobre como funciona o atributo body.

Quando ambos os helpers `set_body` e `set_sql_body` são chamados na mesma span, o valor do helper `set_sql_body` prevalece e o valor do helper `set_body` será ignorado.

<CodeGroup>
  ```python Python theme={null}
  from appsignal import set_sql_body

  set_body("SELECT * FROM users")
  ```
</CodeGroup>

### `set_root_name`

<Tip>
  Este atributo se aplica a todo o trace. Ele pode ser definido em um span filho e não precisa ser definido no span pai mais externo. Este atributo só pode ser definido uma vez por trace. Se for definido várias vezes, apenas o atributo de um span no trace será aplicado.
</Tip>

Cada trace é agrupado sob um endpoint HTTP, nome de worker de job em background ou nome de tarefa. Chamamos esse grupo de "nome de ação". Para alterar esse nome de ação para todo o trace, use o helper `set_root_name`.

Use um nome de ação genérico o suficiente para agrupar todos os traces dessa parte do app, sem reportar nomes diferentes a cada vez. Defina `GET /users/:id` (onde `:id` é o nome do parâmetro de URL) como o nome de ação, em vez de `GET /users/123` (onde `123` é o valor real feito na requisição). O último reportaria um novo incidente para cada requisição única.

<CodeGroup>
  ```python Python theme={null}
  from appsignal import set_root_name

  set_root_name("GET /custom")
  # With URL parameters
  set_root_name("GET /users/:id")
  ```
</CodeGroup>

#### Exemplo de caso de uso

Sua aplicação tem um endpoint chamado `GET /coffee`.

<CodeGroup>
  ```python Python theme={null}
  def coffee(request):
    return render(request, "coffee.html", {})
  ```
</CodeGroup>

Todas as requisições para esse endpoint gerarão amostras chamadas `GET /coffee`, mas seu endpoint trata múltiplas ações: `coffee?action=buy` e `coffee?action=sell`.

<img src="https://mintcdn.com/appsignal-715f5a51/4TRZP0Sq9Zq7PAPW/assets/images/screenshots/node/span-without-root-name.png?fit=max&auto=format&n=4TRZP0Sq9Zq7PAPW&q=85&s=c17dd17713da423bac8d380df6274a1e" alt="Span sem Root Name" width="1030" height="640" data-path="assets/images/screenshots/node/span-without-root-name.png" />

Embora todos usem o endpoint `GET /coffee`, são conceitualmente muito diferentes e, portanto, faria sentido que fossem agrupados separadamente no AppSignal em vez de na mesma amostra `GET /coffee`. Para fazer isso, você pode usar o helper `set_root_name`:

<CodeGroup>
  ```python Python theme={null}
  from appsignal import set_root_name

  def coffee(request):
    if request.GET.action == "buy":
      set_root_name("Buy coffee")
      # Buy coffee...
    elif request.GET.action == "sell":
      set_root_name("Sell coffee")
      # Sell coffee...

    return render(request, "coffee.html", {})
  ```
</CodeGroup>

Usar `set_root_name` mudará o nome da span raiz, agrupando as amostras das requisições `coffee?action=buy` e `coffee?action=sell` em ações separadas:

<img src="https://mintcdn.com/appsignal-715f5a51/4TRZP0Sq9Zq7PAPW/assets/images/screenshots/node/root-name-span.png?fit=max&auto=format&n=4TRZP0Sq9Zq7PAPW&q=85&s=2d6521845df3d5bcd8938900b4b643ac" alt="Span com Root Name" width="1052" height="780" data-path="assets/images/screenshots/node/root-name-span.png" />

## Outros dados de trace

Para personalizar ainda mais os dados armazenados no trace, consulte nossos guias de [Tagging](/guides/tagging) e [Personalização de dados](/guides/custom-data) para adicionar tags, parâmetros, dados de sessão, dados personalizados e muito mais.

[cookbook]: https://opentelemetry.io/docs/instrumentation/python/cookbook/
