TripPin parte 8 - Aggiunta della diagnostica
Nota
Questo contenuto fa attualmente riferimento al contenuto da un'implementazione legacy per la diagnostica in Visual Studio. Il contenuto verrà aggiornato nel prossimo futuro per coprire il nuovo SDK di Power Query in Visual Studio Code.
Questa esercitazione in più parti illustra la creazione di una nuova estensione dell'origine dati per Power Query. L'esercitazione è destinata a essere eseguita in sequenza: ogni lezione si basa sul connettore creato nelle lezioni precedenti, aggiungendo in modo incrementale nuove funzionalità al connettore.
In questa lezione verranno illustrate le procedure seguenti:
- Informazioni sulla funzione Diagnostics.Trace
- Usare le funzioni helper di diagnostica per aggiungere informazioni di traccia per eseguire il debug del connettore
Abilitazione della diagnostica
Gli utenti di Power Query possono abilitare la registrazione delle tracce selezionando la casella di controllo in Opzioni | Diagnostica.
Dopo l'abilitazione, le query successive causeranno la generazione di informazioni di traccia da parte del motore M nei file di log che si trovano in una directory utente fissa.
Quando si eseguono query M dall'interno di Power Query SDK, la traccia viene abilitata a livello di progetto. Nella pagina delle proprietà del progetto sono disponibili tre impostazioni correlate alla traccia:
- Cancella log: quando questa opzione è impostata su
true
, il log verrà reimpostato/cancellato quando si eseguono le query. È consigliabile mantenere questo set sutrue
. - Mostra tracce motore: questa impostazione controlla l'output delle tracce predefinite dal motore M. Queste tracce sono utili solo per i membri del team di Power Query, quindi in genere si vuole mantenere questo set su
false
. - Mostra tracce utente: questa impostazione controlla l'output delle informazioni di traccia dal connettore. Si vuole impostare questa proprietà su
true
.
Dopo l'abilitazione, si inizierà a visualizzare le voci di log nella finestra Output query M, nella scheda Log .
Diagnostics.Trace
La funzione Diagnostics.Trace viene usata per scrivere messaggi nel log di traccia del motore M.
Diagnostics.Trace = (traceLevel as number, message as text, value as any, optional delayed as nullable logical as any) => ...
Importante
M è un linguaggio funzionale con valutazione differita. Quando si usa Diagnostics.Trace
, tenere presente che la funzione verrà chiamata solo se l'espressione di cui fa parte viene effettivamente valutata. Alcuni esempi sono disponibili più avanti in questa esercitazione.
Il traceLevel
parametro può essere uno dei valori seguenti (in ordine decrescente):
TraceLevel.Critical
TraceLevel.Error
TraceLevel.Warning
TraceLevel.Information
TraceLevel.Verbose
Quando la traccia è abilitata, l'utente può selezionare il livello massimo di messaggi che desidera visualizzare. Tutti i messaggi di traccia di questo livello e sotto verranno restituiti nel log. Ad esempio, se l'utente seleziona il livello "Avviso", i messaggi di traccia di TraceLevel.Warning
, TraceLevel.Error
e TraceLevel.Critical
verranno visualizzati nei log.
Il message
parametro è il testo effettivo che verrà restituito al file di traccia. Il testo non conterrà il value
parametro a meno che non venga incluso in modo esplicito nel testo.
Il value
parametro è il risultato restituito dalla funzione. Quando il delayed
parametro è impostato su true
, value
sarà una funzione di parametro zero che restituisce il valore effettivo che si sta valutando. Quando delayed
è impostato su false
, value
sarà il valore effettivo. Di seguito è riportato un esempio di funzionamento.
Uso della diagnostica. Traccia nel connettore TripPin
Per un esempio pratico dell'uso di Diagnostics.Trace e dell'impatto del delayed
parametro, aggiornare la funzione del GetSchemaForEntity
connettore TripPin per eseguire il wrapping dell'eccezione error
:
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);
È possibile forzare un errore durante la valutazione (a scopo di test)passando un nome di entità non valido alla GetEntity
funzione. In questo caso si modifica la withData
riga nella TripPinNavTable
funzione, sostituendo [Name]
con "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;
Abilitare la traccia per il progetto ed eseguire le query di test. Errors
Nella scheda dovrebbe essere visualizzato il testo dell'errore generato:
Inoltre, nella Log
scheda dovrebbe essere visualizzato lo stesso messaggio. Se si usano valori diversi per i message
parametri e value
, questi valori sono diversi.
Si noti anche che il Action
campo del messaggio di log contiene il nome (tipo di origine dati) dell'estensione (in questo caso, Engine/Extension/TripPin
). In questo modo è più semplice trovare i messaggi correlati all'estensione quando sono presenti più query coinvolte e/o la traccia di sistema (motore mashup) è abilitata.
Valutazione ritardata
Come esempio del funzionamento del delayed
parametro, verranno apportate alcune modifiche ed eseguite di nuovo le query.
Per prima cosa, impostare il delayed
valore su false
, ma lasciare invariato il value
parametro:
Diagnostics.Trace(TraceLevel.Error, message, () => error message, false);
Quando si esegue la query, si riceverà un errore che indica che "Non è possibile convertire un valore di tipo Function in type" e non l'errore effettivo generato. Ciò è dovuto al fatto che la chiamata restituisce ora un function
valore, anziché il valore stesso.
Rimuovere quindi la funzione dal value
parametro :
Diagnostics.Trace(TraceLevel.Error, message, error message, false);
Quando si esegue la query, si riceverà l'errore corretto, ma se si seleziona la scheda Log , non saranno presenti messaggi. Ciò è dovuto al fatto che l'oggetto error
finisce per essere generato/valutato durante la chiamata a Diagnostics.Trace
, in modo che il messaggio non venga mai effettivamente restituito.
Dopo aver compreso l'impatto del parametro, assicurarsi di ripristinare lo stato di funzionamento del
delayed
connettore prima di procedere.
Funzioni helper di diagnostica in Diagnostics.pqm
Il file Diagnostics.pqm incluso in questo progetto contiene molte funzioni helper che semplificano la traccia. Come illustrato nell'esercitazione precedente, è possibile includere questo file nel progetto (ricordare di impostare l'azione di compilazione su Compila) e quindi caricarlo nel file del connettore. La parte inferiore del file del connettore dovrebbe ora essere simile al frammento di codice seguente. È possibile esplorare le varie funzioni fornite da questo modulo, ma in questo esempio si useranno solo le Diagnostics.LogValue
funzioni 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
La Diagnostics.LogValue
funzione è molto simile Diagnostics.Trace
a e può essere usata per restituire il valore di ciò che si sta valutando.
Diagnostics.LogValue = (prefix as text, value as any) as any => ...
Il prefix
parametro viene anteporto al messaggio di log. È necessario usarlo per determinare quale chiamata restituisce il messaggio. Il value
parametro è il risultato restituito dalla funzione e verrà scritto anche nella traccia come rappresentazione testuale del valore M. Ad esempio, se value
è uguale a con table
le colonne A e B, il log conterrà la rappresentazione equivalente #table
: #table({"A", "B"}, {{"row1 A", "row1 B"}, {"row2 A", row2 B"}})
Nota
La serializzazione dei valori M nel testo può essere un'operazione costosa. Tenere presente le potenziali dimensioni dei valori restituiti nella traccia.
Nota
La maggior parte degli ambienti di Power Query tronca i messaggi di traccia a una lunghezza massima.
Ad esempio, si aggiornerà la TripPin.Feed
funzione per tracciare gli url
argomenti e schema
passati alla funzione.
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;
È necessario usare i valori nuovi _url
e _schema
nella chiamata a GetAllPagesByNextLink
. Se sono stati usati i parametri della funzione originali, le Diagnostics.LogValue
chiamate non verrebbero mai valutate, con conseguente assenza di messaggi scritti nella traccia. La programmazione funzionale è divertente!
Quando si eseguono le query, verranno visualizzati nuovi messaggi nel log.
Accesso all'URL:
Tipo di schema:
Viene visualizzata la versione serializzata del schema
parametro type
, invece di quello che si otterrà quando si esegue una semplice Text.FromValue
operazione su un valore di tipo (che restituisce "type").
Diagnostics.LogFailure
La Diagnostics.LogFailure
funzione può essere usata per eseguire il wrapping delle chiamate di funzione e scriverà nella traccia solo se la chiamata di funzione ha esito negativo, ovvero restituisce un oggetto error
.
Diagnostics.LogFailure = (text as text, function as function) as any => ...
Internamente, Diagnostics.LogFailure
aggiunge un try
operatore alla function
chiamata. Se la chiamata ha esito negativo, il text
valore viene scritto nella traccia prima di restituire l'oggetto originale error
. Se la function
chiamata ha esito positivo, il risultato viene restituito senza scrivere alcun elemento nella traccia. Poiché gli errori M non contengono un'analisi dello stack completa(ovvero, in genere viene visualizzato solo il messaggio dell'errore), può essere utile quando si desidera individuare la posizione in cui è stato generato l'errore.
Come esempio (scarso), modificare la withData
riga della TripPinNavTable
funzione per forzare nuovamente un errore:
withData = Table.AddColumn(rename, "Data", each Diagnostics.LogFailure("Error in GetEntity", () => GetEntity(url, "DoesNotExist")), type table),
Nella traccia è possibile trovare il messaggio di errore risultante contenente text
e le informazioni sull'errore originali.
Assicurarsi di reimpostare la funzione in uno stato di lavoro prima di procedere con l'esercitazione successiva.
Conclusione
Questa breve lezione (ma importante)ha illustrato come usare le funzioni helper diagnostiche per registrare i file di traccia di Power Query. Se usate correttamente, queste funzioni sono utili per il debug dei problemi all'interno del connettore.
Nota
In qualità di sviluppatore di connettori, è responsabilità dell'utente assicurarsi di non registrare informazioni sensibili o personali come parte della registrazione diagnostica. È anche necessario prestare attenzione a non restituire troppe informazioni di traccia, perché può avere un impatto negativo sulle prestazioni.