Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
TraceProcessor ve výchozím nastavení přistupuje k datům načtením do paměti při zpracování trasování. Tento přístup k ukládání do vyrovnávací paměti se snadno používá, ale může být nákladný z hlediska využití paměti.
TraceProcessor také poskytuje trace.UseStreaming(), které podporuje přístup k více typům trasovacích dat ve streamovacím režimu (zpracování dat při čtení z trasovacího souboru, místo ukládání těchto dat do vyrovnávací paměti). Například trasování systémových volání může být poměrně rozsáhlé a ukládání celého seznamu těchto volání do vyrovnávací paměti může být poměrně nákladné.
Přístup k datům uloženým ve vyrovnávací paměti
Následující kód ukazuje přístup k datům syscall normálním, vyrovnávacím způsobem pomocí 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]}");
}
}
}
}
Přístup ke streamovaným datům
Při rozsáhlém sledování systémových volání může být pokus o ukládání dat systémových volání do paměti poměrně nákladný, nebo dokonce nemožný. Následující kód ukazuje, jak přistupovat ke stejným datům syscall způsobem streamování tím, že nahradíte trace.UseSyscalls() s 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]}");
}
}
}
}
Jak funguje streamování
Ve výchozím nastavení jsou všechna streamovaná data poskytována během prvního průchodu trasováním a data uložená do vyrovnávací paměti z jiných zdrojů nejsou k dispozici. Výše uvedený příklad ukazuje, jak kombinovat streamování s ukládáním do vyrovnávací paměti – data vláken jsou nejprve uložena do vyrovnávací paměti a poté jsou data syscallu streamována. V důsledku toho musí být stopa přečtena dvakrát – jednou za účelem získání dat vlákna ve vyrovnávací paměti a podruhé pro přístup ke streamovaným datům systémových volání s nyní dostupnými daty vlákna ve vyrovnávací paměti. Aby bylo možné zkombinovat streamování a ukládání do vyrovnávací paměti tímto způsobem, příklad předá ConsumerSchedule.SecondPass do trace.UseStreaming().UseSyscalls(), což způsobí, že zpracování syscall proběhne během druhého průchodu skrze trasování. Při spuštění ve druhém průchodu může zpětné volání syscall přistupovat k čekajícímu výsledku ze funkce trace.UseThreads() při zpracování každého volání syscall. Bez tohoto volitelného argumentu by streamování systémových volání proběhlo při prvním průchodu trasováním (byl by pouze jeden průchod) a čekající výsledek z trasování pomocí UseThreads() by ještě nebyl k dispozici. V takovém případě by zpětné volání stále mělo přístup k ThreadId z volání systému, ale nemělo by přístup k procesu pro vlákno (protože data propojující vlákno s procesem jsou poskytována prostřednictvím jiných událostí, které možná ještě nebyly zpracovány).
Mezi ukládáním do vyrovnávací paměti a streamováním se liší některé klíčové rozdíly:
- Bufferování vrátí IPendingResult<T>a výsledek, který obsahuje, je k dispozici pouze před zpracováním sledu. Po zpracování trasování mohou být výsledky vyjmenovány pomocí technik jako foreach a LINQ.
- Streamování vrací void a místo toho přijímá argument zpětného volání. Volá zpětné volání jednou, jakmile bude každá položka k dispozici. Vzhledem k tomu, že data nejsou ukládána do vyrovnávací paměti, nikdy neexistuje seznam výsledků, které lze vypsat pomocí foreach nebo LINQ – streamovací zpětné volání musí ukládat do vyrovnávací paměti tu část dat, kterou chce po dokončení zpracování uchovat k pozdějšímu použití.
- Kód pro zpracování dat uložených ve vyrovnávací paměti je spuštěn po volání trace.Process(), když jsou k dispozici nevyřízené výsledky.
- Kód pro zpracování streamovaných dat je umístěn před voláním trace.Process() a funguje jako zpětné volání pro metodu trace.UseStreaming.Use...().
- Uživatel streamování se může rozhodnout zpracovat pouze část datového proudu a zrušit budoucí vyvolání zpětných volání voláním context.Cancel(). Spotřebitel vyrovnávací paměti vždy obdrží úplný, vyrovnaný seznam.
Korelace streamovaných dat
Někdy se data trasování zobrazují v posloupnosti událostí – například volání syscall se protokolují prostřednictvím samostatných událostí enter a exit, ale kombinovaná data z obou událostí mohou být užitečnější. Metoda trace.UseStreaming().UseSyscalls() koreluje data z obou těchto událostí a poskytuje je, jakmile jsou páry k dispozici. Prostřednictvím funkce trace.UseStreaming() je k dispozici několik typů korelovaných dat.
| Kód | Popis |
|---|---|
| stopa. UseStreaming(). UseContextSwitchData() | Streamuje korelovaná data kontextového přepínání (z kompaktních a nekompaktovaných událostí s přesnějšími identifikátory SwitchInThreadId než u syrových nekompaktovaných událostí). |
| trasování.UseStreaming().UseScheduledTasks() | Streamy korelovaly data naplánovaných úkolů. |
| Trace.UseStreaming().UseSyscalls(). | Streamy korelují data systémových volání. |
| trasování.UseStreaming().UseWindowInFocus() | Streamy korelují data fokusu v okně. |
Samostatné události streamování
Kromě toho trace.UseStreaming() poskytuje parsované události pro různé samostatné typy událostí:
| Kód | Popis |
|---|---|
| Trace().UseStreaming().UseLastBranchRecordEvents() | Toky analyzovaly události záznamu poslední větve (LBR). |
| tracing.UseStreaming(). UseReadyThreadEvents() | Streamy zpracované připravené události vlákna. |
| sledování.UseStreaming().UseThreadCreateEvents() | Streamy analyzované vlákno vytvářejí události. |
| stopa. UseStreaming(). UseThreadExitEvents() | Streamy zpracovaly události ukončení vlákna. |
| stopa. UseStreaming(). UseThreadRundownStartEvents() | Streamy analyzovaly události zahájení rozběhu vlákna. |
| trasování.UseStreaming().UseThreadRundownStopEvents() | Streamy zpracovávaly události zastavení spuštění vláken. |
| stopa. UseStreaming(). UseThreadSetNameEvents() | Streamy zpracovaly události názvů sad vláken. |
Podkladové události streamování pro korelovaná data
Nakonec trace.UseStreaming() také poskytuje základní události použité ke korelaci dat v seznamu výše. Mezi tyto základní události patří:
| Kód | Popis | Zahrnuto v |
|---|---|---|
| Protokol.UseStreaming().UseCompactContextSwitchEvents() | Streamy parsovaly události přepínače kompaktního kontextu. | stopa. UseStreaming(). UseContextSwitchData() |
| stopa. UseStreaming(). UseContextSwitchEvents() | Toky analyzovaly události přepínání kontextu. SwitchInThreadIds nemusí být v některých případech přesné. | stopa. UseStreaming(). UseContextSwitchData() |
| stopa. UseStreaming(). UseFocusChangeEvents() | Proud analyzovaných událostí změny zaměření okna | trasování.UseStreaming().UseWindowInFocus() |
| výstup.UseStreaming().UseScheduledTaskStartEvents() | Streamy analyzované události zahájení naplánované úlohy. | trasování.UseStreaming().UseScheduledTasks() |
| stopa. UseStreaming(). UseScheduledTaskStopEvents() | Analyzované události zastavení naplánovaných úloh streamů. | trasování.UseStreaming().UseScheduledTasks() |
| stopa. UseStreaming(). UseScheduledTaskTriggerEvents() | Zpracování streamů událostí spouštěče naplánovaných úloh. | trasování.UseStreaming().UseScheduledTasks() |
| stopa. UseStreaming(). UseSessionLayerSetActiveWindowEvents() | Streamy analyzovaly události nastavení aktivního okna na úrovni relace. | trasování.UseStreaming().UseWindowInFocus() |
| stopa. UseStreaming(). UseSyscallEnterEvents() | Streamy analyzovaly události syscall enter. | Trace.UseStreaming().UseSyscalls(). |
| stopa. UseStreaming(). UseSyscallExitEvents() | Streamy událostí ukončení systémového volání. | Trace.UseStreaming().UseSyscalls(). |
Další kroky
V tomto kurzu jste se naučili používat streamování pro přístup k datům trasování okamžitě a s využitím menší paměti.
Dalším krokem je přístup k datům, která chcete získat z vašich záznamů. Podívejte se na ukázky a podívejte se na některé nápady. Mějte na paměti, že ne všechny stopy obsahují všechny podporované typy dat.
Windows developer