Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Important
Para usar essa funcionalidade, primeiro você deve habilitar o recurso de integração do Application Insights usando uma conta de administrador. Certifique-se de que o usuário que habilita o recurso tenha os privilégios necessários para modificar a organização do Dataverse (como a função administrador do sistema ou ser um administrador do Power Platform/Dynamics 365) e tenha acesso de colaborador ao recurso do Application Insights. Se um usuário sem as permissões necessárias habilitar a integração, os dados de telemetria não serão gravados no Application Insights. Para obter mais informações, consulte Analisar aplicativos controlados por modelos e Microsoft Dataverse telemetria com o Application Insights.
No momento, não há suporte para ILogger durante uma sessão de criação de perfil ou depuração de plug-in na ferramenta Registro de Plug-in ou na extensão Power Platform Tools para Visual Studio.
Quando você habilita o Application Insights para sua organização, todos os plug-ins gravados usando a Interface ILogger fornecida no SDK para .NET assemblies gravam telemetria em seu recurso do Application Insights.
A plataforma Dataverse captura os dados de telemetria do Dataverse e de aplicativos baseados em modelo e os exporta para o recurso do Application Insights. Há alguma latência entre o momento em que ele foi capturado e quando ele fica disponível para você no Application Insights. Como Microsoft coleta essa telemetria, você não precisa escrever nenhum código para habilitá-la.
Os dados de telemetria provenientes de plug-ins usando a interface ILogger são diferentes de duas maneiras:
- Essa telemetria é gravada diretamente no recurso do Application Insights e nunca é enviada para Microsoft.
- Há menos latência ao exibir esses dados.
- Você deve atualizar o código do plug-in para usar a interface ILogger.
O uso do ILogger fornece dados de telemetria verdadeiros e destina-se a trabalhar em conjunto com os logs de rastreamento de plug-in existentes escritos usando a interface ITracingService. A tabela a seguir compara os recursos:
| Criteria | ILogger para Application Insights | Rastreamento do ITracingService nos logs de rastreamento de plug-in |
|---|---|---|
| Utilização pretendida | Capture a telemetria ao longo do tempo para análise e depuração. | Ao desenvolver e depurar plug-ins |
| Quanto tempo os dados são armazenados | De acordo com o período de retenção de dados do Application Insights, que é de 90 dias por padrão | 24 horas |
| Available | Somente para organizações que assinam a integração do Application Insights. | Disponível para qualquer organização quando o rastreamento de plug-in está habilitado. |
| Quantidade de dados | Cada mensagem de log pode passar um valor de cadeia de caracteres. | Somente 10 kb de texto podem ser gravados para cada execução de plug-in. O texto é truncado após os primeiros 10 kb. |
| Disponível em erros de runtime | No | Disponível nos erros do cliente de aplicativos orientados por modelo e como anotações na API Web. Para obter mais informações, consulte Incluir mais detalhes sobre os erros. |
Você deve continuar a usar o ITracingService.Trace para gravar na tabela Log de Rastreamento do Plug-in quando necessário. Nem todas as organizações habilitam o Application Insights. Se o código do plug-in usar a interface ILogger e a organização não tiver a integração do Application Insights habilitada, nada será gravado. Portanto, é importante continuar usando o método Trace do ITracingService nos seus plug-ins. Os logs de rastreamento de plug-ins continuam sendo uma forma importante de capturar dados durante o desenvolvimento e a depuração de plug-ins, mas nunca tiveram a finalidade de fornecer dados de telemetria. Para obter mais informações, consulte Plug-ins: Rastreamento e registro em log.
Você deve usar o ILogger porque ele fornece telemetria sobre o que acontece dentro de um plug-in. Essa telemetria é integrada ao escopo maior dos dados capturados com a integração do Application Insights. A integração do Application Insights informa quando um plug-in é executado, quanto tempo leva para ser executado e se ele faz solicitações http externas, mas Microsoft não pode adicionar nenhum código de telemetria nos plug-ins que você grava para estender o comportamento da plataforma.
Se você é um ISV com um produto que inclui plug-ins, os clientes que permitem o Application Insights apreciam poder ver o que está acontecendo em seus plug-ins e esses dados podem ajudá-lo a dar suporte a eles se houver problemas. Mas os dados capturados usando o ILogger só são enviados para o recurso do cliente inscrito. Você só poderá ver os dados capturados para seus próprios ambientes quando tiver o Application Insights habilitado.
Use ILogger
ILogger é uma interface comum para capturar informações de log. A implementação fornecida com o SDK para assemblies do .NET oferece métodos comuns para oferecer suporte à definição de um escopo e a diferentes níveis de log. No momento, não há nenhuma configuração para controlar qual nível de logs são gravados. Use os níveis no Application Insights para filtrar os logs a serem exibidos.
O plug-in de exemplo a seguir mostra o uso de ILogger e ITracingService.Trace.
Note
Certifique-se de incluir using Microsoft.Xrm.Sdk.PluginTelemetry;. Não use using Microsoft.Extensions.Logging;, caso contrário, a ILogger instância é nula.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.PluginTelemetry;
using System;
using System.Net.Http;
namespace ILoggerExample
{
public class AccountPostOperation : IPlugin
{
private string webAddress;
public AccountPostOperation(string config)
{
if (string.IsNullOrEmpty(config))
{
webAddress = "https://www.bing.com";
}
else
{
webAddress = config;
}
}
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
ILogger logger = (ILogger)serviceProvider.GetService(typeof(ILogger));
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
try
{
string startExecMsg = "Start execution of AccountPostOperation";
logger.LogInformation(startExecMsg);
tracingService.Trace(startExecMsg);
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName != "account")
{
string wrongEntityMsg = "Plug-in registered for wrong entity {0}";
logger.LogWarning(wrongEntityMsg, entity.LogicalName);
tracingService.Trace(wrongEntityMsg, entity.LogicalName);
return;
}
string activityMsg = "Callback";
using (logger.BeginScope(activityMsg))
{
tracingService.Trace(activityMsg);
string startTaskMsg = "Start Task Creation";
logger.LogInformation(startTaskMsg);
tracingService.Trace(startTaskMsg);
Entity followup = new Entity("task");
followup["subject"] = "Send e-mail to the new customer.";
followup["description"] =
"Follow up with the customer. Check if there are any new issues that need resolution.";
followup["scheduledstart"] = DateTime.Now.AddDays(7);
followup["scheduledend"] = DateTime.Now.AddDays(7);
followup["category"] = context.PrimaryEntityName;
// Refer to the account in the task activity.
if (context.OutputParameters.Contains("id"))
{
Guid regardingobjectid = new Guid(context.OutputParameters["id"].ToString());
string regardingobjectidType = "account";
followup["regardingobjectid"] =
new EntityReference(regardingobjectidType, regardingobjectid);
}
// Obtain the IOrganizationService reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider
.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
//Create the task
service.Create(followup);
string endTaskMsg = "Task creation completed";
logger.LogInformation(endTaskMsg);
tracingService.Trace(endTaskMsg);
}
string outBoundScope = "OutboundCall";
using (logger.BeginScope(outBoundScope))
{
string outboundStartMsg = "Outbound call started";
logger.LogInformation(outboundStartMsg);
tracingService.Trace(outboundStartMsg);
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromMilliseconds(15000); //15 seconds
client.DefaultRequestHeaders.ConnectionClose = true; //Set KeepAlive to false
HttpResponseMessage response = client
.GetAsync(webAddress)
.GetAwaiter()
.GetResult(); //Make sure it is synchronous
response.EnsureSuccessStatusCode();
string responseText = response.Content
.ReadAsStringAsync()
.GetAwaiter()
.GetResult(); //Make sure it is synchronous
string shortResponseText = responseText.Substring(0, 20);
logger.LogInformation(shortResponseText);
tracingService.Trace(shortResponseText);
string outboundEndMsg = "Outbound call ended successfully";
logger.LogInformation(outboundEndMsg);
tracingService.Trace(outboundEndMsg);
}
}
}
catch (Exception e)
{
string errMsg = "Plugin failed";
logger.LogError(e, errMsg);
tracingService.Trace($"{errMsg}:{e.Message}");
throw new InvalidPluginExecutionException(e.Message, e);
}
}
}
}
Ao registrar esse plug-in em uma etapa síncrona PostOperation para o Create de uma entidade account, você pode usar os Logs do Application Insights para visualizar a saída dentro de alguns minutos. Use a Linguagem de Consulta Kusto (KQL) para consultar os resultados.
Filtre itens para uma única operação usando o operation_ParentId, que representa o ID da solicitação no cabeçalho da resposta.
A entrada correspondente no log de rastreamento do plug-in se parece com isto:
Start execution of AccountPostOperation
Callback
Start Task Creation
Task creation completed
Outbound call started
<!doctype html><html
Outbound call ended successfully
As linhas retornadas no Application Insights não mostram as informações definidas usando o Método BeginScope. Esses dados são definidos no customDimensions dos registros adicionados nesse escopo. Use essa consulta para mostrar os logs dentro do escopo.
Essa consulta limita os resultados aos logs adicionados durante o escopo Callback.
Essa consulta limita os resultados aos logs adicionados durante o OutboundCall escopo:
Registro em log de exceções
Na parte inferior do exemplo de código de plug-in anterior, o código a seguir usa LogError para registrar uma exceção capturada e lança um InvalidPluginExecutionException:
catch (Exception e)
{
string errMsg = "Plugin failed";
logger.LogError(e, errMsg);
tracingService.Trace($"{errMsg}:{e.Message}");
throw new InvalidPluginExecutionException(e.Message, e);
}
Usando o código de plug-in anterior, você pode causar uma exceção passando um valor inválido para os dados de configuração de registro de etapa. Neste exemplo, o valor é NOT_A_URL.
Esse valor substitui o valor padrão (https://www.bing.com) e faz com que a chamada de saída falhe.
Não há nada de errado com a solicitação que um cliente pode enviar:
POST [Organization URI]/api/data/v9.1/accounts HTTP/1.1
Prefer: odata.include-annotations="*"
Authorization: Bearer [REDACTED]
Content-Type: application/json
{
"name":"Test account"
}
Mas devido ao registro incorreto da etapa de plug-in, a resposta retorna o seguinte erro com todos os detalhes quando o Prefer: odata.include-annotations="*" cabeçalho é usado:
HTTP/1.1 400 Bad Request
Content-Type: application/json; odata.metadata=minimal
x-ms-service-request-id: 8fd35fd6-5329-4bd5-a1b7-757f91822322
REQ_ID: 8fd35fd6-5329-4bd5-a1b7-757f91822322
OData-Version: 4.0
Date: Sat, 24 Apr 2021 18:24:46 GMT
{
"error": {
"code": "0x80040265",
"message": "An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.",
"@Microsoft.PowerApps.CDS.ErrorDetails.OperationStatus": "0",
"@Microsoft.PowerApps.CDS.ErrorDetails.SubErrorCode": "-2146233088",
"@Microsoft.PowerApps.CDS.HelpLink": "http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a80040265&client=platform",
"@Microsoft.PowerApps.CDS.TraceText": "\r\n[ILoggerExample: ILoggerExample.AccountPostOperation]\r\n[2ee952aa-90a4-eb11-b1ac-000d3a8f6891: ILoggerExample.AccountPostOperation: Create of account]\r\n\r\n\t\r\n\tStart execution of AccountPostOperation\r\n\tCallback\r\n\tStart Task Creation\r\n\tTask creation completed\r\n\tOutbound call started\r\n\tPlugin failed:An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.\r\n\t\r\n",
"@Microsoft.PowerApps.CDS.InnerError.Message": "An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set."
}
}
O Log de Rastreamento do Plug-in contém esses dados de exceção, que incluem os ExceptionDetails dados.
Exception type: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]
Message: An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ActivityId>09bf305c-8272-4fc4-801b-479280cb3069</ActivityId>
<ErrorCode>-2147220891</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
<KeyValuePairOfstringanyType>
<d2p1:key>OperationStatus</d2p1:key>
<d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">0</d2p1:value>
</KeyValuePairOfstringanyType>
<KeyValuePairOfstringanyType>
<d2p1:key>SubErrorCode</d2p1:key>
<d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">-2146233088</d2p1:value>
</KeyValuePairOfstringanyType>
</ErrorDetails>
<HelpLink i:nil="true" />
<Message>An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.</Message>
<Timestamp>2021-04-24T18:24:46.4900727Z</Timestamp>
<ExceptionRetriable>false</ExceptionRetriable>
<ExceptionSource>PluginExecution</ExceptionSource>
<InnerFault i:nil="true" />
<OriginalException>PluginExecution</OriginalException>
<TraceText>
Start execution of AccountPostOperation
Callback
Start Task Creation
Task creation completed
Outbound call started
Plugin failed:An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.
</TraceText>
</OrganizationServiceFault>
No Application Insights, se você exibir os rastreamentos no escopo desta solicitação e com o escopo definido para OutboundCall, como mostrado anteriormente, poderá ver que a única entrada indica que a chamada de saída foi iniciada.
No Application Insights, ao alternar sua consulta para usar exceptions em vez de traces, você verá três exceções registradas:
Aquele em que cloud_RoleInstance é igual a SandboxRoleInstance é aquele que foi escrito devido ao método ILogger LogError. Os outros dois representam locais diferentes em que o erro foi registrado no servidor.
Note
O SandboxRoleInstance client_Type é PC. Esse valor ocorre porque o plug-in é executado em uma área restrita isolada como um cliente e não no servidor.
Você pode se concentrar no log de erros gerado pelo seu código filtrando por cloud_RoleInstance:
O texto da mensagem formatada é capturado como parte do customDimensions.
Consulte também
Analisar aplicativos controlados por modelos e Microsoft Dataverse telemetria com o Application Insights
Plug-ins
Depurar um plug-in
Exibir logs de rastreamento
Serviço de rastreamento
Tabela PluginTraceLog