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

# SDK Go: analytics, DNS e domínios

> Leia analytics de borda, erros, logs de requisições e desempenho de uma aplicação web, verifique o DNS, defina um domínio e limpe o cache com c.Apps.Network.

`c.Apps.Network` funciona **apenas com aplicações web**. Todo método recebe o `ctx` e o id da aplicação primeiro.

Cada trecho abaixo roda sozinho dentro deste programa: cole um de cada vez em `main` e execute o `goimports` (veja [Executando os exemplos](/pt-br/sdks/go/client#executando-os-exemplos)).

```go theme={"system"}
package main

import (
	"context"
	"os"
	"time"

	"github.com/squarecloudofc/sdk-api-go/v3"
)

var (
	ctx   = context.Background()
	c     = squarecloud.New(os.Getenv("SQUARECLOUD_API_KEY"))
	appID = "abc123def456abc123def456"
	end   = time.Now()
	start = end.Add(-24 * time.Hour) // the last 24 hours
)

func main() {
	// Paste one snippet here, then run goimports.
}
```

## Janelas de tempo

`Analytics`, `Errors`, `Logs` e `Performance` recebem um `start` e um `end`, cada um um `time.Time` (enviado como RFC 3339 em UTC). O programa acima define os dois como as últimas 24 horas. Uma janela tem no máximo **7 dias**, e `start` é limitado à data de criação da aplicação. Uma janela inválida resulta em 400 `INVALID_TIME_RANGE`.

Os resultados ficam em cache em intervalos de 5 minutos. Os cache misses desses quatro métodos compartilham um limite de 20 requisições a cada 60 segundos por conta: ultrapassá-lo resulta em 429 `RATE_LIMITED`.

## Analytics

`Network.Analytics(ctx, appID, start, end, filters)` retorna os totais de tráfego e seus detalhamentos como um `*NetworkAnalytics`. Retorna `nil` (e um erro `nil`) para uma janela sem tráfego. Passe um `squarecloud.AnalyticsFilters{}` vazio para não usar filtros.

```go theme={"system"}
analytics, err := c.Apps.Network.Analytics(ctx, appID, start, end, squarecloud.AnalyticsFilters{})
if err != nil {
	log.Fatal(err)
}

if analytics != nil {
	fmt.Println(analytics.Visits)    // []AnalyticsTimeBucket: Date, Visits, Requests, Bytes
	fmt.Println(analytics.Countries) // []AnalyticsBucket: Type ("BR"), Visits, Requests, Bytes
}
```

Os detalhamentos são `Countries`, `Devices`, `OS`, `Browsers`, `Protocols`, `Methods`, `Paths`, `Referers`, `Providers`, `IPs`, `StatusCodes`, `Bots` e `ContentTypes` (JSON `countries`, ..., `status_codes`, `bots`, `content_types`). Cada grupo tem `Type`, `Visits`, `Requests` e `Bytes` (`int64`).

### Filtros

Os filtros restringem todos os detalhamentos. Cada um recebe o valor exato de `Type` do seu detalhamento. Um campo vazio não é enviado:

```go theme={"system"}
brazil, err := c.Apps.Network.Analytics(ctx, appID, start, end, squarecloud.AnalyticsFilters{
	Country:  "BR",
	Path:     "/api",
	Provider: "GOOGLE (15169)",
})
if err != nil {
	log.Fatal(err)
}

if brazil != nil {
	fmt.Println(brazil.Paths)
}
```

| Filtro | Exemplo |
| - | - |
| `Country` | `"BR"` (código de 2 letras) |
| `IP` | `"203.0.113.7"` |
| `Path` | `"/api"` (prefixo de caminho) |
| `Status` | `"404"` |
| `OS`, `Browser`, `Protocol`, `Bot` | O `Type` do detalhamento |
| `Referer` | `"Direct"` significa sem referer |
| `Provider` | `"NAME (ASN)"`, por exemplo `"GOOGLE (15169)"` |
| `ContentType` | O `Type` do detalhamento |

Um filtro inválido resulta em 400 `INVALID_FILTER`.

## Erros

`Network.Errors(ctx, appID, start, end, include4xx)` retorna as respostas 5xx da janela, além das 4xx quando `include4xx` é `true`. Retorna `nil` para uma janela vazia.

```go theme={"system"}
errs, err := c.Apps.Network.Errors(ctx, appID, start, end, true)
if err != nil {
	log.Fatal(err)
}

if errs != nil {
	fmt.Println(errs.Summary.Total, errs.Summary.ByClass) // ByClass: map[string]int64 with "4xx", "5xx"
	fmt.Println(errs.TopPaths)
}
```

## Logs de requisições

`Network.Logs(ctx, appID, start, end)` retorna requisições individuais com detalhes do cliente, da requisição e da resposta. Disponível nos planos Pro e Enterprise (caso contrário, 403 `UPGRADE_REQUIRED`).

```go theme={"system"}
logs, err := c.Apps.Network.Logs(ctx, appID, start, end)
if err != nil {
	log.Fatal(err)
}
for _, l := range logs {
	fmt.Println(l.Timestamp, l.Request.Method, l.Request.Path, l.Response.Status)
}
```

Os campos que a API pode enviar como `null` são ponteiros (`Client.IP`, `Client.Country`, `Request.Query`, `Request.Referer`, `Response.Cache`, ...).

## Desempenho

`Network.Performance(ctx, appID, start, end)` retorna percentis de latência (`P50`, `P95`, `P99`, em ms) na borda e na origem, por país, por localização e para os caminhos mais lentos. Retorna `nil` para uma janela vazia. Disponível nos planos Pro e Enterprise.

Cada percentil é um `*float64`, `nil` quando não houve requisições para medir:

```go theme={"system"}
performance, err := c.Apps.Network.Performance(ctx, appID, start, end)
if err != nil {
	log.Fatal(err)
}

if performance != nil {
	if p95 := performance.Summary.Edge.P95; p95 != nil {
		fmt.Println("edge p95", *p95)
	}
	if p95 := performance.Summary.Origin.P95; p95 != nil {
		fmt.Println("origin p95", *p95)
	}
}
```

## DNS

`Network.DNS(ctx, appID)` retorna os registros DNS de que seu domínio personalizado precisa, com seus status. Sem um domínio personalizado, resulta em 400 `NO_CUSTOM_DOMAIN`.

```go theme={"system"}
records, err := c.Apps.Network.DNS(ctx, appID)
if err != nil {
	log.Fatal(err)
}
for _, r := range records {
	fmt.Println(r.Type, r.Name, r.Value, r.Status) // Type: "txt" | "cname"
}
```

## Domínio personalizado

`Network.SetDomain(ctx, appID, domain)` associa um domínio personalizado (plano Standard ou superior). Passe `"@"` para removê-lo.

```go theme={"system"}
if err := c.Apps.Network.SetDomain(ctx, appID, "www.example.com"); err != nil {
	log.Fatal(err)
}

// Remove it
if err := c.Apps.Network.SetDomain(ctx, appID, "@"); err != nil {
	log.Fatal(err)
}
```

| Status | Código | Quando |
| - | - | - |
| 400 | `INVALID_DOMAIN` | Não é um nome de domínio válido |
| 400 | `RESERVED_DOMAIN` | Um domínio da Square Cloud |
| 403 | `UPGRADE_REQUIRED` | O plano não tem domínios personalizados |
| 403 | `LOAD_BALANCER_LIMIT_REACHED` | O limite de aplicações do plano neste domínio foi atingido |
| 409 | `DOMAIN_ALREADY_EXISTS` | O domínio pertence a uma aplicação de outra conta |
| 502 | `DNS_FAILED` | O provedor de borda recusou o domínio |

## Limpando o cache

`Network.PurgeCache(ctx, appID)` limpa o cache de borda da aplicação. É limitado a uma limpeza a cada 60 segundos (429 `KEEP_CALM`).

```go theme={"system"}
if err := c.Apps.Network.PurgeCache(ctx, appID); err != nil {
	log.Fatal(err)
}
```

## Erros dos métodos de analytics

| Status | Código | Quando |
| - | - | - |
| 400 | `INVALID_TIME_RANGE` | `start`/`end` ausente, malformado ou invertido |
| 400 | `INVALID_FILTER` | Um filtro não corresponde ao seu formato (`Analytics`) |
| 403 | `UPGRADE_REQUIRED` | `Logs` e `Performance` fora dos planos Pro e Enterprise |
| 429 | `RATE_LIMITED` | Limite compartilhado de cache misses atingido |
| 500 | `UNABLE_TO_FETCH_ANALYTICS`, `UNABLE_TO_FETCH_ERRORS`, `UNABLE_TO_FETCH_PERFORMANCE` | O provedor de borda falhou |
| 503 | `ANALYTICS_BUSY` | Os analytics de borda estão ocupados: tentado novamente de forma automática |

## Próximos passos

<CardGroup cols={3}>
  <Card title="Tempo real" icon="wave-pulse" href="/pt-br/sdks/go/realtime">
    Acompanhe logs e status ao vivo.
  </Card>

  <Card title="Referência da API de rede" icon="code" href="/pt-br/api-reference/endpoint/apps/network/analytics">
    Os endpoints REST por trás destes métodos.
  </Card>

  <Card title="Analytics de borda pela CLI" icon="terminal" href="/pt-br/cli-reference/edge-analytics">
    As mesmas ações pelo terminal.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.