Руководство провайдера ETW на основе имени.Net 4.0
Я хочу получить руководство для провайдера событий на основе имени провайдера событий (например, Sample-Test)
Образец кода
[EventSource(Name = "Sample-Test")]
public sealed class EventSourceLogger : EventSource
Вот мой провайдер
internal class EventProviderVersionOne : EventProvider
{
internal EventProviderVersionOne(Guid id)
: base(id)
{ }
[StructLayout(LayoutKind.Explicit, Size = 16)]
private struct EventData
{
[FieldOffset(0)]
internal UInt64 DataPointer;
[FieldOffset(8)]
internal uint Size;
[FieldOffset(12)]
internal int Reserved;
}
}
Мой класс регистратора для регистрации событий
public class EventLogger
{
public static EventLogger Log = new EventLogger();
internal static EventProviderVersionOne MProvider = new EventProviderVersionOne(new Guid(ConfigurationSettings.AppSettings["EtwEventProviderGuid"]));
...
}
Пожалуйста, предложите код, необходимый для получения GUID на основе EventSourceName. Я уже зарегистрировался в Eventvwr.
3 ответа
Я нашел свой ответ в github.
https://github.com/jonwagner/EventSourceProxy/blob/master/EventSourceProxy/EventSourceManifest.cs
Благодарю.
Следующее представляется алгоритмом в менее запутанной форме:
public static byte[] Concat(byte[] a, byte[] b)
{
byte[] retval = new byte[a.Length + b.Length];
a.CopyTo(retval, 0);
b.CopyTo(retval, a.Length);
return retval;
}
public static byte[] Slice(byte[] a, int startIndex, int length)
{
byte[] retval = new byte[length];
Array.Copy(a, startIndex, retval, 0, length);
return retval;
}
private static Guid GenerateGuidFromName(string name)
{
byte[] namespaceGuid = Guid.Parse("b22d2c48-90c3-c847-87f8-1a15bfc130fb").ToByteArray();
byte[] nameBytes = Encoding.BigEndianUnicode.GetBytes(name);
byte[] sha1Hash = SHA1.Create().ComputeHash(Concat(namespaceGuid, nameBytes));
byte[] guidBytes = Slice(sha1Hash, 0, 16);
// Overwrite the top 4 bits of the 8th byte with 0101
{
guidBytes[7] &= 0x0F;
guidBytes[7] |= 0x50;
}
return new Guid(guidBytes);
}
Это мой быстрый и грязный способ сделать это. Он отлично работает для служебной программы, в которой я его использую, но я бы кэшировал сопоставления в долго работающем производственном приложении, чтобы избежать непредвиденных последствий создания источников событий.
private static Guid GenerateGuidFromName(string name)
{
var eventSource = new EventSource(name);
return eventSource.Guid;
}
Я использовал PerfView, чтобы получить GUID. Начните захват, включите провайдера, которому вы хотите знать GUID, запустите ведение журнала, перейдите к записи "log" и здесь вы увидите GUID.
Когда вы зарегистрировали провайдера в масштабе всей системы, вы можете использовать xperf -providers
чтобы увидеть GUID.