Menggunakan streaming dengan TraceProcessor
Secara default, TraceProcessor mengakses data dengan memuatnya ke dalam memori saat jejak diproses. Pendekatan buffering ini mudah digunakan, tetapi bisa mahal dalam hal penggunaan memori.
TraceProcessor juga menyediakan jejak. UseStreaming(), yang mendukung akses beberapa jenis data pelacakan dengan cara streaming (memproses data saat dibaca dari file pelacakan, daripada buffering data tersebut dalam memori). Misalnya, jejak syscalls bisa sangat besar, dan buffering seluruh daftar syscalls dalam jejak bisa sangat mahal.
Mengakses data yang di-buffer
Kode berikut menunjukkan mengakses data syscall dengan cara normal yang di-buffer melalui jejak. 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]}");
}
}
}
}
Mengakses data streaming
Dengan pelacakan syscalls besar, mencoba buffer data syscall dalam memori bisa sangat mahal, atau bahkan mungkin tidak mungkin. Kode berikut menunjukkan cara mengakses data syscall yang sama dengan cara streaming, menggantikan jejak. UseSyscalls() dengan jejak. 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]}");
}
}
}
}
Cara kerja streaming
Secara default, semua data streaming disediakan selama pelacakan pertama, dan data yang di-buffer dari sumber lain tidak tersedia. Contoh di atas menunjukkan cara menggabungkan streaming dengan buffering – data utas di-buffer sebelum data syscall dialirkan. Akibatnya, jejak harus dibaca dua kali - sekali untuk mendapatkan data utas buffer, dan kedua kalinya untuk mengakses data syscall streaming dengan data utas buffer sekarang tersedia. Untuk menggabungkan streaming dan buffering dengan cara ini, contoh meneruskan ConsumerSchedule.SecondPass ke pelacakan. UseStreaming(). UseSyscalls(), yang menyebabkan pemrosesan syscall terjadi dalam detik melewati jejak. Dengan menjalankan dalam pass kedua, panggilan balik syscall dapat mengakses hasil yang tertunda dari pelacakan. UseThreads() saat memproses setiap syscall. Tanpa argumen opsional ini, streaming syscall akan berjalan di pertama melewati jejak (hanya akan ada satu pass), dan hasil yang tertunda dari jejak. UseThreads() belum akan tersedia. Dalam hal ini, panggilan balik masih akan memiliki akses ke ThreadId dari syscall, tetapi tidak akan memiliki akses ke proses untuk utas (karena utas untuk memproses data penautan disediakan melalui peristiwa lain yang mungkin belum diproses).
Beberapa perbedaan utama dalam penggunaan antara buffering dan streaming:
- Buffering mengembalikan T IPendingResult<>, dan hasil yang disimpannya hanya tersedia sebelum jejak diproses. Setelah jejak diproses, hasilnya dapat dijumlahkan menggunakan teknik seperti foreach dan LINQ.
- Streaming mengembalikan kekosongan dan sebaliknya mengambil argumen panggilan balik. Ini memanggil panggilan balik sekali saat setiap item tersedia. Karena data tidak di-buffer, tidak pernah ada daftar hasil untuk dijumlahkan dengan foreach atau LINQ - panggilan balik streaming perlu buffer bagian mana pun dari data yang ingin disimpan untuk digunakan setelah pemrosesan selesai.
- Kode untuk memproses data buffer muncul setelah panggilan untuk melacak. Proses(), ketika hasil yang tertunda tersedia.
- Kode untuk memproses data streaming muncul sebelum panggilan untuk dilacak. Process(), sebagai panggilan balik ke pelacakan. UseStreaming.Use... () metode.
- Konsumen streaming hanya dapat memilih untuk memproses bagian dari streaming dan membatalkan panggilan balik di masa mendatang dengan memanggil konteks. Batal(). Konsumen buffering selalu diberikan daftar lengkap yang di-buffer.
Data streaming berkorelasi
Terkadang data pelacakan datang dalam urutan peristiwa - misalnya, syscalls dicatat melalui peristiwa masuk dan keluar terpisah, tetapi data gabungan dari kedua peristiwa dapat lebih membantu. Pelacakan metode. UseStreaming(). UseSyscalls() menghubungkan data dari kedua peristiwa ini dan menyediakannya saat pasangan tersedia. Beberapa jenis data berkorelasi tersedia melalui jejak. UseStreaming():
Kode | Deskripsi |
---|---|
bekas. UseStreaming(). UseContextSwitchData() | Mengalirkan data pengalihan konteks yang berkorelasi (dari peristiwa ringkas dan tidak ringkas, dengan SwitchInThreadIds yang lebih akurat daripada peristiwa mentah yang tidak ringkas). |
bekas. UseStreaming(). UseScheduledTasks() | Mengalirkan data tugas terjadwal yang berkorelasi. |
bekas. UseStreaming(). UseSyscalls() | Mengalirkan data panggilan sistem yang berkorelasi. |
bekas. UseStreaming(). UseWindowInFocus() | Mengalirkan data window-in-focus yang berkorelasi. |
Peristiwa streaming mandiri
Selain itu, lacak. UseStreaming() menyediakan peristiwa yang diurai untuk sejumlah jenis peristiwa mandiri yang berbeda:
Kode | Deskripsi |
---|---|
bekas. UseStreaming(). UseLastBranchRecordEvents() | Streaming mengurai peristiwa rekaman cabang terakhir (LBR). |
bekas. UseStreaming(). UseReadyThreadEvents() | Streaming peristiwa alur siap diurai. |
bekas. UseStreaming(). UseThreadCreateEvents() | Aliran utas yang diurai membuat peristiwa. |
bekas. UseStreaming(). UseThreadExitEvents() | Streaming peristiwa keluar utas yang diurai. |
bekas. UseStreaming(). UseThreadRundownStartEvents() | Streaming peristiwa mulai rundown utas yang diurai. |
bekas. UseStreaming(). UseThreadRundownStopEvents() | Streaming peristiwa penghentian rundown utas yang diurai. |
bekas. UseStreaming(). UseThreadSetNameEvents() | Streaming peristiwa nama kumpulan utas yang diurai. |
Peristiwa streaming yang mendasar untuk data yang berkorelasi
Akhirnya, lacak. UseStreaming() juga menyediakan peristiwa mendasar yang digunakan untuk menghubungkan data dalam daftar di atas. Peristiwa yang mendasar ini adalah:
Kode | Deskripsi | Disertakan dalam |
---|---|---|
bekas. UseStreaming(). UseCompactContextSwitchEvents() | Streaming mengurai peristiwa pengalihan konteks ringkas. | bekas. UseStreaming(). UseContextSwitchData() |
bekas. UseStreaming(). UseContextSwitchEvents() | Streaming peristiwa pengalihan konteks yang diurai. SwitchInThreadIds mungkin tidak akurat dalam beberapa kasus. | bekas. UseStreaming(). UseContextSwitchData() |
bekas. UseStreaming(). UseFocusChangeEvents() | Streaming peristiwa perubahan fokus jendela yang diurai. | bekas. UseStreaming(). UseWindowInFocus() |
bekas. UseStreaming(). UseScheduledTaskStartEvents() | Streaming acara mulai tugas terjadwal yang diurai. | bekas. UseStreaming(). UseScheduledTasks() |
bekas. UseStreaming(). UseScheduledTaskStopEvents() | Streaming acara berhenti tugas terjadwal yang diurai. | bekas. UseStreaming(). UseScheduledTasks() |
bekas. UseStreaming(). UseScheduledTaskTriggerEvents() | Mengalirkan peristiwa pemicu tugas terjadwal yang diurai. | bekas. UseStreaming(). UseScheduledTasks() |
bekas. UseStreaming(). UseSessionLayerSetActiveWindowEvents() | Streams parsed session-layer set active window events. | bekas. UseStreaming(). UseWindowInFocus() |
bekas. UseStreaming(). UseSyscallEnterEvents() | Streams parsed syscall masukkan peristiwa. | bekas. UseStreaming(). UseSyscalls() |
bekas. UseStreaming(). UseSyscallExitEvents() | Streaming peristiwa keluar syscall yang diurai. | bekas. UseStreaming(). UseSyscalls() |
Langkah berikutnya
Dalam tutorial ini, Anda mempelajari cara menggunakan streaming untuk mengakses data pelacakan segera dan menggunakan lebih sedikit memori.
Langkah selanjutnya adalah melihat akses data yang Anda inginkan dari jejak Anda. Lihat sampel untuk beberapa ide. Perhatikan bahwa tidak semua jejak menyertakan semua jenis data yang didukung.
Windows developer