Melhorar o tempo de consulta com a indexação personalizada

Os índices personalizados no Cloud Logging permitem indexar campos LogEntry consultados com frequência nos buckets de registros para acelerar as consultas em dados de registro de alto volume. Além dos campos que o Logging indexa automaticamente, é possível configurar índices personalizados em campos de string ou de números inteiros para buckets novos ou atuais.

Visão geral

O desempenho da consulta é essencial para qualquer solução de geração de registros. À medida que as cargas de trabalho escalonar verticalmente e os volumes de registros correspondentes aumentam, a indexação dos dados de registros mais usados pode reduzir o tempo de consulta.

Para melhorar o desempenho da consulta, o Logging indexa automaticamente os seguintes campos LogEntry:

Além dos campos que o Logging indexa automaticamente, também é possível direcionar um bucket de registros para indexar outros campos LogEntry criando um índice personalizado para o bucket.

Por exemplo, suponha que suas expressões de consulta geralmente incluam o campo jsonPayload.request.status. É possível configurar um índice personalizado para um bucket que inclua jsonPayload.request.status. Qualquer consulta subsequente nos dados desse bucket fará referência aos dados indexados jsonPayload.request.status se a expressão de consulta incluir esse campo.

Usando a Google Cloud CLI ou a API Logging, é possível adicionar índices personalizados a buckets de registros novos ou atuais. Ao selecionar outros campos para incluir no índice personalizado, observe as seguintes limitações:

  • É possível adicionar até 20 campos por índice personalizado.
  • Depois de configurar ou atualizar o índice personalizado de um bucket, aguarde uma hora para que as alterações sejam aplicadas às consultas. Essa latência garante a precisão do resultado da consulta e aceita registros gravados no passado.
  • O Logging aplica a indexação personalizada aos dados armazenados em buckets de registro após a criação ou alteração do índice. As alterações nos índices personalizados não se aplicam retroativamente aos registros.

Antes de começar

Antes de começar a configurar um índice personalizado, faça o seguinte:

Definir o índice personalizado

Para cada campo adicionado ao índice personalizado de um bucket, você define dois atributos: um caminho e um tipo de campo:

  • fieldPath: descreve o caminho específico para o campo LogEntry nas entradas de registro. Por exemplo, jsonPayload.req_status.
  • type: indica se o campo é do tipo string ou inteiro. Os valores possíveis são INDEX_TYPE_STRING e INDEX_TYPE_INTEGER.

Para adicionar um índice personalizado, crie um novo bucket ou atualize um atual. Para mais informações sobre como configurar buckets, consulte Configurar buckets de registros.

Para configurar um índice personalizado ao criar um bucket, faça o seguinte:

gcloud

Use o comando gcloud logging buckets create e defina a flag --index:

gcloud logging buckets create BUCKET_NAME \
--location=LOCATION \
--description="DESCRIPTION" \
--index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE

Exemplo de comando:

gcloud logging buckets create int_index_test_bucket \
--location=global \
--description="Bucket with integer index" \
--index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER

API

Para criar um bucket, use projects.locations.buckets.create na API Logging. Prepare os argumentos do método da seguinte maneira:

  1. Defina o parâmetro parent como o recurso em que o bucket será criado: projects/PROJECT_ID/locations/LOCATION

    A variável LOCATION refere-se à região em que você quer que seus registros sejam armazenados.

    Por exemplo, se você quiser criar um bucket para o projeto my-project na região asia-east2, o parâmetro parent será semelhante a este: projects/my-project/locations/asia-east2

  2. Defina o parâmetro bucketId, por exemplo, my-bucket.

  3. No corpo da solicitação LogBucket, configure o objeto IndexConfig para criar o índice personalizado.

  4. Chame projects.locations.buckets.create para criar o bucket.

Para atualizar um bucket e incluir um índice personalizado, faça o seguinte:

gcloud

Use o comando gcloud logging buckets update e defina a flag --add-index:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--add-index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE

Exemplo de comando:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--add-index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER

API

Use projects.locations.buckets.patch na API Logging. No corpo da solicitação LogBucket, configure o objeto IndexConfig para incluir os campos LogEntry que você quer indexar.

Excluir um campo indexado personalizado

Para excluir um campo do índice personalizado de um bucket, faça o seguinte:

gcloud

Use o comando gcloud logging buckets update e defina a flag --remove-indexes :

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--remove-indexes=INDEX_FIELD_NAME

Exemplo de comando:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--remove-indexes=jsonPayload.req_status

API

Use projects.locations.buckets.patch na API Logging. No corpo da solicitação LogBucket, remova os campos LogEntry do objeto IndexConfig.

Atualizar o tipo de dados do campo indexado personalizado

Se você precisar corrigir o tipo de dados de um campo indexado personalizado, faça o seguinte:

gcloud

Use o comando gcloud logging buckets update e defina a flag --update-index:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--update-index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE

Exemplo de comando:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--update-index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER

API

Use projects.locations.buckets.patch na API Logging. No corpo da solicitação LogBucket, atualize o objeto IndexConfig para fornecer o tipo de dados correto para um campo LogEntry.

Atualizar o caminho de um campo indexado personalizado

Se você precisar corrigir o caminho de um campo indexado personalizado, faça o seguinte:

gcloud

Use o comando gcloud logging buckets update e defina as flags --remove-indexes e --update-index:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--remove-indexes=OLD_INDEX_FIELD_NAME \
--update-index=fieldPath=NEW_INDEX_FIELD_NAME,type=INDEX_TYPE

Exemplo de comando:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--remove-indexes=jsonPayload.req_status_old_path \
--add-index=fieldPath=jsonPayload.req_status_new_path,type=INDEX_TYPE_INTEGER

API

Use projects.locations.buckets.patch na API Logging. No corpo da solicitação LogBucket, atualize o objeto IndexConfig para fornecer o caminho de campo correto para um campo LogEntry.

Listar todos os campos indexados de um bucket

Para listar os detalhes de um bucket, incluindo os campos indexados personalizados, faça o seguinte:

gcloud

Use o comando gcloud logging buckets describe:

gcloud logging buckets describe BUCKET_NAME \
--location=LOCATION

Exemplo de comando:

gcloud logging buckets describe indexed-bucket \
--location global

API

Use projects.locations.buckets.get na API Logging.

Limpar campos indexados personalizados

Para remover todos os campos indexados personalizados de um bucket, faça o seguinte:

gcloud

Use o comando gcloud logging buckets update e adicione a flag --clear-indexes:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--clear-indexes

Exemplo de comando:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--clear-indexes

API

Use projects.locations.buckets.patch na API Logging. No corpo da solicitação LogBucket, exclua o objeto IndexConfig.

Consultar e visualizar dados indexados

Para consultar os dados incluídos em campos indexados personalizados, restrinja o escopo da consulta ao bucket que contém os campos indexados personalizados e especifique a visualização de registro apropriada:

gcloud

Para ler registros de um bucket de registros, use o comando gcloud logging read e adicione um LOG_FILTER para incluir seus dados indexados:

gcloud logging read LOG_FILTER --bucket=BUCKET_ID --location=LOCATION --view=LOG_VIEW_ID

API

Para ler registros de um bucket de registros, use o método entries.list. Defina resourceNames para especificar o bucket e a visualização de registro apropriados e defina filter para selecionar os dados indexados.

Para informações detalhadas sobre a sintaxe de filtragem, consulte Linguagem de consulta do Logging.

Indexação e tipos de campo

A forma como você configura a indexação de campos personalizados pode afetar como os registros são armazenados em buckets de registros e como as consultas são processadas.

No momento da gravação

O Logging tenta usar o índice personalizado em dados armazenados em buckets de registro após a criação do índice.

Os campos indexados são digitados, o que tem implicações para o carimbo de data/hora na entrada de registro. Quando a entrada de registro é armazenada no bucket de registros, o campo de registro é avaliado em relação ao tipo de índice usando estas regras:

  • Se o tipo de um campo for igual ao do índice, os dados serão adicionados ao índice de forma idêntica.
  • Se o tipo do campo for diferente do tipo do índice, a geração de registros vai tentar converter para o tipo do índice (por exemplo, de inteiro para string).
    • Se a coerção de tipo falhar, os dados não serão indexados. Quando a coerção de tipo é bem-sucedida, os dados são indexados.

No momento da consulta

Ativar um índice em um campo muda a forma como você precisa consultar esse campo. Por padrão, o Logging aplica restrições de filtro aos campos com base no tipo de dados em cada entrada de registro que está sendo avaliada. Quando a indexação está ativada, as restrições de filtro em um campo são aplicadas com base no tipo do índice. Adicionar um índice a um campo impõe um esquema a ele.

Quando um índice personalizado é configurado para um bucket, os comportamentos de correspondência de esquema são diferentes quando as duas condições a seguir são atendidas:

  • O tipo de dados de origem de um campo não corresponde ao tipo de índice desse campo.
  • O usuário aplica uma restrição a esse campo.

Considere os seguintes payloads JSON:

{"jsonPayload": {"name": "A", "value": 12345}}
{"jsonPayload": {"name": "B", "value": "3"}}

Agora aplique este filtro a cada um:

jsonPayload.value > 20

Se o campo jsonPayload.value não tiver indexação personalizada, o Logging vai aplicar a correspondência de tipo flexível:

  • Para "A", o Logging observa que o valor da chave "value" é, na verdade, um número inteiro e que a restrição "20" pode ser convertida em um número inteiro. O Logging avalia 12345 > 20 e retorna "true" porque esse é o caso numericamente.

  • Para "B", o Logging observa que o valor da chave "value" é, na verdade, uma string. Em seguida, ele avalia "3" > "20" e retorna "true", já que esse é o caso alfanumericamente.

Se o campo jsonPayload.value estiver incluído no índice personalizado, o Logging vai avaliar essa restrição usando o índice em vez da lógica usual do Logging. As mudanças de comportamento:

  • Se o índice for do tipo string, todas as comparações serão de string.
    • A entrada "A" não corresponde, já que "12345" não é maior que "20" alfanumericamente. A entrada "B" corresponde, já que a string "3" é maior que "20".
  • Se o índice for do tipo inteiro, todas as comparações serão de números inteiros.
    • A entrada "B" não corresponde, já que "3" não é maior que "20" numericamente. A entrada "A" corresponde, já que "12345" é maior que "20".

Essa diferença de comportamento é sutil e precisa ser considerada ao definir e usar índices personalizados.

Como filtrar casos extremos

Para o índice do tipo inteiro jsonPayload.value, suponha que um valor de string seja filtrado:

jsonPayload.value = "hello"

Se o valor da consulta não puder ser convertido para o tipo de índice, o índice será ignorado.

No entanto, suponha que, para um índice do tipo string, você transmita um valor inteiro:

jsonPayload.value > 50

Nem A nem B correspondem, já que nem "12345" nem "3" são alfanumericamente maiores que "50".