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.
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 comotrue
. - 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
.
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.Trace
o , 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.Error
e 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:
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.
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.Trace
com 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:
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.
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.