How to Enable WPP Tracing Through the Windows Event Log Service
The Windows Event Log service supports WPP logging and decoding. This topic describes how to enable WPP tracing through the Windows Event Log service.
Enabling WPP tracing in this scenario requires no extra work to the WPP provider. However, to use the Windows Event Log service, you must supply a manifest and an Event Log provider. To enable WPP tracing, declare a debug channel and specify the associated control GUID as declared for your WPP provider.
WPP tracing is not meant to be enabled all the time, so by default the enable attribute in the manifest should be set to false. When WPP tracing is needed, change the attribute in the manifest, so that enabled=»true».
You cannot specify or individually select control bits. To enable all WPP events to this channel, specify a keyword value of 0XFFFFFFFF. Internally, control bits map to keywords; if you know which bit maps to a specific keyword, you can select that keyword to get a specific set of events. In the example manifest, the keyword value is 0xFFFF because less than 16 WPP control bits are needed. To get a specific set of events after installation, you may change the keywords using the wevtutil.exe command-line utility. The command is:
wevtutil sl /k:
Note that the channel must first be disabled to change the keyword value.
Declaring a channel in this manner enables both the WPP provider (whose control GUID is specified) and the Event Log provider (under which this channel is declared) to access the debug channel, so either provider can write to this channel. WPP events or normal ETW events can now be seen under this channel through the event viewer.
EVENT_TRACE_LOGFILEA structure (evntrace.h)
The EVENT_TRACE_LOGFILE structure specifies how the consumer wants to read events (from a log file or in real-time) and the callbacks that will receive the events.
When ETW flushes a buffer, this structure contains information about the event tracing session and the buffer that ETW flushed.
Syntax
Members
Name of the log file used by the event tracing session. Specify a value for this member if you are consuming from a log file.
This member must be NULL if LoggerName is specified.
You must know the log file name the controller specified. If the controller logged events to a private session (the controller set the LogFileMode member of EVENT_TRACE_PROPERTIES to EVENT_TRACE_PRIVATE_LOGGER_MODE), the file name must include the process identifier that ETW appended to the log file name. For example, if the controller named the log file xyz.etl and the process identifier is 123, ETW uses xyz.etl_123 as the file name.
If the controller set the LogFileMode member of EVENT_TRACE_PROPERTIES to EVENT_TRACE_FILE_MODE_NEWFILE, the log file name must include the sequential serial number used to create each new log file.
The user consuming the events must have permissions to read the file.
Name of the event tracing session. Specify a value for this member if you want to consume events in real time. This member must be NULL if LogFileName is specified.
You can only consume events in real time if the controller set the LogFileMode member of EVENT_TRACE_PROPERTIES to EVENT_TRACE_REAL_TIME_MODE.
Only users with administrative privileges, users in the Performance Log Users group, and applications running as LocalSystem, LocalService, NetworkService can consume events in real time. To grant a restricted user the ability to consume events in real time, add them to the Performance Log Users group or call EventAccessControl.
WindowsВ XP and WindowsВ 2000:В В Anyone can consume real time events.
On output, the current time, in 100-nanosecond intervals since midnight, January 1, 1601.
On output, the number of buffers processed.
Reserved. Do not use.
Modes for processing events. The modes are defined in the Evntcons.h header file. You can specify one or more of the following modes:
Value | Meaning |
---|---|
PROCESS_TRACE_MODE_EVENT_RECORD | Specify this mode if you want to receive events in the new EVENT_RECORD format. To receive events in the new format you must specify a callback in the EventRecordCallback member. If you do not specify this mode, you receive events in the old format through the callback specified in the EventCallback member. Prior to WindowsВ Vista:В В Not supported. |
PROCESS_TRACE_MODE_RAW_TIMESTAMP | Specify this mode if you do not want the time stamp value in the TimeStamp member of EVENT_HEADER and EVENT_TRACE_HEADER converted to system time (leaves the time stamp value in the resolution that the controller specified in the Wnode.ClientContext member of EVENT_TRACE_PROPERTIES). Prior to WindowsВ Vista:В В Not supported. |
PROCESS_TRACE_MODE_REAL_TIME | Specify this mode to receive events in real time (you must specify this mode if LoggerName is not NULL). |
On output, an EVENT_TRACE structure that contains the last event processed.
On output, a TRACE_LOGFILE_HEADER structure that contains general information about the session and the computer on which the session ran.
Pointer to the BufferCallback function that receives buffer-related statistics for each buffer ETW flushes. ETW calls this callback after it delivers all the events in the buffer. This callback is optional.
On output, contains the size of each buffer, in bytes.
On output, contains the number of bytes in the buffer that contain valid information.
Pointer to the EventCallback function that ETW calls for each event in the buffer.
Specify this callback if you are consuming events from a provider that used one of the TraceEvent functions to log events.
Pointer to the EventRecordCallback function that ETW calls for each event in the buffer.
Specify this callback if you are consuming events from a provider that used one of the EventWrite functions to log events.
Prior to WindowsВ Vista:В В Not supported.
On output, if this member is TRUE, the event tracing session is the NT Kernel Logger. Otherwise, it is another event tracing session.
Context data that a consumer can specify when calling OpenTrace. If the consumer uses EventRecordCallback to consume events, ETW sets the UserContext member of the EVENT_RECORD structure to this value.
Prior to WindowsВ Vista:В В Not supported.
Remarks
Be sure to initialize the memory for this structure to zero before setting any members.
Consumers pass this structure to the OpenTrace function.
When ETW flushes a buffer, it passes the structure to the consumer’s BufferCallback function.
The evntrace.h header defines EVENT_TRACE_LOGFILE as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.
Вертим логи как хотим ― анализ журналов в системах Windows
Пора поговорить про удобную работу с логами, тем более что в Windows есть масса неочевидных инструментов для этого. Например, Log Parser, который порой просто незаменим.
В статье не будет про серьезные вещи вроде Splunk и ELK (Elasticsearch + Logstash + Kibana). Сфокусируемся на простом и бесплатном.
Журналы и командная строка
До появления PowerShell можно было использовать такие утилиты cmd как find и findstr. Они вполне подходят для простой автоматизации. Например, когда мне понадобилось отлавливать ошибки в обмене 1С 7.7 я использовал в скриптах обмена простую команду:
Она позволяла получить в файле fail.txt все ошибки обмена. Но если было нужно что-то большее, вроде получения информации о предшествующей ошибке, то приходилось создавать монструозные скрипты с циклами for или использовать сторонние утилиты. По счастью, с появлением PowerShell эти проблемы ушли в прошлое.
Основным инструментом для работы с текстовыми журналами является командлет Get-Content, предназначенный для отображения содержимого текстового файла. Например, для вывода журнала сервиса WSUS в консоль можно использовать команду:
Для вывода последних строк журнала существует параметр Tail, который в паре с параметром Wait позволит смотреть за журналом в режиме онлайн. Посмотрим, как идет обновление системы командой:
Смотрим за ходом обновления Windows.
Если же нам нужно отловить в журналах определенные события, то поможет командлет Select-String, который позволяет отобразить только строки, подходящие под маску поиска. Посмотрим на последние блокировки Windows Firewall:
Смотрим, кто пытается пролезть на наш дедик.
При необходимости посмотреть в журнале строки перед и после нужной, можно использовать параметр Context. Например, для вывода трех строк после и трех строк перед ошибкой можно использовать команду:
Оба полезных командлета можно объединить. Например, для вывода строк с 45 по 75 из netlogon.log поможет команда:
Журналы системы ведутся в формате .evtx, и для работы с ними существуют отдельные командлеты. Для работы с классическими журналами («Приложение», «Система», и т.д.) используется Get-Eventlog. Этот командлет удобен, но не позволяет работать с остальными журналами приложений и служб. Для работы с любыми журналами, включая классические, существует более универсальный вариант ― Get-WinEvent. Остановимся на нем подробнее.
Для получения списка доступных системных журналов можно выполнить следующую команду:
Вывод доступных журналов и информации о них.
Для просмотра какого-то конкретного журнала нужно лишь добавить его имя. Для примера получим последние 20 записей из журнала System командой:
Последние записи в журнале System.
Для получения определенных событий удобнее всего использовать хэш-таблицы. Подробнее о работе с хэш-таблицами в PowerShell можно прочитать в материале Technet about_Hash_Tables.
Для примера получим все события из журнала System с кодом события 1 и 6013.
В случае если надо получить события определенного типа ― предупреждения или ошибки, ― нужно использовать фильтр по важности (Level). Возможны следующие значения:
- 0 ― всегда записывать;
- 1 ― критический;
- 2 ― ошибка;
- 3 ― предупреждение;
- 4 ― информация;
- 5 ― подробный (Verbose).
Собрать хэш-таблицу с несколькими значениями важности одной командой так просто не получится. Если мы хотим получить ошибки и предупреждения из системного журнала, можно воспользоваться дополнительной фильтрацией при помощи Where-Object:
Ошибки и предупреждения журнала System.
Аналогичным образом можно собирать таблицу, фильтруя непосредственно по тексту события и по времени.
Подробнее почитать про работу обоих командлетов для работы с системными журналами можно в документации PowerShell:
PowerShell ― механизм удобный и гибкий, но требует знания синтаксиса и для сложных условий и обработки большого количества файлов потребует написания полноценных скриптов. Но есть вариант обойтись всего-лишь SQL-запросами при помощи замечательного Log Parser.
Работаем с журналами посредством запросов SQL
Утилита Log Parser появилась на свет в начале «нулевых» и с тех пор успела обзавестись официальной графической оболочкой. Тем не менее актуальности своей она не потеряла и до сих пор остается для меня одним из самых любимых инструментов для анализа логов. Загрузить утилиту можно в Центре Загрузок Microsoft, графический интерфейс к ней ― в галерее Technet. О графическом интерфейсе чуть позже, начнем с самой утилиты.
О возможностях Log Parser уже рассказывалось в материале «LogParser — привычный взгляд на непривычные вещи», поэтому я начну с конкретных примеров.
Для начала разберемся с текстовыми файлами ― например, получим список подключений по RDP, заблокированных нашим фаерволом. Для получения такой информации вполне подойдет следующий SQL-запрос:
Посмотрим на результат:
Смотрим журнал Windows Firewall.
Разумеется, с полученной таблицей можно делать все что угодно ― сортировать, группировать. Насколько хватит фантазии и знания SQL.
Log Parser также прекрасно работает с множеством других источников. Например, посмотрим откуда пользователи подключались к нашему серверу по RDP.
Работать будем с журналом TerminalServices-LocalSessionManager\Operational.
Не со всеми журналами Log Parser работает просто так ― к некоторым он не может получить доступ. В нашем случае просто скопируем журнал из %SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx в %temp%\test.evtx.
Данные будем получать таким запросом:
Смотрим, кто и когда подключался к нашему серверу терминалов.
Особенно удобно использовать Log Parser для работы с большим количеством файлов журналов ― например, в IIS или Exchange. Благодаря возможностям SQL можно получать самую разную аналитическую информацию, вплоть до статистики версий IOS и Android, которые подключаются к вашему серверу.
В качестве примера посмотрим статистику количества писем по дням таким запросом:
Если в системе установлены Office Web Components, загрузить которые можно в Центре загрузки Microsoft, то на выходе можно получить красивую диаграмму.
Выполняем запрос и открываем получившуюся картинку…
Любуемся результатом.
Следует отметить, что после установки Log Parser в системе регистрируется COM-компонент MSUtil.LogQuery. Он позволяет делать запросы к движку утилиты не только через вызов LogParser.exe, но и при помощи любого другого привычного языка. В качестве примера приведу простой скрипт PowerShell, который выведет 20 наиболее объемных файлов на диске С.
Ознакомиться с документацией о работе компонента можно в материале Log Parser COM API Overview на портале SystemManager.ru.
Благодаря этой возможности для облегчения работы существует несколько утилит, представляющих из себя графическую оболочку для Log Parser. Платные рассматривать не буду, а вот бесплатную Log Parser Studio покажу.
Интерфейс Log Parser Studio.
Основной особенностью здесь является библиотека, которая позволяет держать все запросы в одном месте, без россыпи по папкам. Также сходу представлено множество готовых примеров, которые помогут разобраться с запросами.
Вторая особенность ― возможность экспорта запроса в скрипт PowerShell.
В качестве примера посмотрим, как будет работать выборка ящиков, отправляющих больше всего писем:
Выборка наиболее активных ящиков.
При этом можно выбрать куда больше типов журналов. Например, в «чистом» Log Parser существуют ограничения по типам входных данных, и отдельного типа для Exchange нет ― нужно самостоятельно вводить описания полей и пропуск заголовков. В Log Parser Studio нужные форматы уже готовы к использованию.
Помимо Log Parser, с логами можно работать и при помощи возможностей MS Excel, которые упоминались в материале «Excel вместо PowerShell». Но максимального удобства можно достичь, подготавливая первичный материал при помощи Log Parser с последующей обработкой его через Power Query в Excel.
Приходилось ли вам использовать какие-либо инструменты для перелопачивания логов? Поделитесь в комментариях.