TripPin パート 8 - 診断の追加
このマルチパート チュートリアルでは、Power Query 用の新しいデータ ソース拡張機能の作成について説明します。 このチュートリアルは、順次実行することを意図したものです。各レッスンでは、それまでのレッスンで作成したコネクタを基にして、コネクタに新しい機能を段階的に追加していきます。
このレッスンの内容:
- Diagnostics.Trace 関数について学習する
- Diagnostics ヘルパー関数を使用して、コネクタのデバッグに役立つトレース情報を追加する
診断の有効化
Power Query ユーザーは、 [オプション] | [診断] の下にあるチェックボックスをオンにして、トレース ログを有効にできます。

有効にすると、それ以降のクエリでは、M エンジンによって、特定のユーザー ディレクトリにあるログ ファイルにトレース情報が出力されます。
Power Query SDK 内から M クエリを実行すると、トレースがプロジェクト レベルで有効になります。 [プロジェクトのプロパティ] ページには、トレースに関連する 3 つの設定があります。
- [Clear Log](ログの消去) —これを
trueに設定すると、クエリの実行時にログがリセット/消去されます。 これはtrueに設定したままにしておくことをお勧めします。 - [Show Engine Traces](エンジン トレースの表示) —この設定は、M エンジンからの組み込みトレースの出力を制御します。 これらのトレースは一般に Power Query チームのメンバーのみが使用するため、通常はこれを
falseに設定したままにしておくことをお勧めします。 - [Show User Traces](ユーザー トレースの表示) —この設定は、コネクタが出力するトレース情報を制御します。 これは
trueに設定することをお勧めします。

有効にすると、[M Query Output](M クエリ出力) ウィンドウの [ログ] タブの下にログ エントリが表示されます。
Diagnostics.Trace
Diagnostics.Trace 関数は、M エンジンのトレース ログにメッセージを書き込むために使用されます。
Diagnostics.Trace = (traceLevel as number, message as text, value as any, optional delayed as nullable logical as any) => ...
重要
M は、遅延評価を行う関数型言語です。 Diagnostics.Trace を使用する場合、この関数は、それが属している式が実際に評価される場合にのみ呼び出されることに注意してください。 この例については、このチュートリアルの後半で説明します。
traceLevel パラメーターには、次のいずれかの値を指定できます (降順)。
TraceLevel.CriticalTraceLevel.ErrorTraceLevel.WarningTraceLevel.InformationTraceLevel.Verbose
トレースが有効になっている場合、ユーザーは、表示するメッセージの最大レベルを選択できます。 このレベルおよびそれより下のすべてのトレース メッセージがログに出力されます。 たとえば、ユーザーが "Warning" レベルを選択すると、TraceLevel.Warning、TraceLevel.Error、TraceLevel.Critical のトレース メッセージがログに表示されます。
message パラメーターは、トレース ファイルに出力される実際のテキストです。 テキストに明示的に含めない限り、テキストには value パラメーターが含まれないことに注意してください。
value パラメーターは関数から返されます。 delayed パラメーターが true に設定されている場合、value は、評価している実際の値を返すパラメーターなしの関数です。 delayed が false に設定されている場合、value は実際の値です。 この動作の例については、以下を参照してください。
TripPin コネクタでの Diagnostics.Trace の使用
Diagnostics.Trace を実際に使用する例と delayed パラメーターの影響を確認するには、error 例外をラップするように TripPin コネクタの GetSchemaForEntity 関数を更新します。
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);
GetEntity 関数に無効なエンティティ名を渡すと、評価中に (テスト目的で) エラーを強制的に発生させることができます。 ここでは、TripPinNavTable 関数の withData 行を変更して、[Name] を "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;
プロジェクトのトレースを有効にし、テスト クエリを実行します。 Errors タブには、 発生させたエラーのテキストが表示されます。

Log タブにも、同じメッセージが表示されます。 message と value の各パラメーターで異なる値を使用すると、異なる結果になることに注意してください。

ログ メッセージの Action フィールドには、拡張機能の名前 (データソースの種類) が含まれていることにも注意してください (この場合は Engine/Extension/TripPin)。 これにより、関連するクエリが複数ある場合や、システム (マッシュアップ エンジン) のトレースが有効になっている場合に、拡張機能に関連するメッセージを簡単に見つけることができます。
遅延評価
delayed パラメーターの動作の例として、いくつかの変更を行い、クエリを再実行します。
まず、delayed 値を false に設定します。ただし、value パラメーターはそのままにしておきます。
Diagnostics.Trace(TraceLevel.Error, message, () => error message, false);
クエリを実行すると、"Function 型の値を型 Type に変換できません" というエラーが表示されます。これは、発生させた実際のエラーではありません。 これは、呼び出しが値自体ではなく function 値を返すようになったためです。
次に、value パラメーターから関数を削除します。
Diagnostics.Trace(TraceLevel.Error, message, error message, false);
クエリを実行すると、正しいエラーが表示されますが、 [ログ] タブを確認しても、メッセージがありません。 これは、error が最終的に Diagnostics.Trace の呼び出し 中に 発生して評価されるためです。そのため、メッセージが実際には出力されません。
delayedパラメーターの影響が理解できたら、次に進む前に、コネクタを正常な状態にリセットしてください。
Diagnostics.pqm 内の診断ヘルパー関数
このプロジェクトに含まれる Diagnostics.pqm ファイルには、トレースを簡単にするためのヘルパー関数が複数含まれています。 前のチュートリアルで示したように、このファイルをプロジェクトに含め ([ビルド アクション] を [コンパイル] に設定してください)、コネクタ ファイルに読み込むことができます。 コネクタ ファイルの下部は、次のコード スニペットのようになります。 このモジュールで提供されているさまざまな関数を自由に試すことができますが、このサンプルでは、Diagnostics.LogValue と 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
Diagnostics.LogValue 関数は Diagnostics.Trace とよく似ており、評価する対象の値を出力するために使用できます。
Diagnostics.LogValue = (prefix as text, value as any) as any => ...
prefix パラメーターは、ログ メッセージの前に付加されます。 これを使用して、どの呼び出しがメッセージを出力したかを判断します。 関数からは value パラメーターが返され、M 値のテキスト表現としてトレースにも書き込まれます。 たとえば、value が列 A と列 B を持つ table に等しい場合、ログには同等の #table 表現 #table({"A", "B"}, {{"row1 A", "row1 B"}, {"row2 A", row2 B"}}) が含まれます。
注意
M 値をテキストにシリアル化する操作には、多くの処理が必要になる可能性があります。 トレースに出力する値がどれくらいのサイズになるかに注意してください。
注意
ほとんどの Power Query 環境では、トレース メッセージが最大長に切り捨てられます。
例として、TripPin.Feed 関数を更新して、関数に渡された url と schema の各引数をトレースするとします。
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;
GetAllPagesByNextLink の呼び出しでは、新しい値 _url と _schema を使用する必要があることに注意してください。 元の関数パラメーターを使用した場合、Diagnostics.LogValue 呼び出しは実際には評価されず、トレースにメッセージは書き込まれません。 関数型プログラミングは面白いです。
クエリを実行すると、ログに新しいメッセージが表示されます。
url へのアクセス: 
スキーマの種類: 
schema パラメーター type のシリアル化されたバージョンが表示されることに注意してください。型の値に対して単純な Text.FromValue を実行したときに取得される値 (結果は "type" になります) ではありません。
Diagnostics.LogFailure
Diagnostics.LogFailure 関数は、関数呼び出しをラップするために使用でき、関数呼び出しが失敗した場合 (つまり、error を返す場合) にのみトレースに書き込みます。
Diagnostics.LogFailure = (text as text, function as function) as any => ...
内部的には、Diagnostics.LogFailure は try 演算子を function 呼び出しに追加します。 呼び出しが失敗した場合は、text 値がトレースに書き込まれてから、元の error が返されます。 function 呼び出しが成功した場合は、結果が返され、トレースには何も書き込まれません。 M エラーにはスタック トレース全体は含まれていません (つまり、通常はエラーのメッセージのみが表示されます)。そのため、これは、エラーが実際に発生した場所を特定するときに役立ちます。
(不適切な) 例として、TripPinNavTable 関数の withData 行を変更して、エラーをもう一度強制的に発生させます。
withData = Table.AddColumn(rename, "Data", each Diagnostics.LogFailure("Error in GetEntity", () => GetEntity(url, "DoesNotExist")), type table),
トレースには、text が格納されたエラー メッセージと元のエラー情報が含まれます。

次のチュートリアルに進む前に、関数を正常な状態にリセットしてください。
まとめ
この短い (重要な) レッスンでは、診断ヘルパー関数を使用して Power Query トレース ファイルにログを記録する方法を説明しました。 これらの関数を適切に使用すると、コネクタ内の問題のデバッグに非常に役立ちます。
注意
コネクタ開発者には、機密情報や個人を特定できる情報 (PII) を診断ログの一部としてログに記録しないようにする責任があります。 また、パフォーマンスに悪影響を及ぼす可能性があるため、出力されるトレース情報が多くなりすぎないように注意する必要があります。