Todos os produtos
Search
Central de documentação

Simple Log Service:Referência geral

Última atualização: Jul 03, 2026

Fornece referências gerais para o uso da Structured Process Language (SPL) em diferentes cenários.

Otimização de instruções SPL

Várias instruções SPL podem produzir o mesmo resultado de processamento de dados. Escrever instruções SPL concisas e eficientes simplifica a manutenção e melhora o desempenho. A tabela a seguir apresenta algumas sugestões.

Sugestão

Antes da otimização

Após a otimização

Combine cláusulas where consecutivas em uma única cláusula.

*
| where request_method = 'POST'
| where cast(status as integer) >= 500
*
| where request_method = 'POST' and cast(status as integer) >= 500

Agrupe cláusulas extend consecutivas em uma só.

*
| extend k1 = 'v1'
| extend k2 = 'v2'
| extend k3 = 'v3'
*
| extend k1 = 'v1', k2 = 'v2', k3 = 'v3'

Substitua a combinação de extend e project-away por project-rename.

*
| extend method = request_method
| project-away request_method
*
| project-rename method = request_method

Modifique os valores dos campos diretamente em vez de usar extend para criar novos campos, exceto quando necessário.

*
| extend newContent = json_extract(content, 'abc \d+')
| project-away content
*
| extend content = json_extract(content, 'abc \d+')

Tratamento de campos especiais

Campos de tempo

Durante a execução da SPL, o tipo de dados dos campos de tempo nos logs do Simple Log Service é sempre INTEGER ou BIGINT. Esses campos incluem o campo de timestamp de dados __time__ e a parte em nanossegundos do timestamp de dados __time_ns_part__.

Para atualizar o timestamp dos dados, use a instrução extend e garanta que o novo valor seja do tipo INTEGER ou BIGINT. Outras instruções não operam em campos de tempo. O comportamento delas é descrito a seguir:

  • project, project-away e project-rename: Essas instruções mantêm os campos de tempo por padrão. Não é possível renomeá-los ou sobrescrevê-los.

  • parse-regexp e parse-json: Se o resultado da extração incluir campos de tempo, eles serão ignorados.

Exemplo

Extraia valores de campos de tempo a partir de uma string de tempo existente.

  • Instrução SPL

    * 
    | parse-regexp time, '([\d\-\s:]+)\.(\d+)' as ts, ms
    | extend ts=date_parse(ts, '%Y-%m-%d %H:%i:%S')
    | extend __time__=cast(to_unixtime(ts) as INTEGER)
    | extend __time_ns_part__=cast(ms as INTEGER) * 1000000
    | project-away ts, ms
  • Dados de entrada

    time: '2023-11-11 01:23:45.678'
  • Resultado de saída

    __time__: 1699637025
    __time_ns_part__: 678000000
    time: '2023-11-11 01:23:45.678'

Nomes de campos com caracteres especiais

Se um nome de campo contiver espaços ou outros caracteres especiais, coloque-o entre aspas duplas (") ao referenciá-lo. Por exemplo, se um campo for nomeado como A B, contendo um espaço, referencie-o como "A B" na instrução SPL:

* | where "A B" like '%error%'

Nomes de campos sem distinção entre maiúsculas e minúsculas

Nas consultas de varredura do SLS, os nomes de campos referenciados nas instruções SPL não diferenciam maiúsculas de minúsculas. Por exemplo, se um log contiver um campo chamado Method, você poderá referenciá-lo como method ou METHOD na instrução SPL.

Importante

Isso se aplica ao recurso de consulta de varredura do Simple Log Service. Para mais informações, consulte Consultas de varredura.

Exemplo

Use um nome de campo sem distinção entre maiúsculas e minúsculas em uma cláusula where.

  • Instrução SPL

    * | where METHOD like 'Post%'
  • Dados de entrada

    Method: 'PostLogstoreLogs'
  • Resultado de saída

    Method: 'PostLogstoreLogs'

Resolução de conflitos de nomes de campos

Durante o upload de logs ou a execução da SPL, o processamento sensível a maiúsculas e minúsculas pode causar conflitos de nomes de campos. Por exemplo, um log bruto pode conter tanto o campo Method quanto o campo method. A SPL resolve esses conflitos de maneiras diferentes, dependendo do cenário.

Para evitar essas situações, padronize os nomes dos campos em seus logs brutos.

Conflitos nos dados de entrada

Se um log bruto contiver campos cujos nomes sejam idênticos ao ignorar a diferenciação entre maiúsculas e minúsculas, como Status e status, a SPL selecionará aleatoriamente um dos campos para entrada e descartará o outro. Por exemplo:

  • Instrução SPL

    * | extend status_cast = cast(status as bigint)
  • Dados de entrada

    Status: '200'
    status: '404'
  • Resultado do processamento

    • Possibilidade 1: O valor do campo Status é mantido.

      Status: '200' -- The first column is retained, and the second column is discarded.
      status_cast: '200'
    • Possibilidade 2: O valor do campo status é mantido.

      status: '404' -- The second column is retained, and the first column is discarded.
      Status_cast: '404'

Conflitos nos resultados de saída

Cenário 1: Conflitos de campos de dados brutos

Durante a execução da SPL, podem ser gerados campos com nomes idênticos ao ignorar a diferenciação entre maiúsculas e minúsculas. A SPL seleciona aleatoriamente um deles para a saída. Por exemplo, se um campo de log contiver uma string JSON, o uso da instrução parse-json pode criar campos com nomes conflitantes:

  • Instrução SPL

    * | parse-json content
  • Dados de entrada

    content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
  • Resultado de saída

    • Possibilidade 1: O campo Method é mantido.

      content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
      Method: 'PostLogs' -- The Method field is retained.
      status: '200'
    • Possibilidade 2: O campo method é mantido.

      content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
      method: 'GetLogs' -- The method field is retained.
      status: '200'

Cenário 2: Conflitos com novos campos de dados gerados

Para evitar ambiguidades, a SPL preserva a capitalização dos nomes de novos campos gerados explicitamente pelas instruções. Isso se aplica aos nomes de campos gerados pela instrução extend e aos nomes de campos especificados explicitamente usando as nas instruções parse-regexp e parse-csv.

Por exemplo, se você usar extend para criar um novo campo Method, o nome do campo resultante permanecerá Method.

  • Instrução SPL

    * | extend Method = 'Post'
  • Dados de entrada

    Status: '200'
  • Resultado de saída

    Status: '200'
    Method: 'Post'

Tratamento de conflitos de campos reservados do SLS

Importante

Isso se aplica aos recursos de consumo em tempo real e consulta de varredura do Simple Log Service.

Para obter a lista completa de campos reservados, consulte Campos reservados. A SPL lê dados da estrutura LogGroup como entrada. Para mais informações sobre a definição de LogGroup, consulte Codificação de dados. Se os dados brutos gravados no Simple Log Service não estiverem codificados no formato padrão LogGroup, alguns campos reservados poderão aparecer em LogContent em vez de sua localização padrão. A SPL trata esses campos reservados da seguinte forma:

  • Para os campos __source__, __topic__, __time__ e __time_ns_part__, a SPL lê seus valores da estrutura padrão LogGroup e ignora quaisquer campos com os mesmos nomes em LogContent.

  • Para campos de tag com o prefixo __tag__: , a SPL tenta primeiro ler seus valores da estrutura padrão LogGroup. Se nenhum valor for encontrado, a SPL o lê de LogContent. Por exemplo, para o campo __tag__:ip, a SPL tenta primeiro ler o campo com a chave ip da lista LogTag. Se o campo não existir, a SPL então lê o campo de log com a chave __tag__:ip dos campos de log personalizados em LogContent.

O campo __line__ para pesquisa de texto completo

Importante

Isso se aplica ao recurso de consulta de varredura do SLS.

Para filtrar logs brutos no console ou usando a operação de API GetLogstoreLogs, use o campo __line__.

Exemplo

  • Pesquise a palavra-chave error nos logs.

    * | where __line__ like '%error%'
  • Se um log contiver um campo chamado __line__, coloque o nome do campo entre crases para referenciá-lo.

    * | where `__line__` ='20'

Políticas de retenção e sobrescrita de valores

Quando uma instrução SPL é executada e um campo de saída tem o mesmo nome que um campo de entrada existente, o valor do campo é determinado pela seguinte política:

Importante

Essas políticas não se aplicam à instrução extend. Para extend, se houver conflito de nome de campo, o novo valor será sempre utilizado.

Tipos de dados inconsistentes entre valores antigos e novos

O valor original do campo de entrada é mantido.

Exemplo

  • Exemplo 1: Um campo renomeado por uma instrução project tem um nome conflitante.

    • Instrução SPL

      * 
      | extend status=cast(status as BIGINT) -- Convert the type of the status field to BIGINT.
      | project code=status -- The new value's type (BIGINT) differs from the old value's type (VARCHAR), so the old value is kept.
    • Dados de entrada

      status: '200'
      code: 'Success'
    • Resultado de saída

      code: 'Success'
  • Exemplo 2: Um campo extraído por uma instrução parse-json tem um nome conflitante.

    • Instrução SPL

      * 
      | extend status=cast(status as BIGINT) -- Convert the type of the status field to BIGINT.
      | parse-json content -- The old type of status is BIGINT and the new type is VARCHAR. The old value is retained.
    • Dados de entrada

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Resultado de saída

      content: '{"status": "Success", "body": "this is test"}'
      status: 200
      body: 'this is test'

Tipos de dados consistentes entre valores antigos e novos

Se o valor de entrada for nulo, o novo valor será usado. Caso contrário, o comportamento é determinado pelo parâmetro mode na instrução, conforme definido na tabela a seguir.

Importante

Se o parâmetro mode não for especificado na instrução, seu valor padrão será overwrite.

Modo

Descrição

overwrite

Sobrescreve o valor antigo com o novo valor.

preserve

Mantém o valor antigo e descarta o novo valor.

Exemplo

  • Exemplo 1: Um campo renomeado por uma instrução project tem um nome conflitante e o mesmo tipo. O modo padrão é overwrite.

    • Instrução SPL

    * | project code=status -- The old and new types of code are both VARCHAR. The new value is used based on the overwrite mode.
    • Dados de entrada

      status: '200'
      code: 'Success'
    • Resultado de saída

      code: '200'
  • Exemplo 2: Um campo extraído por uma instrução parse-json tem um nome conflitante e o mesmo tipo. O modo padrão é overwrite.

    • Instrução SPL

      * | parse-json content -- The old and new types of status are both VARCHAR. The new value is used based on the overwrite mode.
    • Dados de entrada

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Resultado de saída

      content: '{"status": "Success", "body": "this is test"}'
      status: 'Success'
      body: 'this is test'
  • Exemplo 3: Um campo extraído por uma instrução parse-json tem um nome conflitante e o mesmo tipo. O modo está definido como preserve.

    • Instrução SPL

      * | parse-json -mode='preserve' content -- The old and new types of status are both VARCHAR. The old value is retained based on the preserve mode.
    • Dados de entrada

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Resultado de saída

      content: '{"status": "Success", "body": "this is test"}'
      status: '200'
      body: 'this is test'

Conversão de tipos de dados

Tipo inicial

Quando a SPL processa dados, todos os campos de entrada são inicialmente do tipo VARCHAR, exceto os campos de tempo de log. Se o processamento subsequente exigir um tipo de dados diferente, converta o tipo explicitamente.

Exemplo

Para filtrar logs de acesso com código de status 5xx, converta o campo status para o tipo BIGINT antes da comparação.

* -- The initial type of the status field is VARCHAR.
| where cast(status as BIGINT) >= 500 -- Convert the type of the status field to BIGINT, and then perform the comparison.

Retenção de tipo

Após usar a instrução extend para converter o tipo de dados de um campo, o processamento subsequente mantém o tipo convertido.

Exemplo

* -- A Logstore is used as input data. Except for time fields, all fields are initially of the VARCHAR type.
| where __source__='127.0.0.1' -- Filter on the __source__ field.
| extend status=cast(status as BIGINT) -- Convert the type of the status field to BIGINT.
| project status, content
| where status>=500 -- The type of the status field remains BIGINT, so it can be directly compared with the number 500.

Tratamento de valores nulos em expressões SPL

Geração de valores nulos

Durante o processamento de dados da SPL, valores nulos são gerados nos seguintes cenários:

  1. Se um campo usado em uma expressão SPL não existir nos dados de entrada, seu valor será tratado como nulo durante os cálculos.

  2. Se ocorrer uma exceção durante o cálculo de uma expressão SPL, o resultado será nulo. Por exemplo, quando uma conversão de tipo cast falha ou um índice de array está fora dos limites.

Exemplo

  1. Se um campo não existir, seu valor será tratado como nulo nos cálculos.

    • Instrução SPL

      * | extend withoutStatus=(status is null)
    • Dados de entrada

      # Entry 1
      status: '200'
      code: 'Success'
      
      # Entry 2
      code: 'Success'
    • Resultado de saída

      # Entry 1
      status: '200'
      code: 'Success'
      withoutStatus: false
      
      # Entry 2
      code: 'Success'
      withoutStatus: true
  2. Se ocorrer uma exceção durante o cálculo, o resultado será nulo.

    • Instrução SPL

      *
      | extend code=cast(code as BIGINT) -- Failed to convert the code field to BIGINT.
      | extend values=json_parse(values)
      | extend values=cast(values as ARRAY(BIGINT))
      | extend last=arr[10] -- Array index out of bounds.
    • Dados de entrada

      status: '200'
      code: 'Success'
      values: '[1,2,3]'
    • Resultado de saída

      status: '200'
      code: null
      values: [1, 2, 3]
      last: null

Eliminação de valores nulos

Para eliminar valores nulos durante os cálculos, use a expressão COALESCE. Ela retorna o primeiro valor não nulo de uma lista de expressões. Também é possível especificar um valor padrão para uso caso todas as expressões resultem em nulo.

Exemplo

Leia o último elemento de um array. Se o array estiver vazio, o valor padrão será 0.

  • Instrução SPL

    *
    | extend values=json_parse(values)
    | extend values=cast(values as ARRAY(BIGINT))
    | extend last=COALESCE(values[3], values[2], values[1], 0)
  • Dados de entrada

    # Entry 1
    values: '[1, 2, 3]'
    
    # Entry 2
    values: '[]'
  • Resultado de saída

    # Entry 1
    values: [1, 2, 3]
    last: 3
    
    # Entry 2
    values: []
    last: 0

Escape de caracteres

Aspas simples

Aspas simples delimitam literais de string. Se o literal de string contiver uma aspa simples, use uma aspa simples adicional para escapá-la.

Exemplo

  • Instrução SPL

    *
    | extend user = 'Alice'
    | extend phone = 'Alice''s Phone'
  • Resultado de saída

    user: Alice
    phone: Alice's Phone

Aspas duplas

Aspas duplas delimitam nomes de campos. Se o nome do campo contiver uma aspa dupla, use uma aspa dupla adicional para escapá-la.

Exemplo

  • Instrução SPL

    *
    | extend user_name = 'Alice'
    | extend "user name" = 'Alice'
    | extend "user""name" = 'Alice'
  • Resultado de saída

    user_name: Alice
    user name: Alice
    user"name: Alice

Outros caracteres especiais

Exemplo 1

Na SPL, a barra invertida (\) não é um caractere de escape e, portanto, é preservada como está.

  • Instrução SPL

    *
    | extend a = 'foo\tbar'
    | extend b = 'foo\nbar'
  • Resultado de saída

    a: foo\tbar
    b: foo\nbar

Exemplo 2

Se uma string precisar incluir caracteres especiais, como tabulação ou nova linha, use a função chr para concatenar strings.

  • Instrução SPL

    *
    | extend a = concat('foo', chr(9), 'bar')
    | extend b = concat('foo', chr(10), 'bar')
  • Resultado de saída

    a: foo	bar
    b: foo
    bar

Tratamento de erros

Erro de sintaxe

Erros de sintaxe ocorrem quando uma instrução SPL está malformada, como nome de instrução incorreto, erro de referência de palavra-chave ou erro de especificação de tipo. Quando ocorre um erro de sintaxe, a SPL não processa nenhum dado. Corrija a instrução com base na mensagem de erro.

Erro de dados

Um erro de dados ocorre quando uma função ou conversão falha durante a execução da SPL. A SPL define o campo resultante como null. Como erros de dados podem ocorrer em qualquer linha, a SPL faz uma amostragem aleatória e retorna apenas algumas mensagens de erro. Você pode ignorar esses erros ou modificar a instrução SPL com base no conteúdo dos dados.

Erros de dados não interrompem todo o processo de execução. A instrução SPL ainda retorna resultados, mas o campo onde ocorreu o erro é definido como null.

Tempo limite de execução

Uma instrução SPL contém várias instruções, e seus tempos de execução variam dependendo do cenário de dados. Se o tempo total de execução exceder o período de tempo limite padrão, a execução será interrompida e um erro de tempo limite será retornado com um resultado vazio. O período de tempo limite padrão varia para consultas de varredura, consumo em tempo real e coleta Logtail.

Para resolver esse erro, simplifique sua instrução SPL para reduzir sua complexidade, por exemplo, otimizando expressões regulares complexas ou reduzindo o número de pipelines.

Limite de memória excedido

Uma instrução SPL contém várias instruções, e seu consumo de memória varia dependendo do cenário de dados. A execução da SPL é limitada a uma cota de memória específica. Se essa cota for excedida, a execução falhará e um erro de limite de memória excedido será retornado com um resultado vazio. A cota de memória padrão varia para consultas de varredura, consumo em tempo real e coleta Logtail.

Para resolver esse erro, simplifique sua instrução SPL para reduzir sua complexidade, diminua o número de pipelines ou verifique se o tamanho dos dados brutos é excessivo.