Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Por padrão, o TraceProcessor acessa os dados carregando-os na memória à medida que o rastreamento é processado. Essa abordagem de buffer é fácil de usar, mas pode ser cara em termos de uso de memória.
TraceProcessor também fornece trace.UseStreaming(), que suporta o acesso a vários tipos de dados de trace de forma contínua (processando dados à medida que são lidos do ficheiro de trace, em vez de armazenar esses dados em buffer na memória). Por exemplo, o rastreamento de chamadas de sistema pode ser bastante grande, e armazenar em buffer toda a lista de chamadas de sistema neste rastreamento pode ser muito dispendioso.
Acesso a dados em buffer
O código seguinte mostra o acesso aos dados syscall de maneira normal e com buffer via o método trace.UseSyscalls():
using Microsoft.Windows.EventTracing;
using Microsoft.Windows.EventTracing.Processes;
using Microsoft.Windows.EventTracing.Syscalls;
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: <trace.etl>");
return;
}
using (ITraceProcessor trace = TraceProcessor.Create(args[0]))
{
IPendingResult<ISyscallDataSource> pendingSyscallData = trace.UseSyscalls();
trace.Process();
ISyscallDataSource syscallData = pendingSyscallData.Result;
Dictionary<IProcess, int> syscallsPerCommandLine = new Dictionary<IProcess, int>();
foreach (ISyscall syscall in syscallData.Syscalls)
{
IProcess process = syscall.Thread?.Process;
if (process == null)
{
continue;
}
if (!syscallsPerCommandLine.ContainsKey(process))
{
syscallsPerCommandLine.Add(process, 0);
}
++syscallsPerCommandLine[process];
}
Console.WriteLine("Process Command Line: Syscalls Count");
foreach (IProcess process in syscallsPerCommandLine.Keys)
{
Console.WriteLine($"{process.CommandLine}: {syscallsPerCommandLine[process]}");
}
}
}
}
Acesso a dados de streaming
Com o grande rastreamento de chamadas de sistema, tentar armazenar em buffer os dados das chamadas de sistema na memória pode ser bastante caro, ou então pode nem ser possível. O código a seguir mostra como aceder aos mesmos dados syscall de forma contínua, substituindo trace.UseSyscalls() com trace.UseStreaming().UseSyscalls():
using Microsoft.Windows.EventTracing;
using Microsoft.Windows.EventTracing.Processes;
using Microsoft.Windows.EventTracing.Syscalls;
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: <trace.etl>");
return;
}
using (ITraceProcessor trace = TraceProcessor.Create(args[0]))
{
IPendingResult<IThreadDataSource> pendingThreadData = trace.UseThreads();
Dictionary<IProcess, int> syscallsPerCommandLine = new Dictionary<IProcess, int>();
trace.UseStreaming().UseSyscalls(ConsumerSchedule.SecondPass, context =>
{
Syscall syscall = context.Data;
IProcess process = syscall.GetThread(pendingThreadData.Result)?.Process;
if (process == null)
{
return;
}
if (!syscallsPerCommandLine.ContainsKey(process))
{
syscallsPerCommandLine.Add(process, 0);
}
++syscallsPerCommandLine[process];
});
trace.Process();
Console.WriteLine("Process Command Line: Syscalls Count");
foreach (IProcess process in syscallsPerCommandLine.Keys)
{
Console.WriteLine($"{process.CommandLine}: {syscallsPerCommandLine[process]}");
}
}
}
}
Como funciona o streaming
Por padrão, todos os dados de streaming são fornecidos durante a primeira passagem pelo rastreamento, e os dados armazenados em buffer de outras fontes não estão disponíveis. O exemplo acima mostra como combinar streaming com buffering – os dados de thread são armazenados em buffer antes que os dados syscall sejam transmitidos. Como resultado, o rastreamento deve ser lido duas vezes – uma para obter os dados de thread em buffer e uma segunda vez para aceder aos dados de sistema de chamadas em fluxo, agora que os dados de thread em buffer estão disponíveis. Para combinar streaming e buffering dessa maneira, o exemplo passa ConsumerSchedule.SecondPass para a função trace.UseStreaming().UseSyscalls(), o que faz com que o processamento syscall aconteça durante uma segunda passagem pela análise de rastreamento. Ao ser executado numa segunda passagem, o retorno de chamada syscall pode aceder ao resultado pendente do trace.UseThreads() quando processa cada syscall. Sem este argumento opcional, o syscall streaming teria ocorrido na primeira passagem pelo rastreamento (haveria apenas uma passagem), e o resultado pendente de trace.UseThreads() ainda não estaria disponível. Nesse caso, o retorno de chamada ainda teria acesso ao ThreadId do syscall, mas não teria acesso ao processo para o thread (porque o thread para processar dados de vinculação é fornecido por meio de outros eventos que podem não ter sido processados ainda).
Algumas diferenças importantes no uso entre buffering e streaming:
- O buffer retorna um IPendingResult<T>e o resultado que ele mantém está disponível somente antes que o rastreamento tenha sido processado. Após o rastreamento ter sido processado, os resultados podem ser enumerados usando técnicas como foreach e LINQ.
- O streaming não retorna valor (void) e, em vez disso, utiliza uma função de retorno de chamada. Ele executa a função de retorno uma vez à medida que cada item fica disponível. Como os dados não são armazenados em buffer, nunca há uma lista de resultados para enumerar com foreach ou LINQ – o retorno de chamada de streaming precisa armazenar em buffer qualquer parte dos dados que deseja salvar para uso após a conclusão do processamento.
- O código para processar dados armazenados em buffer aparece após a chamada para trace.Process(), quando os resultados pendentes estiverem disponíveis.
- O código para processar dados de streaming aparece antes da chamada para trace.Process(), como um retorno de chamada para o método trace.UseStreaming.Use...().
- Um consumidor de streaming pode optar por processar apenas parte do fluxo e cancelar retornos de chamada futuros chamando context.Cancel(). Um consumidor de buffering sempre recebe uma lista em buffer completa.
Dados de streaming correlacionados
Às vezes, os dados de rastreamento vêm em uma sequência de eventos – por exemplo, syscalls são registrados por meio de eventos de entrada e saída separados, mas os dados combinados de ambos os eventos podem ser mais úteis. O rastreamento do método UseStreaming().UseSyscalls() correlaciona os dados de ambos os eventos e fornece-os à medida que a dupla se torna disponível. Alguns tipos de dados correlacionados estão disponíveis através de trace.UseStreaming().
| Código | Descrição |
|---|---|
| traço. UseStreaming(). UseContextSwitchData() | Transmite dados de mudanças de contexto correlacionados (de eventos compactos e não compactos, com SwitchInThreadIds mais precisos do que eventos crus não compactos). |
| traço. UseStreaming(). UseScheduledTasks() | Correlaciona fluxos de dados de tarefas agendadas. |
| traço. UseStreaming(). UseSyscalls() | Transmite dados de chamadas do sistema correlacionados. |
| traço. UseStreaming(). UseWindowInFocus() | Fluxos correlacionados de dados de janela em foco. |
Eventos de streaming independentes
Além disso, trace.UseStreaming() fornece eventos analisados para uma série de tipos diferentes de eventos independentes:
| Código | Descrição |
|---|---|
| traço. UseStreaming(). UseLastBranchRecordEvents() | Os fluxos processam eventos do último registro de ramificação (LBR). |
| traço. UseStreaming(). UseReadyThreadEvents() | Os fluxos analisaram eventos de thread prontos. |
| traço. UseStreaming(). UseThreadCreateEvents() | Streams analisados criam eventos de criação de thread. |
| traço. UseStreaming(). UseThreadExitEvents() | Transmite eventos de saída de threads analisados. |
| traço. UseStreaming(). UseThreadRundownStartEvents() | Os fluxos analisaram eventos de início de rundown de thread. |
| trace.UseStreaming(). UseThreadRundownStopEvents() | Streams analisaram eventos de parada de rundown de thread. |
| traço. UseStreaming(). UseThreadSetNameEvents() | Streams analisou eventos de nome do conjunto de threads. |
Eventos de streaming subjacentes para dados correlacionados
Por fim, UseStreaming() também fornece os eventos subjacentes usados para correlacionar dados na lista acima. Estes acontecimentos subjacentes são:
| Código | Descrição | Incluído em |
|---|---|---|
| traço. UseStreaming(). UseCompactContextSwitchEvents() | Os fluxos analisam eventos compactos de mudança de contexto. | traço. UseStreaming(). UseContextSwitchData() |
| traço. UseStreaming(). UseContextSwitchEvents() | Os fluxos analisam eventos de comutação de contexto. SwitchInThreadIds pode não ser preciso em alguns casos. | traço. UseStreaming(). UseContextSwitchData() |
| traço. UseStreaming(). UseFocusChangeEvents() | Os fluxos analisaram eventos de alteração de foco da janela. | traço. UseStreaming(). UseWindowInFocus() |
| traço. UseStreaming(). UseScheduledTaskStartEvents() | Fluxos analisam eventos de início de tarefas agendadas. | traço. UseStreaming(). UseScheduledTasks() |
| traço. UseStreaming(). UseScheduledTaskStopEvents() | Fluxos processam eventos de paragem de tarefas agendadas. | traço. UseStreaming(). UseScheduledTasks() |
| traço. UseStreaming(). UseScheduledTaskTriggerEvents() | Os fluxos analisaram eventos de gatilho de tarefas agendadas. | traço. UseStreaming(). UseScheduledTasks() |
| trace. UseStreaming(). UseSessionLayerSetActiveWindowEvents() | Fluxos analisados no nível de sessão definiram eventos da janela ativa. | traço. UseStreaming(). UseWindowInFocus() |
| traço. UseStreaming(). UseSyscallEnterEvents() | Streams de eventos de entrada de syscall são analisados. | traço. UseStreaming(). UseSyscalls() |
| traço. UseStreaming(). UseSyscallExitEvents() | Transmite eventos de saída de chamadas de sistema analisados. | traço. UseStreaming(). UseSyscalls() |
Próximas Etapas
Neste tutorial, você aprendeu como usar o streaming para acessar dados de rastreamento imediatamente e usando menos memória.
O próximo passo é procurar acessar os dados que você deseja de seus rastreamentos. Veja as amostras para algumas ideias. Observe que nem todos os rastreamentos incluem todos os tipos de dados suportados.
Windows developer