Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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 trace.UseStreaming(), yang mendukung akses beberapa jenis data pelacakan secara streaming (memproses data saat dibaca dari file pelacakan, daripada menyimpan data tersebut dalam memori). Misalnya, sebuah "trace" syscalls bisa sangat besar, dan buffering seluruh daftar syscalls dalam sebuah "trace" bisa sangat mahal.
Mengakses data yang di-buffer
Kode berikut menunjukkan cara mengakses data syscall dengan cara yang normal dan ter-buffer melalui 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]}");
}
}
}
}
Mengakses data streaming
Dengan jejak syscalls yang besar, mencoba menyimpan data syscall dalam memori bisa sangat mahal, atau bahkan mungkin tidak bisa dilakukan. Kode berikut menunjukkan cara mengakses data syscall yang sama dengan cara streaming, menggantikan trace.UseSyscalls() dengan 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]}");
}
}
}
}
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, penelusuran harus dibaca dua kali - sekali untuk mendapatkan data utas yang dibuffer, dan kedua kali untuk mengakses data syscall yang dialirkan dengan data utas yang dibuffer sekarang tersedia. Untuk menggabungkan streaming dan buffering dengan cara ini, contoh meneruskan ConsumerSchedule.SecondPass ke lacak.UseStreaming().UseSyscalls(), yang menyebabkan pengolahan syscall terjadi pada pengulangan kedua melalui lacak tersebut. Dengan menjalankan pass kedua, panggilan balik syscall dapat mengakses hasil yang tertunda dari pelacakan UseThreads() saat memproses setiap syscall. Tanpa argumen opsional ini, streaming syscall akan dijalankan pada lintasan pertama melalui jejak (hanya akan ada satu lintasan), dan hasil yang tertunda dari trace.UseThreads() tidak 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 IPendingResult<T>, 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 yang dibuffer muncul setelah panggilan ke trace.Process(), ketika hasil yang masih menunggu tersedia.
- Kode untuk memproses data streaming muncul sebelum panggilan ke trace.Process(), sebagai callback ke metode trace.UseStreaming.Use...().
- Seorang konsumen streaming dapat memilih untuk hanya memproses sebagian dari streaming dan membatalkan panggilan balik di masa mendatang dengan memanggil context.Cancel(). Konsumen yang melakukan buffering selalu diberikan daftar lengkap yang sudah 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. Metode pelacakan trace.UseStreaming().UseSyscalls() menghubungkan data dari kedua peristiwa ini dan menyediakannya saat data pasangan tersebut tersedia. Beberapa jenis data berkorelasi dapat diakses melalui trace.UseStreaming():
| Kode | Deskripsi |
|---|---|
| bekas. UseStreaming(). UseContextSwitchData() | Mengalirkan data pergantian konteks yang berkorelasi (dari peristiwa kompak dan non-kompak, dengan SwitchInThreadIds yang lebih akurat daripada peristiwa mentah yang non-kompak). |
| bekas. UseStreaming(). UseScheduledTasks() | Menyediakan data tugas terjadwal terkoordinasi. |
| trace. UseStreaming(). UseSyscalls() | Menyalurkan data panggilan sistem yang berkorelasi. |
| bekas. UseStreaming(). UseWindowInFocus() | Mengalirkan data window-in-focus yang berkorelasi. |
Acara streaming khusus
Selain itu, Trace.UseStreaming() menyediakan peristiwa yang diparsing untuk sejumlah jenis peristiwa mandiri yang berbeda.
| Kode | Deskripsi |
|---|---|
| pelacakan.UseStreaming().UseLastBranchRecordEvents() | Streaming mengurai peristiwa rekaman cabang terakhir (LBR). |
| lacak.UseStreaming().UseReadyThreadEvents() | Streaming peristiwa alur siap diurai. |
| bekas. UseStreaming(). UseThreadCreateEvents() | Aliran utas yang diurai membuat peristiwa. |
| lacak.UseStreaming().UseThreadExitEvents() | Streaming peristiwa keluar utas yang diurai. |
| bekas. UseStreaming(). UseThreadRundownStartEvents() | Mengalirkan peristiwa mulai penguraian rangkaian utas. |
| bekas. UseStreaming(). UseThreadRundownStopEvents() | Streaming penghentian peristiwa rundown utas yang diproses. |
| pelacakan.UseStreaming().UseThreadSetNameEvents() | Aliran peristiwa penamaan kumpulan utas yang telah diurai. |
Peristiwa streaming dasar 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() | Mengalirkan peristiwa perubahan fokus jendela yang telah diurai. | bekas. UseStreaming(). UseWindowInFocus() |
| bekas. UseStreaming(). UseScheduledTaskStartEvents() | Mengalirkan peristiwa dimulainya tugas terjadwal yang telah diurai. | bekas. UseStreaming(). UseScheduledTasks() |
| Trace.UseStreaming().UseScheduledTaskStopEvents() | Streaming acara berhenti tugas terjadwal yang diurai. | bekas. UseStreaming(). UseScheduledTasks() |
| bekas. UseStreaming(). UseScheduledTaskTriggerEvents() | Memproses peristiwa pemicu tugas terjadwal yang telah diurai. | bekas. UseStreaming(). UseScheduledTasks() |
| bekas. UseStreaming(). UseSessionLayerSetActiveWindowEvents() | Stream mengurai sesi-lapisan yang mengatur peristiwa jendela aktif. | bekas. UseStreaming(). UseWindowInFocus() |
| bekas. UseStreaming(). UseSyscallEnterEvents() | Streams parsed syscall masukkan peristiwa. | trace. UseStreaming(). UseSyscalls() |
| bekas. UseStreaming(). UseSyscallExitEvents() | Mengalirkan peristiwa keluar syscall yang telah diurai. | trace. UseStreaming(). UseSyscalls() |
Langkah Selanjutnya
Dalam tutorial ini, Anda mempelajari cara menggunakan streaming untuk mengakses data pelacakan segera dan menggunakan lebih sedikit memori.
Langkah selanjutnya adalah melihat dan mengakses data yang Anda inginkan dari rekam jejak Anda. Lihat sampel untuk beberapa ide. Perhatikan bahwa tidak semua jejak menyertakan semua jenis data yang didukung.
Windows developer