TripPin parte 8 - Adicionando diagnósticos

Nota

Atualmente, esse conteúdo faz referência ao conteúdo de uma implementação herdada para diagnóstico no Visual Studio. O conteúdo será atualizado em um futuro próximo para cobrir o novo SDK do Power Query no Visual Studio Code.

Este tutorial com várias partes aborda a criação de uma nova extensão de fonte de dados para o 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ê irá:

  • 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 diagnósticos

Os utilizadores do Power Query podem ativar o registo de rastreio selecionando a caixa de verificação em Opções | Diagnóstico.

Habilite o rastreamento no Power Query.

Uma vez habilitada, quaisquer 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 a partir do SDK do Power Query, o rastreio é ativado ao nível do projeto. Na página de propriedades do projeto, há três configurações relacionadas ao rastreamento:

  • Limpar log—quando isso estiver definido como true, o log será redefinido/limpo quando você executar suas consultas. Recomendamos que mantenha esta definição como true.
  • Mostrar rastreamentos do mecanismo — essa configuração controla a saída de rastreamentos internos do mecanismo M. Esses rastreamentos só são úteis para membros da equipe do 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 pelo conector. Você vai querer definir isso como true.

Propriedades do projeto.

Uma vez ativado, você começará a ver entradas de log na janela M Query Output, 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 preguiçosa. Ao usar Diagnostics.Traceo , 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 mais adiante 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á ativado, o usuário pode selecionar o nível máximo de mensagens que gostaria de ver. Todas as mensagens de rastreamento deste nível e abaixo serão enviadas para o log. Por exemplo, se o usuário selecionar o nível "Aviso", as mensagens de rastreamento de TraceLevel.Warning, TraceLevel.Errore TraceLevel.Critical apareceriam nos logs.

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

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

Usando diagnósticos. Rastrear no conector TripPin

Para obter um exemplo prático do uso do Diagnostics.Trace e do impacto do delayed parâmetro, atualize a função do GetSchemaForEntity conector TripPin 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. Errors Na guia você deve ver o texto do erro que você gerou:

Mensagem de erro.

Além disso, na Log guia, você verá a mesma mensagem. Se você usar valores diferentes para os message parâmetros e value , eles serão diferentes.

Registo de erros.

Observe também que o Action campo da mensagem de log contém o nome (Tipo de fonte de dados) da sua extensão (neste caso, Engine/Extension/TripPin). Isso torna mais fácil encontrar as mensagens relacionadas à sua extensão quando há várias consultas envolvidas e/ou o rastreamento do sistema (mecanismo de mashup) está ativado.

Avaliação tardia

Como 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 que "Não é possível converter um valor do tipo Função para o tipo Tipo", e não o erro real que você gerou. Isso ocorre porque a chamada agora está retornando um function valor, em vez do valor em si.

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

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

Ao executar a consulta, você receberá o erro correto, mas se verificar a guia Log , não haverá mensagens. Isso ocorre porque o error acaba sendo levantado/avaliado durante a chamada para Diagnostics.Trace, então a mensagem nunca é realmente saída.

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

Funções auxiliares de diagnóstico no Diagnostics.pqm

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

// 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.Tracecom a , e pode ser usada para produzir 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ê usaria isso para descobrir qual chamada produz a mensagem. O value parâmetro é o que a função retornará e também será gravado no rastreamento como uma representação de texto do valor M. Por exemplo, se value for igual a a com as table colunas A e B, o log conterá a representação equivalente #table : #table({"A", "B"}, {{"row1 A", "row1 B"}, {"row2 A", row2 B"}})

Nota

Serializar valores M em texto pode ser uma operação cara. Esteja ciente do tamanho potencial dos valores que você está enviando para o rastreamento.

Nota

A maioria dos ambientes do Power Query truncará mensagens de rastreamento até um comprimento máximo.

Como exemplo, você atualizará a TripPin.Feed função para rastrear os argumentos e schema passados url 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;

Você tem que usar o novo _url e _schema valores na chamada para GetAllPagesByNextLink. Se você usasse 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!

Quando você executa suas consultas, agora você deve ver novas mensagens no log.

Acessando url:

Acessando a mensagem url.

Tipo de esquema:

Mensagem de tipo de esquema.

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

Diagnostics.LogFailure

A Diagnostics.LogFailure função pode ser usada para encapsular chamadas de função e só gravará 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 bem-sucedida, o resultado será retornado sem escrever nada no rastreamento. Como os erros M não contêm um rastreamento de pilha completa (ou seja, você normalmente vê apenas a mensagem do erro), isso pode ser útil quando você deseja identificar onde o erro foi gerado.

Como um exemplo (pobre), modifique a withData TripPinNavTable linha da função para forçar um erro mais uma vez:

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 seu text, e as informações de erro originais.

Mensagem LogFailure.

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

Conclusão

Esta breve (mas importante!) lição mostrou-lhe como utilizar as funções auxiliares de diagnóstico para iniciar sessão nos ficheiros de rastreio do Power Query. Quando usadas corretamente, essas funções são úteis na depuração de problemas dentro do seu conector.

Nota

Como desenvolvedor de conectores, é sua responsabilidade garantir que você não registre informações confidenciais ou de identificação pessoal (PII) como parte de seu registro 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óximos passos

TripPin Parte 9 - TestConnection