> ## 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: logs e status ao vivo

> Acompanhe ao vivo os logs, o status e os eventos de sistema de uma aplicação com c.Apps.Realtime, um iterador que mescla o status e se reconecta sozinho.

`c.Apps.Realtime(ctx, appID)` abre um stream ao vivo dos logs, do status e dos eventos de sistema de uma aplicação e retorna um `*squarecloud.Realtime`. É um **iterador**: chame `Next` em um loop até que ele retorne um erro, e sempre chame `Close`.

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

import (
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"os"

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

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	c := squarecloud.New(os.Getenv("SQUARECLOUD_API_KEY"))
	appID := "abc123def456abc123def456"

	r, err := c.Apps.Realtime(ctx, appID)
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	for {
		ev, err := r.Next()
		if err != nil {
			if errors.Is(err, io.EOF) || ctx.Err() != nil {
				break // the stream ended, or ctx was canceled
			}
			log.Fatal(err)
		}

		switch ev.Event {
		case "logs":
			fmt.Println(ev.Stream, ev.Line) // "stdout" | "stderr"
		case "status":
			fmt.Println(ev.Status.CPU, ev.Status.RAM) // never nil: always the full, merged state
		default:
			fmt.Println(ev.Event, ev.Data) // "system", "error" or "message"
		}
	}
}
```

O `ctx` passado para `Realtime` governa o stream inteiro: `Next` não recebe argumentos. Para interromper, a partir de outra goroutine, um loop bloqueado em `Next`, cancele esse `ctx`.

## Eventos

Todo `RealtimeEvent` tem `Event`, `Data` (o texto bruto do frame) e `ID` (o id do último evento, `""` se não houver).

| `Event` | Campos extras | Descrição |
| - | - | - |
| `logs` | `Stream`, `Line` | Uma linha de log. O primeiro caractere de `Data` indica o stream (`\u0001` stdout, `\u0002` stderr); o SDK o remove em `Line` e define `Stream` como `"stdout"` ou `"stderr"` |
| `status` | `Status` | Métricas do container ao vivo. O primeiro frame é completo e os seguintes trazem apenas o que mudou: o SDK os mescla, então `Status` (um `*RealtimeStatus`, nunca `nil` neste evento) é sempre o estado completo |
| `system` | | Eventos de conexão como `REALTIME_CONNECTING \| <id>`, `REALTIME_TIMEOUT` ou `REALTIME_DISCONNECTED` |
| `error` | | Um código de erro como `CONTAINER_NOT_FOUND` |
| `message` | | Um frame sem nome de `event` |

### A struct `Status`

| Campo | Descrição |
| - | - |
| `CPU` (`cpu`) | Uso de CPU (%) |
| `CPULimit` (`cpuLimit`) | Número de núcleos de CPU alocados (por exemplo, `1` ou `0.5`) |
| `RAM` (`ram`) | `[usedMB, limitMB]` como um `[2]float64` |
| `Status` (`status`) | Estado do container, por exemplo `running` |
| `NetIO` (`netIO`) | Totais de rede `In`/`Out` (`i`, `o`), com `New` para o intervalo mais recente, em bytes por segundo |
| `BlockIO` (`bIO`) | Totais de disco `In`/`Out` (`i`, `o`) |
| `Uptime` (`uptime`) | Unix ms do início do container |

## Encerrando o stream

`Next` retorna `io.EOF` quando:

* o servidor fecha a conexão de forma limpa (cada conexão dura até **10 minutos**);
* o servidor envia `REALTIME_DISCONNECTED` (o evento é entregue primeiro, depois `io.EOF`);
* você chamou `Close`.

Quando o `ctx` passado para `Realtime` é cancelado ou seu prazo expira, `Next` retorna o `ctx.Err()` puro (`context.Canceled` ou `context.DeadlineExceeded`), não um `*APIError`. Para sair do loop por conta própria, basta usar `break`: o `Close` adiado com defer libera a conexão.

Para continuar acompanhando além de 10 minutos, chame `Realtime` novamente quando o loop terminar.

## Reconexão

Uma conexão perdida, ou o servidor delegando a reconexão ao cliente (`REALTIME_RECONNECT`), reabre o stream sozinho:

* até **3 vezes seguidas**; qualquer evento `logs` ou `status` zera a contagem;
* cada reabertura ocorre pelo menos **5,5 s** após a abertura anterior, para respeitar o ritmo da API de uma abertura a cada 5 segundos por aplicação.

O `Status` mesclado sobrevive às reconexões. Após 3 reconexões falhas, `Next` retorna um `*APIError` com `NETWORK_ERROR` (status `0`).

## Limites e erros

* **5** conexões simultâneas por conta e **30** por aplicação, somando todos os usuários. Ultrapassar resulta em 429 `REALTIME_MAX_CONNECTIONS` ou `REALTIME_MAX_CONNECTIONS_APP`.
* O status HTTP é verificado antes do streaming, então esses erros (e o 404 para uma aplicação desconhecida) são retornados pelo próprio `Realtime`, antes do primeiro `Next`.
* Quando o `ctx` não tem prazo, o prazo de `WithTimeout` cobre apenas a abertura, até os headers da resposta chegarem (`TIMEOUT` se não chegarem). O stream em si não tem prazo além do `ctx`.

## Próximos passos

<CardGroup cols={3}>
  <Card title="Snapshots" icon="clock-rotate-left" href="/pt-br/sdks/go/snapshots">
    Faça backup e restaure aplicações e bancos de dados.
  </Card>

  <Card title="Referência da API de tempo real" icon="code" href="/pt-br/api-reference/endpoint/apps/realtime">
    O endpoint REST por trás deste stream.
  </Card>

  <Card title="Logs pela CLI" icon="terminal" href="/pt-br/cli-reference/logs">
    O mesmo stream pelo terminal.
  </Card>
</CardGroup>


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