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

# Instrumentando queries Ecto

export const Compatibility = ({versions = [], label = "Available in"}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const defaultPillStyle = {
    borderColor: "#d4d4d8",
    background: "#f4f4f5",
    color: "#3f3f46"
  };
  const pillStyles = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#d8b4fe",
      color: "#6b21a8"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#5eead4",
      color: "#115e59"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#86efac",
      color: "#166534"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#93c5fd",
      color: "#1e40af"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fca5a5",
      color: "#991b1b"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fdba74",
      color: "#9a3412"
    }
  };
  const getPillStyle = name => ({
    ...defaultPillStyle,
    ...pillStyles[name] || ({})
  });
  return <div className="not-prose my-4 rounded-lg border border-zinc-200 bg-zinc-50 px-4 py-3 text-sm dark:border-white/10 dark:bg-white/5">
      <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
        <span className="font-semibold text-zinc-700 dark:text-zinc-200">
          {label}:
        </span>
        {versions.map((v, i) => <span key={`${v.name}-${v.version}-${i}`} className="inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium" style={getPillStyle(v.name)}>
            <span>{v.name}</span>
            <span className="opacity-70">
              {v.version}
              {v.exact ? "" : "+"}
            </span>
          </span>)}
      </div>
    </div>;
};

O AppSignal usa a instrumentação Telemetry do Ecto para obter informações sobre queries executadas no seu app, anexando um handler que é chamado sempre que uma query é executada.

## Instrumentação automática

A instrumentação Ecto se conecta automaticamente aos seus repos Ecto se a configuração `:otp_app` estiver definida como o nome do OTP app da sua aplicação. O instalador configura isso automaticamente para você.

<CodeGroup>
  ```elixir Elixir theme={null}
  config :appsignal, :config,
    otp_app: :my_app, # Defina isto com o nome do seu OTP app
    name: "My app",
    push_api_key: "your-api-key",
    env: Mix.env
  ```
</CodeGroup>

A integração então usa a configuração do seu app para descobrir quais repos estão configurados, pois seu app terá uma linha de configuração como esta em `config/config.exs`:

<CodeGroup>
  ```elixir Elixir theme={null}
  config :my_app,
    ecto_repos: [AppsignalPhoenixExample.Repo]
  ```
</CodeGroup>

### Desabilitar a instrumentação automática

<Compatibility versions={[{ name: "AppSignal for Elixir", version: "2.5.1" }]} />

Para desabilitar a instrumentação automática do Ecto, defina [a opção de configuração `instrument_ecto`](/elixir/configuration/options#option-instrument_ecto) como `false`.

## Instrumentando preloads do Ecto

<Compatibility versions={[{ name: "AppSignal for Elixir", version: "2.8.2" }]} />

Como queries de preload do Ecto usam internamente vários processos Elixir para executar as diferentes consultas ao banco de dados envolvidas, algumas alterações manuais no seu código são necessárias para que o AppSignal as instrumente corretamente.

No topo do seu módulo de repo Ecto, substitua `use Ecto.Repo` por `use Appsignal.Ecto.Repo`, como no exemplo a seguir:

<CodeGroup>
  ```elixir Elixir theme={null}
  defmodule MyApp.Repo do
    # substitua `use Ecto.Repo` por `use Appsignal.Ecto.Repo`
    use Appsignal.Ecto.Repo,
      otp_app: :my_app,
      adapter: Ecto.Adapters.Postgres
  end
  ```
</CodeGroup>

Se o seu módulo de repo Ecto tiver sua própria implementação da função `default_options/1`, certifique-se de chamar `super` dentro dela para mesclar suas opções padrão com as da instrumentação de repo Ecto do AppSignal:

<CodeGroup>
  ```elixir Elixir theme={null}
  defmodule MyApp.Repo do
    use Appsignal.Ecto.Repo, ...

    def default_options(operation) do
      super(operation) ++ [
        # ... suas opções padrão aqui ...
      ]
    end
  end
  ```
</CodeGroup>

## Anexação manual do handler

Para repos que não estão listados na configuração `:ecto_repos`, você pode anexar um handler manualmente ao iniciar o supervisor do seu app. Na maioria das aplicações, isso é feito na função `start/2` da sua aplicação.

<CodeGroup>
  ```elixir Elixir theme={null}
  def start(_type, _args) do
    children = [
      AppsignalPhoenixExample.Repo,
      AppsignalPhoenixExampleWeb.Endpoint
    ]

    Appsignal.Ecto.attach(:my_otp_app, MyApp.Repo)

    opts = [strategy: :one_for_one, name: AppsignalPhoenixExample.Supervisor]
    Supervisor.start_link(children, opts)
  end
  ```
</CodeGroup>

Neste exemplo, anexamos o handler de Telemetry à nossa aplicação Phoenix chamando `Appsignal.Ecto.attach/2`. O primeiro argumento é o nome do OTP app ao qual o repo pertence, e o segundo argumento é o módulo do repo.

## Métricas

<Compatibility versions={[{ name: "AppSignal for Elixir", version: "2.17.2" }]} />

Além de instrumentar suas queries Ecto, o AppSignal for Elixir coleta
métricas sobre o desempenho dos seus repos Ecto:

* `ecto_query_time`: O tempo que o banco de dados gasta executando cada query, tagueado
  por `repo` e `hostname`, e para cada tabela por `repo` e `source`.

* `ecto_queue_time`: O tempo gasto esperando por uma conexão de banco de dados do
  pool, tagueado por `repo` e `hostname`.

* `ecto_decode_time`: O tempo gasto decodificando os resultados da query em termos Elixir,
  tagueado por `repo` e `hostname`, e para cada tabela por `repo` e `source`.

* `ecto_idle_time`: O tempo que a conexão ficou ociosa no pool antes de ser
  retirada, tagueado por `repo` e `hostname`.

* `ecto_total_time`: A soma de queue, query e decode time, tagueado por `repo`
  e `hostname`, e para cada tabela por `repo` e `source`.

O AppSignal usa essas métricas para criar o magic dashboard do Ecto, que
mostra insights-chave sobre o desempenho dos seus repos Ecto:

<Frame caption="O magic dashboard do Ecto no AppSignal">
  <img src="https://mintcdn.com/appsignal-715f5a51/nF8c1Rwq1cS7b5hg/assets/images/screenshots/elixir/integrations/ecto/automated-dashboard.png?fit=max&auto=format&n=nF8c1Rwq1cS7b5hg&q=85&s=a53723c44b296164b7ad992951faa48d" alt="Magic dashboard mostrando métricas-chave do Ecto" width="2382" height="1698" data-path="assets/images/screenshots/elixir/integrations/ecto/automated-dashboard.png" />
</Frame>
