Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Note
Ce contenu fait actuellement référence au contenu d’une implémentation héritée pour les diagnostics dans Visual Studio. Le contenu sera mis à jour prochainement pour couvrir le nouveau Kit de développement logiciel (SDK) Power Query dans Visual Studio Code.
Ce tutoriel en plusieurs parties traite de la création d’une nouvelle extension de source de données pour Power Query. Le didacticiel est destiné à être effectué de manière séquentielle : chaque leçon s’appuie sur le connecteur créé dans les leçons précédentes, en ajoutant de manière incrémentielle de nouvelles fonctionnalités à votre connecteur.
Dans cette leçon, vous allez :
- En savoir plus sur la fonction Diagnostics.Trace
- Utilisez les fonctions d’assistance de diagnostics pour ajouter des informations de traçage afin de faciliter le débogage de votre connecteur
Activation des diagnostics
Les utilisateurs power Query peuvent activer la journalisation des traces en cochant la case sous Options | Diagnostics.
Une fois activée, toute requête suivante entraîne le moteur M à émettre les informations de traçage dans les fichiers de log situés dans un répertoire utilisateur fixe.
Lorsque vous exécutez des requêtes M à partir du Kit de développement logiciel (SDK) Power Query, le suivi est activé au niveau du projet. Dans la page des propriétés du projet, il existe trois paramètres liés au suivi :
Effacer le journal : lorsqu'il est défini sur
true, le journal est réinitialisé/effacé lorsque vous exécutez vos requêtes. Nous vous recommandons de conserver cette valeur définie surtrue.Afficher les traces du moteur : ce paramètre contrôle la sortie des traces intégrées à partir du moteur M. Ces traces sont uniquement utiles pour les membres de l’équipe Power Query. Vous souhaitez donc généralement conserver ce jeu sur
false.Afficher les traces utilisateur : ce paramètre contrôle la sortie des informations de trace par votre connecteur. Vous souhaitez définir ce paramètre sur
true.
Une fois activées, les entrées de journal sont affichées dans la fenêtre Sortie de requête M, sous l’onglet Journal.
Diagnostics.Trace
La fonction Diagnostics.Trace est utilisée pour écrire des messages dans le journal de trace du moteur M.
Diagnostics.Trace = (traceLevel as number, message as text, value as any, optional delayed as nullable logical as any) => ...
Important
M est un langage fonctionnel avec une évaluation paresseuse. Lorsque vous utilisez Diagnostics.Trace, gardez à l’esprit que la fonction est appelée uniquement si l’expression fait partie de ce qui est réellement évalué. Vous trouverez des exemples de ce comportement plus loin dans ce didacticiel.
Le traceLevel paramètre peut être l’une des valeurs suivantes (dans l’ordre décroissant) :
TraceLevel.CriticalTraceLevel.ErrorTraceLevel.WarningTraceLevel.InformationTraceLevel.Verbose
Lorsque le suivi est activé, l’utilisateur peut sélectionner le niveau maximal de messages qu’il souhaite voir. Tous les messages de suivi de ce niveau et en dessous sont générés dans le journal. Par exemple, si l’utilisateur sélectionne le niveau « Avertissement », les messages de trace de TraceLevel.Warning, TraceLevel.Error et TraceLevel.Critical s'affichent dans les journaux.
Le paramètre message correspond à la sortie texte véritable dans le fichier de trace. Le texte ne contient pas le value paramètre, sauf si vous l’incluez explicitement dans le texte.
Le value paramètre est ce que la fonction retourne. Lorsque le paramètre delayed est défini sur true, value est une fonction sans paramètre qui retourne la valeur réelle que vous évaluez. Quand delayed est défini sur false, value est la valeur réelle. Vous trouverez un exemple de fonctionnement dans l’évaluation différée.
Utilisation de Diagnostics.Trace dans le connecteur TripPin
Pour obtenir un exemple pratique d’utilisation de Diagnostics.Trace et de l’impact du delayed paramètre, mettez à jour la fonction du GetSchemaForEntity connecteur TripPin pour encapsuler l’exception 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);
Vous pouvez forcer une erreur pendant l’évaluation (à des fins de test) en transmettant un nom d’entité non valide à la GetEntity fonction. Ici, vous modifiez la withData ligne dans la TripPinNavTable fonction, en remplaçant [Name] par "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;
Activez le suivi pour votre projet et exécutez vos requêtes de test. Sous l’onglet Errors , vous devez voir le texte de l’erreur que vous avez générée :
En outre, sous l’onglet Log , vous devez voir le même message. Si vous utilisez des valeurs différentes pour le paramètre message et le paramètre value, ces valeurs seraient différentes.
Notez également que le Action champ du message de journal contient le nom (type de source de données) de votre extension (dans ce cas, Engine/Extension/TripPin). Ce champ facilite la recherche des messages liés à votre extension lorsqu’il existe plusieurs requêtes impliquées et/ou le suivi système (moteur mashup) est activé.
Évaluation différée
En guise d’exemple de fonctionnement du delayed paramètre, vous devez apporter des modifications et réexécuter les requêtes.
Tout d’abord, définissez la valeur de delayed à false, mais laissez le paramètre value tel quel.
Diagnostics.Trace(TraceLevel.Error, message, () => error message, false);
Lorsque vous exécutez la requête, vous recevez une erreur indiquant que « Nous ne pouvons pas convertir une valeur de type Function en type Type », et non l’erreur réelle que vous avez générée. Cette différence est due au fait que l’appel retourne maintenant une function valeur, plutôt que la valeur elle-même.
Ensuite, supprimez la fonction du value paramètre :
Diagnostics.Trace(TraceLevel.Error, message, error message, false);
Lorsque vous exécutez la requête, vous recevez l’erreur correcte, mais si vous consultez l’onglet Journal, il n’y a aucun message. Cette différence est due au fait que le error est déclenché/évalué lors de l'appel à Diagnostics.Trace, ce qui fait que le message n'est jamais réellement affiché.
Maintenant que vous comprenez l’impact du delayed paramètre, veillez à réinitialiser votre connecteur à un état de travail avant de continuer.
Fonctions d’assistance de diagnostic dans Diagnostics.pqm
Le fichier Diagnostics.pqm inclus dans ce projet contient de nombreuses fonctions d’assistance qui facilitent le suivi. Comme indiqué dans le tutoriel précédent, vous pouvez inclure ce fichier dans votre projet (n’oubliez pas de définir l’action de génération à compiler), puis de le charger dans votre fichier de connecteur. Le bas de votre fichier connecteur doit maintenant ressembler à l’extrait de code suivant. N’hésitez pas à explorer les différentes fonctions que ce module fournit, mais dans cet exemple, vous n’utilisez que les fonctions Diagnostics.LogValue et 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 fonction est beaucoup comme Diagnostics.Trace, et peut être utilisée pour générer la valeur de ce que vous évaluez.
Diagnostics.LogValue = (prefix as text, value as any) as any => ...
Le prefix paramètre est ajouté au message de journal. Vous utilisez ce paramètre pour déterminer l’appel qui génère le message. Le value paramètre est ce que la fonction retourne et est également écrit dans la trace sous forme de représentation textuelle de la valeur M. Par exemple, si value est égal à un table ayant les colonnes A et B, le journal contient la représentation équivalente #table : #table({"A", "B"}, {{"row1 A", "row1 B"}, {"row2 A", row2 B"}})
Note
La sérialisation des valeurs M en texte peut être une opération coûteuse. N’oubliez pas la taille potentielle des valeurs que vous placez dans la trace.
Note
La plupart des environnements Power Query tronquent les messages de trace à une longueur maximale.
Par exemple, mettez à jour la fonction TripPin.Feed pour tracer les arguments url et schema passés à la fonction.
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;
Vous devez utiliser les nouvelles valeurs _url dans l’appel à _schemaGetAllPagesByNextLink. Si vous avez utilisé les paramètres de fonction d’origine, les Diagnostics.LogValue appels ne sont jamais réellement évalués, ce qui entraîne l’absence de messages écrits dans la trace.
La programmation fonctionnelle est amusante !
Lorsque vous exécutez vos requêtes, vous devez maintenant voir de nouveaux messages dans le journal.
Accès à l’URL :
Type de schéma :
La version sérialisée du schema paramètre type s’affiche, plutôt que le résultat obtenu lorsque vous effectuez simplement une Text.FromValue sur une valeur de type (ce qui affiche « type »).
Diagnostics.LogFailure
La Diagnostics.LogFailure fonction peut être utilisée pour encapsuler les appels de fonction et n’écrit dans la trace que si l’appel de fonction échoue (autrement dit, retourne un error).
Diagnostics.LogFailure = (text as text, function as function) as any => ...
En interne, Diagnostics.LogFailure ajoute un opérateur try à l'appel function. Si l’appel échoue, la text valeur est écrite dans la trace avant de retourner l’original error. Si l’appel function réussit, le résultat est renvoyé sans écrire quoi que ce soit dans la trace. Étant donné que les erreurs M ne contiennent pas de trace de pile complète (autrement dit, vous ne voyez généralement que le message de l’erreur), cette fonction peut être utile lorsque vous souhaitez identifier l’emplacement où l’erreur a été générée.
Pour prendre un exemple (médiocre), modifiez la ligne withData de la fonction TripPinNavTable pour forcer une erreur une fois de plus :
withData = Table.AddColumn(rename, "Data", each Diagnostics.LogFailure("Error in GetEntity", () => GetEntity(url, "DoesNotExist")), type table),
Dans la trace, vous trouverez le message d’erreur résultant contenant votre text et les informations d’erreur d’origine.
Veillez à réinitialiser votre fonction à un état de travail avant de suivre le didacticiel suivant.
Conclusion
Cette brève leçon (mais importante) vous a montré comment utiliser les fonctions d’assistance de diagnostic pour vous connecter aux fichiers de trace Power Query. Lorsqu'elles sont utilisées correctement, ces fonctions sont utiles pour déboguer les problèmes au sein de votre connecteur.
Note
En tant que développeur de connecteurs, il est de votre responsabilité de vous assurer que vous ne journalisez pas les informations sensibles ou personnellement identifiables (PII) dans le cadre de votre journalisation des diagnostics. Vous devez également veiller à ne pas générer trop d’informations de trace, car elles peuvent avoir un impact négatif sur les performances.