> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Este motor permite processar arquivos de log de aplicativos como um fluxo de registros.

# Motor de tabela FileLog

Este motor permite processar arquivos de log de aplicativos como um fluxo de registros.

`FileLog` permite que você:

* Monitore arquivos de log.
* Processe novos registros à medida que são adicionados aos arquivos de log monitorados.

## Criando uma tabela

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = FileLog('path_to_logs', 'format_name') SETTINGS
    [poll_timeout_ms = 0,]
    [poll_max_batch_size = 0,]
    [max_block_size = 0,]
    [max_threads = 0,]
    [poll_directory_watch_events_backoff_init = 500,]
    [poll_directory_watch_events_backoff_max = 32000,]
    [poll_directory_watch_events_backoff_factor = 2,]
    [handle_error_mode = 'default']
```

Argumentos do motor:

* `path_to_logs` – Caminho para os arquivos de log aos quais assinar. Pode ser o caminho para um diretório com arquivos de log ou para um único arquivo de log. Observe que o ClickHouse permite apenas caminhos dentro do diretório `user_files`.
* `format_name` - Formato do registro. Observe que o FileLog processa cada linha de um arquivo como um registro separado, e nem todos os formatos de dados são adequados para isso.

Parâmetros opcionais:

* `poll_timeout_ms` - Timeout para um único poll do arquivo de log. Padrão: [stream\_poll\_timeout\_ms](/pt-BR/reference/settings/session-settings/stream#stream_poll_timeout_ms).
* `poll_max_batch_size` — Quantidade máxima de registros a serem obtidos em um único poll. Padrão: [max\_block\_size](/pt-BR/reference/settings/session-settings/max#max_block_size).
* `max_block_size` — Tamanho máximo do lote (em registros) para o poll. Padrão: [max\_insert\_block\_size](/pt-BR/reference/settings/session-settings/max-insert#max_insert_block_size).
* `max_threads` - Número máximo de threads para analisar arquivos; o padrão é 0, o que significa que o número será max(1, physical\_cpu\_cores / 4).
* `poll_directory_watch_events_backoff_init` - Valor inicial de espera para a thread de monitoramento do diretório. Padrão: `500`.
* `poll_directory_watch_events_backoff_max` - Valor máximo de espera para a thread de monitoramento do diretório. Padrão: `32000`.
* `poll_directory_watch_events_backoff_factor` - Velocidade do backoff, exponencial por padrão. Padrão: `2`.
* `handle_error_mode` — Como tratar erros no motor FileLog. Valores possíveis: default (uma exceção será lançada se não for possível analisar uma mensagem), stream (a mensagem da exceção e a mensagem bruta serão salvas nas colunas virtuais `_error` e `_raw_message`).

## Descrição

Os registros recebidos são rastreados automaticamente, portanto cada registro em um arquivo de log é contabilizado apenas uma vez.

`SELECT` não é particularmente útil para ler registros (exceto para depuração), porque cada registro só pode ser lido uma vez. É mais prático criar fluxos em tempo real usando [visões materializadas](/pt-BR/reference/statements/create/view). Para fazer isso:

1. Use o motor para criar uma tabela FileLog e trate-a como um fluxo de dados.
2. Crie uma tabela com a estrutura desejada.
3. Crie uma visão materializada que converta os dados do motor e os grave em uma tabela criada anteriormente.

Quando a `MATERIALIZED VIEW` é associada ao motor, ela começa a coletar dados em segundo plano. Isso permite que você receba continuamente registros de arquivos de log e os converta para o formato necessário usando `SELECT`.
Uma tabela FileLog pode ter quantas visões materializadas você quiser; elas não leem dados da tabela diretamente, mas recebem novos registros (em blocos). Dessa forma, você pode gravar em várias tabelas com diferentes níveis de detalhamento (com agrupamento - agregação e sem).

Exemplo:

```sql theme={null}
CREATE TABLE logs (
    timestamp UInt64,
    level String,
    message String
  ) ENGINE = FileLog('user_files/my_app/app.log', 'JSONEachRow');

CREATE TABLE daily (
    day Date,
    level String,
    total UInt64
  ) ENGINE = SummingMergeTree
  PARTITION BY toYYYYMM(day)
  ORDER BY (day, level);

CREATE MATERIALIZED VIEW consumer TO daily
    AS SELECT toDate(toDateTime(timestamp)) AS day, level, count() AS total
    FROM logs GROUP BY day, level;

SELECT level, sum(total) FROM daily GROUP BY level;
```

Para deixar de receber dados dos fluxos ou alterar a lógica de conversão, desanexe a visão materializada:

```sql theme={null}
DETACH TABLE consumer;
ATTACH TABLE consumer;
```

Se você quiser alterar a tabela de destino usando `ALTER`, recomendamos desativar a visão materializada para evitar discrepâncias entre a tabela de destino e os dados provenientes da view.

## Colunas virtuais

* `_filename` - Nome do arquivo de log. Tipo de dado: `LowCardinality(String)`.
* `_offset` - Offset no arquivo de log. Tipo de dado: `UInt64`.

Colunas virtuais adicionais quando `handle_error_mode='stream'`:

* `_raw_record` - Registro bruto que não pôde ser processado com sucesso. Tipo de dado: `Nullable(String)`.
* `_error` - Mensagem da exceção gerada durante a falha de parsing. Tipo de dado: `Nullable(String)`.

Observação: as colunas virtuais `_raw_record` e `_error` são preenchidas apenas em caso de exceção durante o parsing; elas sempre são `NULL` quando a mensagem é processada com sucesso.

## Durabilidade dos dados

O motor `FileLog` registra o offset consumido de um fragmento antes que o insert ao qual ele pertence seja confirmado; portanto, a interrupção do servidor pode fazer com que o offset registrado fique adiantado em relação aos dados que chegaram à tabela de destino. Ao reiniciar, cada arquivo de log é retomado a partir do offset registrado em seu diretório de metadados, de modo que essas linhas nunca são lidas novamente: elas são perdidas sem gerar erro, e `count()` simplesmente retorna um valor menor. Uma falha comum de processo é suficiente para expor esse problema e não exige perda de energia, pois o offset é registrado em um arquivo de metadados renomeado para o local definitivo enquanto a parte de destino ainda está sendo gravada.

A perda do cache de páginas do SO também pode descartar dados que já haviam sido gravados na tabela de destino; por exemplo, em caso de perda de energia no nível do dispositivo ou reinicialização inadequada do host ou do kernel. Os arquivos de metadados que armazenam os offsets são gravados sem `fsync` do arquivo ou de seu diretório, portanto também não oferecem garantia própria de durabilidade.

Diferentemente dos motores de broker de mensagens, não é possível proteger o `FileLog` contra isso tornando primeiro o destino durável. Como o offset é registrado dentro do pipeline de leitura, antes da conclusão do insert ao qual pertence, definir `fsync_after_insert = 1` nas tabelas `MergeTree` de destino não torna a parte inserida durável antes do avanço do offset. Trate o consumo do `FileLog` como acompanhamento de arquivos locais sem garantias: quando nenhuma linha puder ser perdida, mantenha os arquivos de log de origem até verificar os dados consumidos no destino, para que o consumo possa ser repetido. Remover e recriar a tabela descarta os offsets registrados e relê os arquivos desde o início.
