mirror of
https://github.com/ceph/ceph
synced 2025-02-20 17:37:29 +00:00
common: Add Windows ETW support
This patch adds generic ETW logging on top of syslog calls. The events are described in the message compiler file `event_logging.mc`. Using the cross platform utility `windmc`, we will generate the header file, `event_logging.h`, needed by the ETW implementation, and the resource file `event_logging.rc`. Over the generated resource file we will run another utility called `windres`. this tool is used to compile the binary objects needed by the OS utilities (i.e. `Event Viewer`) to view the logged events. On usage, a registry key needs to be added/removed on the target computer. The registry looks like the following: [HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\<get_process_name>] "EventMessageFile"="<Folder_location_to>\\event_logging.dll" I.E.: [HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\rbd-wnbd] "EventMessageFile"="C:\\Program Files\\Ceph\\bin\\event_logging.dll" Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Signed-off-by: Lucian Petrut <lpetrut@cloudbasesolutions.com> Co-authored-by: Lucian Petrut <lpetrut@cloudbasesolutions.com>
This commit is contained in:
parent
9ab1b5cb65
commit
8e7042f4ca
@ -104,13 +104,34 @@ set(common_srcs
|
||||
version.cc)
|
||||
|
||||
if(WIN32)
|
||||
if(MINGW)
|
||||
set(CMAKE_MC_COMPILER x86_64-w64-mingw32-windmc)
|
||||
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/src/common/event_logging.h
|
||||
COMMAND ${CMAKE_MC_COMPILER} -b -e h -h ${CMAKE_BINARY_DIR}/src/common/
|
||||
-r ${CMAKE_BINARY_DIR}/src/common ${CMAKE_SOURCE_DIR}/src/common/win32/event_logging.mc
|
||||
COMMAND ${CMAKE_RC_COMPILER} ${CMAKE_BINARY_DIR}/src/common/event_logging.rc
|
||||
-o ${CMAKE_BINARY_DIR}/src/common/event_logging.o
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -o ${CMAKE_BINARY_DIR}/bin/event_logging.dll -shared
|
||||
${CMAKE_BINARY_DIR}/src/common/event_logging.o
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/common/win32/event_logging.mc)
|
||||
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/common/win32/syslog.cc
|
||||
APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_BINARY_DIR}/src/common/event_logging.h)
|
||||
|
||||
include_directories(SYSTEM "${CMAKE_BINARY_DIR}/src/common/")
|
||||
|
||||
list(APPEND common_srcs
|
||||
win32/blkdev.cc
|
||||
win32/dns_resolve.cc
|
||||
win32/ifaddrs.cc
|
||||
win32/registry.cc
|
||||
win32/service.cc
|
||||
win32/SubProcess.cc)
|
||||
win32/SubProcess.cc
|
||||
win32/syslog.cc)
|
||||
else()
|
||||
list(APPEND common_srcs
|
||||
blkdev.cc
|
||||
|
35
src/common/win32/event_logging.mc
Normal file
35
src/common/win32/event_logging.mc
Normal file
@ -0,0 +1,35 @@
|
||||
SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
|
||||
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
|
||||
Warning=0x2:STATUS_SEVERITY_WARNING
|
||||
Error=0x3:STATUS_SEVERITY_ERROR
|
||||
)
|
||||
|
||||
|
||||
MessageId=0x0001
|
||||
Severity=Success
|
||||
SymbolicName=SUCCESS_EVENTMSG
|
||||
Language=English
|
||||
%1
|
||||
.
|
||||
|
||||
MessageId=0x0002
|
||||
Severity=Informational
|
||||
SymbolicName=INFO_EVENTMSG
|
||||
Language=English
|
||||
%1
|
||||
.
|
||||
|
||||
MessageId=0x0003
|
||||
Severity=Warning
|
||||
SymbolicName=WARN_EVENTMSG
|
||||
Language=English
|
||||
%1
|
||||
.
|
||||
|
||||
MessageId=0x0004
|
||||
Severity=Error
|
||||
SymbolicName=ERROR_EVENTMSG
|
||||
Language=English
|
||||
%1
|
||||
.
|
||||
|
77
src/common/win32/syslog.cc
Normal file
77
src/common/win32/syslog.cc
Normal file
@ -0,0 +1,77 @@
|
||||
#include <windows.h>
|
||||
#include <syslog.h>
|
||||
#include "event_logging.h"
|
||||
#include "common/code_environment.h"
|
||||
|
||||
static HANDLE g_event_source = NULL;
|
||||
|
||||
bool get_event_source()
|
||||
{
|
||||
if (!g_event_source) {
|
||||
HANDLE temp = RegisterEventSourceA(NULL, get_process_name_cpp().c_str());
|
||||
if (!temp)
|
||||
return false;
|
||||
|
||||
if (InterlockedCompareExchangePointer(&g_event_source, temp, NULL)) {
|
||||
// There already was an event source, let's cleanup the one that we've
|
||||
// just created.
|
||||
DeregisterEventSource(temp);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_event_log_entry(int level, const char* msg)
|
||||
{
|
||||
if (!get_event_source()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WORD type;
|
||||
DWORD event_id;
|
||||
switch (level) {
|
||||
case LOG_DEBUG:
|
||||
event_id = SUCCESS_EVENTMSG;
|
||||
type = EVENTLOG_SUCCESS;
|
||||
break;
|
||||
|
||||
case LOG_INFO:
|
||||
case LOG_NOTICE:
|
||||
event_id = INFO_EVENTMSG;
|
||||
type = EVENTLOG_INFORMATION_TYPE;
|
||||
break;
|
||||
|
||||
case LOG_WARNING:
|
||||
event_id = WARN_EVENTMSG;
|
||||
type = EVENTLOG_WARNING_TYPE;
|
||||
break;
|
||||
|
||||
default:
|
||||
event_id = ERROR_EVENTMSG;
|
||||
type = EVENTLOG_ERROR_TYPE;
|
||||
}
|
||||
|
||||
ReportEventA(g_event_source, type,
|
||||
0, event_id, NULL, 1, 0, &msg, NULL);
|
||||
}
|
||||
|
||||
void syslog(int priority, const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
size_t length = (size_t)_vscprintf(format, args) + 1;
|
||||
|
||||
char* buffer = (char*) malloc(length);
|
||||
if (NULL == buffer) {
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
|
||||
vsnprintf_s(buffer, length, length - 1, format, args);
|
||||
va_end(args);
|
||||
|
||||
write_event_log_entry(LOG_PRI(priority), buffer);
|
||||
free(buffer);
|
||||
}
|
@ -25,7 +25,6 @@
|
||||
#define LOG_NOTICE 5 /* normal but significant condition */
|
||||
#define LOG_INFO 6 /* informational */
|
||||
#define LOG_DEBUG 7 /* debug-level messages */
|
||||
#define LOG_NDELAY 8 /* don't delay open */
|
||||
|
||||
#define LOG_KERN (0<<3) /* kernel messages */
|
||||
#define LOG_USER (1<<3) /* user-level messages */
|
||||
@ -49,14 +48,17 @@
|
||||
#define LOG_LOCAL6 (22<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL7 (23<<3) /* reserved for local use */
|
||||
|
||||
#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
|
||||
/* extract priority */
|
||||
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
|
||||
|
||||
|
||||
static inline void
|
||||
openlog(const char *ident, int option, int facility)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
syslog(int priority, const char *format, ...)
|
||||
{
|
||||
}
|
||||
void
|
||||
syslog(int priority, const char *format, ...);
|
||||
|
||||
#endif /* syslog.h */
|
||||
|
Loading…
Reference in New Issue
Block a user