I am trying to Write EventData(C Struct like) to Application Eventlog using "EventWrite". I don't see any Log written to EventLog(Application) I am using the below sprovider.mc file
MessageIdTypedef=DWORD
SeverityNames=(
Success=0x0:STATUS_SEVERITY_SUCCESS
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
Warning=0x2:STATUS_SEVERITY_WARNING
Error=0x3:STATUS_SEVERITY_ERROR
)
FacilityNames=(
System=0x0:FACILITY_SYSTEM
Runtime=0x2:FACILITY_RUNTIME
)
MessageId=0x0002
Severity=Error
Facility=Runtime
SymbolicName=MSG_RUNTIME_ERROR
Language=English
This is a runtime error message
.
Generating resource DLL
mc -U sprovider.mc
rc sprovider.rc
link -dll -noentry -out:sprovider.dll sprovider.res /MACHINE:X64
And my Manifest file is as below
<instrumentationManifest
xmlns="http://schemas.microsoft.com/win/2004/08/events"
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<instrumentation>
<events>
<provider name="evtlog" guid="{78A1B3DE-42A7-4111-85B2-8D199812EDDF}" symbol="MSG_RUNTIME_ERROR"
resourceFileName="c:\\windows\\system32\\evtlog.dll"
messageFileName="c:\\windows\\system32\\evtlog.dll">
<events>
<event symbol="MSG_RUNTIME_ERROR" value="2" version="0" level="win:Error" template="MyEventTemplate"/>
</events>
<templates>
<template tid="MyEventTemplate">
<data name="Message" inType="win:UnicodeString"/>
<data name="UserName" inType="win:UnicodeString"/>
</template>
</templates>
</provider>
</events>
</instrumentation>
</instrumentationManifest>
I run wevtutil im evnt.man Warning: The resource file for publisher sprovider does not contain the metadata resource. Make sure to link the .bin file generated by the Message Compiler into the specified binary.
resourceFileName: c:\windows\system32\sprovider.dll
I am using Win32 code as below to write events
#include <Windows.h>
#include <wchar.h>
#include <evntprov.h>
#include <iostream>
#include "evtlog.h"
using namespace std;
// Define the provider GUID
static const GUID MyProviderGuid =
{ 0x78a1b3de, 0x42a7, 0x4111, { 0x85, 0xb2, 0x8d, 0x19, 0x98, 0x12, 0xed, 0xdf } };
int wmain() {
// Register the event provider
REGHANDLE hProvider = NULL;
if (EventRegister(&MyProviderGuid, NULL, NULL, &hProvider) != ERROR_SUCCESS) {
// Handle the error
std::cout << GetLastError();
return 1;
}
// Sample structured data
struct MyEventData {
WCHAR Message[MAX_PATH];
WCHAR UserName[MAX_PATH];
};
MyEventData eventData = { L"Sree", L"This is a test message" };
// Event data descriptors
EVENT_DATA_DESCRIPTOR dataDescriptors[2];
EventDataDescCreate(&dataDescriptors[0], eventData.Message, (ULONG)(MAX_PATH));
EventDataDescCreate(&dataDescriptors[1], eventData.UserName, (ULONG)(MAX_PATH));
// Define the event descriptor
EVENT_DESCRIPTOR eventDescriptor;
EventDescCreate(&eventDescriptor, MSG_RUNTIME_ERROR, 0, FACILITY_RUNTIME, STATUS_SEVERITY_ERROR, 0, 0, 0);
BOOL bEnabled = EventEnabled(hProvider, &eventDescriptor);
std::cout << std::endl << "Enabled:" << bEnabled;
// Write the event
if (EventWrite(hProvider, &eventDescriptor, 2, dataDescriptors) != ERROR_SUCCESS) {
// Handle the error
std::cout << GetLastError();
return 1;
}
// Unregister the event provider
EventUnregister(hProvider);
return 0;
}
The executable generated from about C code cannot write anything to Log. Please let me know what I am missing here.
According to EventWrite,
If no trace sessions are recording this event, this function will do nothing and return ERROR_SUCCESS.
So, I started a trace session with the Example that Creates a Session and Enables a Manifest-based or Classic Provider. Everything works fine.
Also see Implementing ETW instrumentation and https://github.com/jebidiah-anthony/Windows-Event-Forwarder/blob/master/Creating%20Custom%20Logs.md for more information.
Update: As Defining Channels says,
Events can be written to event log channels, event tracing log files, or both. A channel is basically a sink that collects events. If the target audience for your events uses event consumers such as the Windows Event Viewer, you must define new channels to collect your events or import an existing channel that another provider defined.