]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: Add Windows ETW support 38318/head
authorAlin Gabriel Serdean <aserdean@cloudbasesolutions.com>
Mon, 16 Nov 2020 22:36:36 +0000 (00:36 +0200)
committerAlin Gabriel Serdean <aserdean@ovn.org>
Tue, 9 Feb 2021 08:46:24 +0000 (10:46 +0200)
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>
src/common/CMakeLists.txt
src/common/win32/event_logging.mc [new file with mode: 0644]
src/common/win32/syslog.cc [new file with mode: 0644]
src/include/win32/syslog.h

index e9a732ba9161f8639f5f04dee4be02412a84f261..6f29dfef35080614a59d20ff6c2afc237d065cf0 100644 (file)
@@ -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
diff --git a/src/common/win32/event_logging.mc b/src/common/win32/event_logging.mc
new file mode 100644 (file)
index 0000000..3d08889
--- /dev/null
@@ -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
+.
+
diff --git a/src/common/win32/syslog.cc b/src/common/win32/syslog.cc
new file mode 100644 (file)
index 0000000..7a1a90c
--- /dev/null
@@ -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);
+}
index d59cd3d0c7cb7ed34d75e56a73b1888388323824..28389e0b999cd505e3e67f211d35b96450ce62a8 100644 (file)
@@ -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 */
 #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 */