rktio: add syslog

This commit is contained in:
Matthew Flatt 2017-06-21 06:02:20 -06:00
parent 4de2ff4cbd
commit db7c242983
9 changed files with 192 additions and 90 deletions

View File

@ -34,10 +34,6 @@
#else
# include <errno.h>
#endif
#ifdef USE_C_SYSLOG
# include <syslog.h>
# include <stdarg.h>
#endif
#define mzVA_ARG(x, y) HIDE_FROM_XFORM(va_arg(x, y))
#define TMP_CMARK_VALUE scheme_parameterization_key
@ -3820,16 +3816,6 @@ Scheme_Object *extract_all_levels(Scheme_Logger *logger)
return result;
}
#ifdef USE_WINDOWS_EVENT_LOG
static int event_procs_ready;
typedef HANDLE (WINAPI *mzRegisterEventSourceProc)(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName);
typedef BOOL (WINAPI *mzReportEventProc)(HANDLE hEventLog, WORD wType, WORD wCategory, DWORD dwEventID,
PSID lpUserSid, WORD wNumStrings, DWORD dwDataSize, LPCTSTR* lpStrings,
LPVOID lpRawData);
static mzRegisterEventSourceProc mzRegisterEventSource;
static mzReportEventProc mzReportEvent;
#endif
static Scheme_Object *make_log_message(int level, Scheme_Object *name, int prefix_msg,
char *buffer, intptr_t len, Scheme_Object *data) {
Scheme_Object *msg;
@ -3892,97 +3878,32 @@ void scheme_log_name_pfx_message(Scheme_Logger *logger, int level, Scheme_Object
while (logger) {
if (extract_spec_level(logger->syslog_level, name) >= level) {
#ifdef USE_C_SYSLOG
int pri;
Scheme_Object *cmd;
switch (level) {
case SCHEME_LOG_FATAL:
pri = LOG_CRIT;
pri = RKTIO_LOG_FATAL;
break;
case SCHEME_LOG_ERROR:
pri = LOG_ERR;
pri = RKTIO_LOG_ERROR;
break;
case SCHEME_LOG_WARNING:
pri = LOG_WARNING;
pri = RKTIO_LOG_WARNING;
break;
case SCHEME_LOG_INFO:
pri = LOG_INFO;
pri = RKTIO_LOG_INFO;
break;
case SCHEME_LOG_DEBUG:
default:
pri = LOG_DEBUG;
pri = RKTIO_LOG_DEBUG;
break;
}
if (name)
syslog(pri, "%s: %s", SCHEME_SYM_VAL(name), buffer);
else
syslog(pri, "%s", buffer);
#endif
#ifdef USE_WINDOWS_EVENT_LOG
if (!event_procs_ready) {
HMODULE hm;
hm = LoadLibrary("advapi32.dll");
if (hm) {
mzRegisterEventSource = (mzRegisterEventSourceProc)GetProcAddress(hm, "RegisterEventSourceA");
mzReportEvent = (mzReportEventProc)GetProcAddress(hm, "ReportEventA");
}
event_procs_ready = 1;
}
if (mzRegisterEventSource) {
static HANDLE hEventLog;
WORD ty;
unsigned long sev;
LPCTSTR a[1];
if (!hEventLog) {
Scheme_Object *cmd;
cmd = scheme_get_run_cmd();
hEventLog = mzRegisterEventSource(NULL, SCHEME_PATH_VAL(cmd));
}
switch (level) {
case SCHEME_LOG_FATAL:
ty = EVENTLOG_ERROR_TYPE;
sev = 3;
break;
case SCHEME_LOG_ERROR:
ty = EVENTLOG_ERROR_TYPE;
sev = 3;
break;
case SCHEME_LOG_WARNING:
ty = EVENTLOG_WARNING_TYPE;
sev = 2;
break;
case SCHEME_LOG_INFO:
ty = EVENTLOG_INFORMATION_TYPE;
sev = 1;
break;
case SCHEME_LOG_DEBUG:
default:
ty = EVENTLOG_AUDIT_SUCCESS;
sev = 0;
break;
}
if (name) {
char *naya;
intptr_t slen;
slen = SCHEME_SYM_LEN(name);
naya = (char *)scheme_malloc_atomic(slen + 2 + len + 1);
memcpy(naya, SCHEME_SYM_VAL(name), slen);
memcpy(naya + slen, ": ", 2);
memcpy(naya + slen + 2, buffer, len);
naya[slen + 2 + len] = 0;
buffer = naya;
len += slen + 2;
}
a[0] = buffer;
mzReportEvent(hEventLog, ty, 1 /* category */,
(sev << 30) | 2 /* message */,
NULL,
1, 0,
a, NULL);
}
#endif
cmd = scheme_get_run_cmd();
rktio_syslog(scheme_rktio, pri,
(name ? SCHEME_SYM_VAL(name) : NULL),
buffer, SCHEME_PATH_VAL(cmd));
}
if (extract_spec_level(logger->stderr_level, name) >= level) {
if (name) {
intptr_t slen;

View File

@ -27,6 +27,7 @@ OBJS = rktio_fs.@LTO@ \
rktio_flock.@LTO@ \
rktio_shellex.@LTO@ \
rktio_time.@LTO@ \
rktio_syslog.@LTO@ \
rktio_error.@LTO@ \
rktio_hash.@LTO@ \
rktio_wide.@LTO@ \
@ -81,6 +82,9 @@ rktio_shellex.@LTO@: $(srcdir)/rktio_shellex.c $(RKTIO_HEADERS)
rktio_time.@LTO@: $(srcdir)/rktio_time.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_time.@LTO@ -c $(srcdir)/rktio_time.c
rktio_syslog.@LTO@: $(srcdir)/rktio_syslog.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_syslog.@LTO@ -c $(srcdir)/rktio_syslog.c
rktio_error.@LTO@: $(srcdir)/rktio_error.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_error.@LTO@ -c $(srcdir)/rktio_error.c

View File

@ -885,6 +885,25 @@ char *rktio_wide_path_to_path(rktio_t *rktio, const void *wp);
is actually a `wchar_t*`. The `rktio_path_to_wide_path`
function can fail and report `RKTIO_ERROR_INVALID_PATH`. */
/*************************************************/
/* Logging */
rktio_ok_t rktio_syslog(rktio_t *rktio, int level, const char *name, const char *msg,
const char *exec_name);
/* Adds a message to the system log. The `name` argument can be NULL,
and it is added to the front of the message with a separating ": "
if non_NULL. The `exec_name` is the current executable name; it's
currently, used only on Windows, and the value may matter only the
first time that `rktio_syslog` is called. */
/* `level` values: */
enum {
RKTIO_LOG_FATAL = 1,
RKTIO_LOG_ERROR,
RKTIO_LOG_WARNING,
RKTIO_LOG_INFO,
RKTIO_LOG_DEBUG
};
/*************************************************/
/* Errors */

View File

@ -31,11 +31,14 @@ rktio_t *rktio_init(void)
rktio_init_time(rktio);
rktio_init_wide(rktio);
rktio_syslog_init(rktio);
return rktio;
}
void rktio_destroy(rktio_t *rktio)
{
rktio_syslog_clean(rktio);
rktio_error_clean(rktio);
rktio_process_deinit(rktio);
rktio_free_ghbn(rktio);

View File

@ -91,6 +91,10 @@ struct rktio_t {
wchar_t *wide_buffer;
#endif
#ifdef RKTIO_SYSTEM_WINDOWS
HANDLE hEventLog;
#endif
#ifdef RKTIO_USE_FCNTL_AND_FORK_FOR_FILE_LOCKS
struct rktio_hash_t *locked_fd_process_map;
#endif
@ -311,6 +315,9 @@ int rktio_make_os_pipe(rktio_t *rktio, intptr_t *a, int flags);
char **rktio_get_environ_array(void);
#endif
void rktio_syslog_init(rktio_t* rktio);
void rktio_syslog_clean(rktio_t* rktio);
#ifdef USE_TRANSITIONAL_64_FILE_OPS
# define BIG_OFF_T_IZE(n) n ## 64
#else

View File

@ -0,0 +1,142 @@
#include "rktio.h"
#include "rktio_private.h"
#ifdef RKTIO_SYSTEM_UNIX
# include <syslog.h>
#endif
#ifdef RKTIO_SYSTEM_WINDOWS
# include <stdlib.h>
# include <string.h>
static int event_procs_ready;
typedef HANDLE (WINAPI *do_RegisterEventSourceProc)(wchar_t *lpUNCServerName, wchar_t *lpSourceName);
typedef BOOL (WINAPI *do_ReportEventProc)(HANDLE hEventLog, WORD wType, WORD wCategory, DWORD dwEventID,
PSID lpUserSid, WORD wNumStrings, DWORD dwDataSize, const wchar_t** lpStrings,
LPVOID lpRawData);
static do_RegisterEventSourceProc do_RegisterEventSource;
static do_ReportEventProc do_ReportEvent;
#endif
void rktio_syslog_init(rktio_t *rktio)
{
#ifdef RKTIO_SYSTEM_WINDOWS
if (!event_procs_ready) {
HMODULE hm;
hm = LoadLibraryW(L"advapi32.dll");
if (hm) {
do_RegisterEventSource = (do_RegisterEventSourceProc)GetProcAddress(hm, "RegisterEventSourceW");
do_ReportEvent = (do_ReportEventProc)GetProcAddress(hm, "ReportEventW");
}
event_procs_ready = 1;
}
rktio->hEventLog = INVALID_HANDLE_VALUE;
#endif
}
void rktio_syslog_clean(rktio_t *rktio)
{
#ifdef RKTIO_SYSTEM_WINDOWS
if (rktio->hEventLog != INVALID_HANDLE_VALUE)
CloseHandle(rktio->hEventLog);
#endif
}
rktio_ok_t rktio_syslog(rktio_t *rktio, int level, const char *name, const char *msg, const char *exec_name)
{
#ifdef RKTIO_SYSTEM_UNIX
int pri;
switch (level) {
case RKTIO_LOG_FATAL:
pri = LOG_CRIT;
break;
case RKTIO_LOG_ERROR:
pri = LOG_ERR;
break;
case RKTIO_LOG_WARNING:
pri = LOG_WARNING;
break;
case RKTIO_LOG_INFO:
pri = LOG_INFO;
break;
case RKTIO_LOG_DEBUG:
default:
pri = LOG_DEBUG;
break;
}
if (name)
syslog(pri, "%s: %s", name, msg);
else
syslog(pri, "%s", msg);
return 1;
#endif
#ifdef RKTIO_SYSTEM_WINDOWS
if (do_RegisterEventSource) {
WORD ty;
unsigned long sev;
const wchar_t *a[1];
char *naya = NULL;
int ok;
if (rktio->hEventLog == INVALID_HANDLE_VALUE) {
rktio->hEventLog = do_RegisterEventSource(NULL, WIDE_PATH_temp(exec_name));
if (rktio->hEventLog == INVALID_HANDLE_VALUE) {
get_windows_error();
return 0;
}
}
switch (level) {
case RKTIO_LOG_FATAL:
ty = EVENTLOG_ERROR_TYPE;
sev = 3;
break;
case RKTIO_LOG_ERROR:
ty = EVENTLOG_ERROR_TYPE;
sev = 3;
break;
case RKTIO_LOG_WARNING:
ty = EVENTLOG_WARNING_TYPE;
sev = 2;
break;
case RKTIO_LOG_INFO:
ty = EVENTLOG_INFORMATION_TYPE;
sev = 1;
break;
case RKTIO_LOG_DEBUG:
default:
ty = EVENTLOG_AUDIT_SUCCESS;
sev = 0;
break;
}
if (name) {
intptr_t len, slen;
slen = strlen(name);
len = strlen(msg);
naya = malloc(slen + 2 + len + 1);
memcpy(naya, name, slen);
memcpy(naya + slen, ": ", 2);
memcpy(naya + slen + 2, msg, len);
naya[slen + 2 + len] = 0;
msg = naya;
}
a[0] = WIDE_PATH_temp(msg);
ok = do_ReportEvent(rktio->hEventLog, ty, 1 /* category */,
(sev << 30) | 2 /* message */,
NULL,
1, 0,
a, NULL);
if (!ok)
get_windows_error();
if (naya)
free(naya);
return ok;
} else {
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
return 0;
}
#endif
}

View File

@ -1,5 +1,6 @@
#include "rktio.h"
#include "rktio_private.h"
#include <string.h>
/* For converting byte strings to and from "wide" strings on Windows. */

View File

@ -162,6 +162,10 @@
RelativePath="..\..\rktio\rktio_time.c"
>
</File>
<File
RelativePath="..\..\rktio\rktio_syslog.c"
>
</File>
<File
RelativePath="..\..\rktio\rktio_error.c"
>

View File

@ -129,6 +129,7 @@
<ClCompile Include="..\..\rktio\rktio_flock.c" />
<ClCompile Include="..\..\rktio\rktio_shellex.c" />
<ClCompile Include="..\..\rktio\rktio_time.c" />
<ClCompile Include="..\..\rktio\rktio_syslog.c" />
<ClCompile Include="..\..\rktio\rktio_error.c" />
<ClCompile Include="..\..\rktio\rktio_hash.c" />
<ClCompile Include="..\..\rktio\rktio_wide.c" />