Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota:
Actualmente, este contenido hace referencia al contenido de una implementación heredada para diagnósticos en Visual Studio. El contenido se actualizará casi en el futuro para cubrir el nuevo SDK de Power Query en Visual Studio Code.
En este tutorial de varias partes se describe la creación de una nueva extensión de origen de datos para Power Query. El tutorial está diseñado para realizarse secuencialmente: cada lección se basa en el conector creado en las lecciones anteriores, agregando incrementalmente nuevas funcionalidades al conector.
En esta lección:
- Más información sobre la función Diagnostics.Trace
- Uso de las funciones auxiliares de diagnóstico para agregar información de seguimiento para ayudar a depurar el conector
Habilitación de diagnósticos
Los usuarios de Power Query pueden habilitar el registro de seguimiento activando la casilla en Opciones | Diagnósticos.
Una vez habilitada, las consultas posteriores hacen que el motor de M emita información de seguimiento a los archivos de registro ubicados en un directorio de usuario fijo.
Al ejecutar consultas M desde el SDK de Power Query, el seguimiento está habilitado en el nivel de proyecto. En la página de propiedades del proyecto, hay tres valores relacionados con el seguimiento:
Borrar registro: cuando se establece en
true, el registro se restablece o borra al ejecutar las consultas. Se recomienda mantener este valor establecido entrue.Mostrar rastros del motor: esta opción controla la salida de rastros integrados desde el motor M. Estos seguimientos solo son útiles para los miembros del equipo de Power Query, por lo que normalmente se recomienda mantener esta configuración en
false.Mostrar seguimientos de usuario: esta configuración controla la salida de la información de seguimiento por el conector. Quiere establecer
trueen esta configuración.
Una vez habilitada, las entradas de registro se muestran en la ventana Salida de consulta M, en la pestaña Registro.
Diagnostics.Trace
La función Diagnostics.Trace se usa para escribir mensajes en el registro de seguimiento del motor de M.
Diagnostics.Trace = (traceLevel as number, message as text, value as any, optional delayed as nullable logical as any) => ...
Importante
M es un lenguaje funcional con evaluación diferida. Al usar Diagnostics.Trace, tenga en cuenta que solo se llama a la función si la expresión forma parte de lo que realmente se evalúa. Los ejemplos de este comportamiento se pueden encontrar más adelante en este tutorial.
El traceLevel parámetro puede ser uno de los siguientes valores (en orden descendente):
TraceLevel.CriticalTraceLevel.ErrorTraceLevel.WarningTraceLevel.InformationTraceLevel.Verbose
Cuando el seguimiento está habilitado, el usuario puede seleccionar el nivel máximo de mensajes que desea ver. Todos los mensajes de seguimiento de este nivel e inferiores se registran en el log. Por ejemplo, si el usuario selecciona el nivel "Advertencia", los mensajes de seguimiento de TraceLevel.Warning, TraceLevel.Errory TraceLevel.Critical aparecen en los registros.
El message parámetro es la salida de texto real en el archivo de seguimiento. El texto no contiene el value parámetro a menos que lo incluya explícitamente en el texto.
El value parámetro es lo que devuelve la función. Cuando el parámetro delayed se establece en true, value es una función sin parámetros que devuelve el valor real que está evaluando. Cuando delayed se establece en false, value es el valor real. Un ejemplo de cómo funciona esto se puede encontrar en Evaluación retrasada.
Uso de Diagnostics.Trace en el conector TripPin
Para obtener un ejemplo práctico del uso de Diagnostics.Trace y el impacto del delayed parámetro, actualice la función del conector GetSchemaForEntity TripPin para envolver la error excepción:
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);
Puede forzar un error durante la evaluación (con fines de prueba) pasando un nombre de entidad no válido a la GetEntity función. Aquí cambias la línea withData en la función TripPinNavTable, reemplazando [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;
Habilite el seguimiento del proyecto y ejecute las consultas de prueba. En la Errors pestaña debería ver el texto del error que ha generado:
Además, en la Log pestaña, deberías ver el mismo mensaje. Si usa valores diferentes para los message parámetros y value , estos valores serían diferentes.
Tenga en cuenta también que el Action campo del mensaje de registro contiene el nombre (Tipo de origen de datos) de la extensión (en este caso, Engine/Extension/TripPin). Este campo facilita la búsqueda de los mensajes relacionados con la extensión cuando hay múltiples consultas implicadas y/o cuando el seguimiento del sistema (motor de mashup) está habilitado.
Evaluación retrasada
Como ejemplo de cómo funciona el delayed parámetro, necesita realizar algunas modificaciones y volver a ejecutar las consultas.
En primer lugar, establezca en el valor delayedfalse, pero deje el parámetro value tal como está:
Diagnostics.Trace(TraceLevel.Error, message, () => error message, false);
Al ejecutar la consulta, recibirá un error que indica que "No se puede convertir un valor de tipo Function a tipo Type" y no el error real que ha generado. Esta diferencia se debe a que la llamada ahora devuelve un function valor, en lugar del propio valor.
A continuación, quite la función del parámetro value:
Diagnostics.Trace(TraceLevel.Error, message, error message, false);
Al ejecutar la consulta, recibirá el error correcto, pero si comprueba la pestaña Registro , no hay ningún mensaje. Esta discrepancia se debe error a que termina siendo generado o evaluado durante la llamada a Diagnostics.Trace, por lo que el mensaje nunca se genera realmente.
Ahora que comprende el impacto del parámetro, asegúrese de restablecer el delayed conector a un estado de trabajo antes de continuar.
Funciones auxiliares de diagnóstico en Diagnostics.pqm
El archivo Diagnostics.pqm incluido en este proyecto contiene muchas funciones auxiliares que facilitan el seguimiento. Como se muestra en el tutorial anterior, puede incluir este archivo en el proyecto (recuerde establecer la acción de compilación en Compilar) y, a continuación, cargarlo en el archivo del conector. La parte inferior del archivo del conector debería tener ahora un aspecto similar al siguiente fragmento de código. No dude en explorar las distintas funciones que proporciona este módulo, pero en este ejemplo solo se usan las Diagnostics.LogValue funciones y 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 función Diagnostics.LogValue es muy similar a Diagnostics.Trace, y se puede usar para generar el valor de lo que usted está evaluando.
Diagnostics.LogValue = (prefix as text, value as any) as any => ...
El prefix parámetro se antepone al mensaje de registro. Este parámetro se usa para averiguar qué llamada genera el mensaje. El value parámetro es el valor que la función devuelve y se escribe también en la traza como una representación en texto del valor M. Por ejemplo, si value es igual a un table con las columnas A y B, el registro contiene la representación equivalente #table: #table({"A", "B"}, {{"row1 A", "row1 B"}, {"row2 A", row2 B"}})
Nota:
La serialización de valores de M en texto puede ser una operación costosa. Tenga en cuenta el tamaño potencial de los valores que va a generar en el seguimiento.
Nota:
La mayoría de los entornos de Power Query truncan los mensajes de seguimiento a una longitud máxima.
Por ejemplo, actualice la TripPin.Feed función para realizar un seguimiento de los url argumentos y schema pasados a la función .
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;
Debe usar los nuevos _url y _schema valores en la llamada a GetAllPagesByNextLink. Si ha usado los parámetros de función originales, las Diagnostics.LogValue llamadas nunca se evalúan realmente, lo que no da lugar a ningún mensaje escrito en el seguimiento.
¡La programación funcional es divertida!
Al ejecutar las consultas, ahora debería ver nuevos mensajes en el registro.
Acceso a la dirección URL:
Tipo de esquema:
Se muestra la versión serializada del schema parámetro type, en lugar de lo que se obtiene al hacer un sencillo Text.FromValue en un tipo de valor (lo que da como resultado "tipo").
Diagnostics.LogFailure
La Diagnostics.LogFailure función se puede usar para encapsular las llamadas de función y solo escribe en el seguimiento si se produce un error en la llamada de función (es decir, devuelve un error).
Diagnostics.LogFailure = (text as text, function as function) as any => ...
Internamente, Diagnostics.LogFailure agrega un try operador a la function llamada. Si se produce un error en la llamada, el text valor se escribe en el seguimiento antes de devolver el original error. Si la llamada function se realiza correctamente, el resultado se devuelve sin escribir nada en el registro. Dado que los errores de M no contienen un seguimiento de pila completo (es decir, normalmente solo se ve el mensaje del error), esta función puede ser útil cuando desea identificar dónde se generó el error.
Como ejemplo (deficiente), modifique la withData línea de la TripPinNavTable función para forzar un error una vez más:
withData = Table.AddColumn(rename, "Data", each Diagnostics.LogFailure("Error in GetEntity", () => GetEntity(url, "DoesNotExist")), type table),
En la traza, puede encontrar el mensaje de error resultante que contiene tu text y la información de error original.
Asegúrese de restablecer la función a un estado de trabajo antes de continuar con el siguiente tutorial.
Conclusión
Esta breve lección (pero importante) le mostró cómo usar las funciones auxiliares de diagnóstico para iniciar sesión en los archivos de seguimiento de Power Query. Cuando se usa correctamente, estas funciones son útiles para depurar problemas dentro del conector.
Nota:
Como desarrollador de conectores, es su responsabilidad asegurarse de que no registra información confidencial o de identificación personal (PII) como parte del registro de diagnóstico. También debe tener cuidado de no generar demasiada información de seguimiento, ya que puede tener un impacto negativo en el rendimiento.