Etapa 8-adicionando diagnósticos

Este tutorial de várias partes aborda a criação de uma nova extensão de fonte de dados para Power Query. O tutorial deve ser feito sequencialmente — cada lição se baseia no conector criado nas lições anteriores, adicionando incrementalmente novos recursos ao seu conector.

Nesta lição, você vai:

  • Saiba mais sobre a função Diagnostics. Trace
  • Use as funções auxiliares de diagnóstico para adicionar informações de rastreamento para ajudar a depurar seu conector

Habilitando o diagnóstico

Power Query os usuários podem habilitar o log de rastreamento marcando a caixa de seleção em Opções | Diagnóstico.

Habilite o rastreamento no Power Query.

Uma vez habilitada, todas as consultas subsequentes farão com que o mecanismo M emita informações de rastreamento para arquivos de log localizados em um diretório de usuário fixo.

Ao executar consultas M de dentro do SDK do Power Query, o rastreamento é habilitado no nível do projeto. Na página Propriedades do projeto, há três configurações relacionadas ao rastreamento:

  • Limpar log — Quando isso for definido como true , o log será redefinido/limpo quando você executar suas consultas. Recomendamos que você mantenha esse conjunto como true .
  • Mostrar rastreamentos — do mecanismo Essa configuração controla a saída de rastreamentos internos do mecanismo M. Esses rastreamentos geralmente são úteis apenas para membros da equipe de Power Query, portanto, você normalmente desejará manter esse conjunto como false .
  • Mostrar rastreamentos — de usuário Essa configuração controla a saída de informações de rastreamento por seu conector. Você desejará definir isso como true .

propriedades de Project.

Uma vez habilitado, você começará a ver as entradas de log na janela saída da consulta M, na guia log.

Diagnostics.Trace

A função Diagnostics. Trace é usada para gravar mensagens no log de rastreamento do mecanismo M.

Diagnostics.Trace = (traceLevel as number, message as text, value as any, optional delayed as nullable logical as any) => ...

Importante

M é uma linguagem funcional com avaliação lenta. Ao usar Diagnostics.Trace , tenha em mente que a função só será chamada se a expressão da qual faz parte for realmente avaliada. Exemplos disso podem ser encontrados posteriormente neste tutorial.

O traceLevel parâmetro pode ser um dos seguintes valores (em ordem decrescente):

  • TraceLevel.Critical
  • TraceLevel.Error
  • TraceLevel.Warning
  • TraceLevel.Information
  • TraceLevel.Verbose

Quando o rastreamento está habilitado, o usuário pode selecionar o nível máximo de mensagens que gostaria de ver. Todas as mensagens de rastreamento desse nível e sob serão enviadas para o log. Por exemplo, se o usuário selecionar o nível "aviso", rastrear mensagens de TraceLevel.Warning , TraceLevel.Error e TraceLevel.Critical apareceria nos logs.

O message parâmetro é o texto real que será impresso para o arquivo de rastreamento. Observe que o texto não conterá o value parâmetro, a menos que você o inclua explicitamente no texto.

O value parâmetro é o que a função retornará. Quando o delayed parâmetro for definido como true , value será uma função de parâmetro zero que retorna o valor real que você está avaliando. Quando delayed é definido como false , value será o valor real. Um exemplo de como isso funciona pode ser encontrado abaixo.

Usando Diagnostics. Trace no conector de espilhamento

Para obter um exemplo prático de como usar Diagnostics. Trace e o impacto do delayed parâmetro, atualize a função do conector de busca GetSchemaForEntity para encapsular a error exceção:

GetSchemaForEntity = (entity as text) as type =>
    try
        SchemaTable{[Entity=entity]}[Type]
    otherwise
        let
            message = Text.Format("Couldn't find entity: '#{0}'", {entity})
        in
            Diagnostics.Trace(TraceLevel.Error, message, () => error message, true);

Você pode forçar um erro durante a avaliação (para fins de teste!) passando um nome de entidade inválido para a GetEntity função. Aqui, você altera a withData linha na TripPinNavTable função, substituindo [Name] por "DoesNotExist" .

TripPinNavTable = (url as text) as table =>
    let
        // Use our schema table as the source of top level items in the navigation tree
        entities = Table.SelectColumns(SchemaTable, {"Entity"}),
        rename = Table.RenameColumns(entities, {{"Entity", "Name"}}),
        // Add Data as a calculated column
        withData = Table.AddColumn(rename, "Data", each GetEntity(url, "DoesNotExist"), type table),
        // Add ItemKind and ItemName as fixed text values
        withItemKind = Table.AddColumn(withData, "ItemKind", each "Table", type text),
        withItemName = Table.AddColumn(withItemKind, "ItemName", each "Table", type text),
        // Indicate that the node should not be expandable
        withIsLeaf = Table.AddColumn(withItemName, "IsLeaf", each true, type logical),
        // Generate the nav table
        navTable = Table.ToNavigationTable(withIsLeaf, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
    in
        navTable;

Habilite o rastreamento para seu projeto e execute suas consultas de teste. Na Errors guia, você deve ver o texto do erro gerado:

Mensagem de erro.

Além disso, na Log guia, você deve ver a mesma mensagem. Observe que, se você usar valores diferentes para message os value parâmetros e, eles seriam diferentes.

Log de erros.

Observe também que o Action campo da mensagem de log contém o nome (tipo de fonte de dados) de sua extensão (nesse caso, Engine/Extension/TripPin ). Isso facilita a localização das mensagens relacionadas à sua extensão quando há várias consultas envolvidas e/ou o rastreamento do sistema (mecanismo do mashup) está habilitado.

Avaliação atrasada

Como um exemplo de como o delayed parâmetro funciona, você fará algumas modificações e executará as consultas novamente.

Primeiro, defina o delayed valor como false , mas deixe o value parâmetro como está:

Diagnostics.Trace(TraceLevel.Error, message, () => error message, false);

Ao executar a consulta, você receberá um erro de que "não é possível converter um valor do tipo function para tipo Type", e não o erro real que você gerou. Isso ocorre porque a chamada agora está retornando um function valor, em vez do próprio valor.

Em seguida, remova a função do value parâmetro:

Diagnostics.Trace(TraceLevel.Error, message, error message, false);

Ao executar a consulta, você receberá o erro correto, mas se você marcar a guia log , não haverá nenhuma mensagem. Isso ocorre porque o error acaba sendo gerado/avaliado durante a chamada para Diagnostics.Trace , para que a mensagem nunca seja realmente saída.

Agora que você entendeu o impacto do delayed parâmetro, certifique-se de redefinir o conector de volta para um estado de funcionamento antes de continuar.

Funções auxiliares de diagnóstico em Diagnostics. PQM

O arquivo Diagnostics. PQM incluído neste projeto contém várias funções auxiliares que facilitam o rastreamento. Conforme mostrado no tutorial anterior, você pode incluir esse arquivo em seu projeto (lembrando de definir a ação de compilação a ser compilada) e, em seguida, carregá-lo no arquivo do conector. A parte inferior do arquivo do conector agora deve ser semelhante ao trecho de código abaixo. Sinta-se à vontade para explorar as várias funções que este módulo fornece, mas neste exemplo, você usará apenas as Diagnostics.LogValue Diagnostics.LogFailure funções e.

// Diagnostics module contains multiple functions. We can take the ones we need.
Diagnostics = Extension.LoadFunction("Diagnostics.pqm");
Diagnostics.LogValue = Diagnostics[LogValue];
Diagnostics.LogFailure = Diagnostics[LogFailure];

Diagnostics. LogValue

A Diagnostics.LogValue função é muito parecida Diagnostics.Trace com e pode ser usada para gerar o valor do que você está avaliando.

Diagnostics.LogValue = (prefix as text, value as any) as any => ...

O prefix parâmetro é anexado à mensagem de log. Você o usaria para descobrir qual chamada gera a mensagem. O value parâmetro é o que a função retornará e também será gravada no rastreamento como uma representação de texto do valor M. Por exemplo, se value for igual a a table com as colunas a e B, o log conterá a #table representação equivalente: #table({"A", "B"}, {{"row1 A", "row1 B"}, {"row2 A", row2 B"}})

Observação

A serialização de valores M para texto pode ser uma operação cara. Esteja atento ao tamanho potencial dos valores que você está gerando no rastreamento.

Observação

A maioria dos ambientes de Power Query truncará as mensagens de rastreamento para um comprimento máximo.

Como exemplo, você atualizará a TripPin.Feed função para rastrear os url argumentos e schema passados para a função.

TripPin.Feed = (url as text, optional schema as type) as table =>
    let
        _url = Diagnostics.LogValue("Accessing url", url),
        _schema = Diagnostics.LogValue("Schema type", schema),
        //result = GetAllPagesByNextLink(url, schema)
        result = GetAllPagesByNextLink(_url, _schema)
    in
        result;

Observe que você precisa usar os novos _url valores e _schema na chamada para GetAllPagesByNextLink . Se você usou os parâmetros da função original, as Diagnostics.LogValue chamadas nunca seriam realmente avaliadas, resultando em nenhuma mensagem gravada no rastreamento. A programação funcional é divertida!

Ao executar suas consultas, agora você deve ver novas mensagens no log.

Acessando URL:  acessando mensagem de URL.

Tipo de esquema:  mensagem de tipo de esquema.

Observe que você vê a versão serializada do schema parâmetro type , em vez do que você obteria quando faz um simples Text.FromValue em um valor de tipo (que resulta em "Type").

Diagnostics. LogFailure

A Diagnostics.LogFailure função pode ser usada para encapsular chamadas de função e gravará somente no rastreamento se a chamada de função falhar (ou seja, retornar um error ).

Diagnostics.LogFailure = (text as text, function as function) as any => ...

Internamente, Diagnostics.LogFailure adiciona um try operador à function chamada. Se a chamada falhar, o text valor será gravado no rastreamento antes de retornar o original error . Se a function chamada for realizada com sucesso, o resultado será retornado sem gravar nada no rastreamento. Como os erros M não contêm um rastreamento de pilha completo (ou seja, você normalmente vê apenas a mensagem do erro), isso pode ser útil quando você deseja identificar onde o erro foi realmente gerado.

Como um exemplo (ruim), modifique a withData linha da TripPinNavTable função para forçar um erro novamente:

withData = Table.AddColumn(rename, "Data", each Diagnostics.LogFailure("Error in GetEntity", () => GetEntity(url, "DoesNotExist")), type table),

No rastreamento, você pode encontrar a mensagem de erro resultante contendo suas text e as informações de erro originais.

Mensagem LogFailure.

Certifique-se de redefinir sua função para um estado funcional antes de prosseguir com o próximo tutorial.

Conclusão

Esta lição breve (mas importante!) mostrou como fazer uso das funções auxiliares de diagnóstico para fazer logon nos arquivos de rastreamento de Power Query. Quando usado corretamente, essas funções são extremamente úteis na depuração de problemas dentro de seu conector.

Observação

Como um desenvolvedor de conector, é sua responsabilidade garantir que você não Registre informações confidenciais ou de identificação pessoal (PII) como parte do seu log de diagnóstico. Você também deve ter cuidado para não produzir muitas informações de rastreamento, pois isso pode ter um impacto negativo no desempenho.

Próximas etapas

Parte 9-TestConnection