summaryrefslogtreecommitdiffstats
path: root/src/common/win32/syslog.cc
blob: 7a1a90c9b1104d42463b5226a21efb1f56036315 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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);
}