#include "logging.h"
#include "memory.h"
#include "util.h"
+#include "buf.h"
#include "threads.h"
/*
virLogOutputFunc f;
virLogCloseFunc c;
int priority;
+ virLogDestination dest;
+ const char *name;
};
typedef struct _virLogOutput virLogOutput;
typedef virLogOutput *virLogOutputPtr;
virMutexUnlock(&virLogMutex);
}
+static const char *virLogOutputString(virLogDestination ldest) {
+ switch (ldest) {
+ case VIR_LOG_TO_STDERR:
+ return("stderr");
+ case VIR_LOG_TO_SYSLOG:
+ return("syslog");
+ case VIR_LOG_TO_FILE:
+ return("file");
+ }
+ return("unknown");
+}
static const char *virLogPriorityString(virLogPriority lvl) {
switch (lvl) {
for (i = 0;i < virLogNbOutputs;i++) {
if (virLogOutputs[i].c != NULL)
virLogOutputs[i].c(virLogOutputs[i].data);
+ VIR_FREE(virLogOutputs[i].name);
}
VIR_FREE(virLogOutputs);
i = virLogNbOutputs;
/**
* virLogDefineOutput:
* @f: the function to call to output a message
- * @f: the function to call to close the output (or NULL)
+ * @c: the function to call to close the output (or NULL)
* @data: extra data passed as first arg to the function
* @priority: minimal priority for this filter, use 0 for none
+ * @dest: where to send output of this priority
+ * @name: optional name data associated with an output
* @flags: extra flag, currently unused
*
* Defines an output function for log messages. Each message once
* Returns -1 in case of failure or the output number if successful
*/
int virLogDefineOutput(virLogOutputFunc f, virLogCloseFunc c, void *data,
- int priority, int flags ATTRIBUTE_UNUSED) {
+ int priority, int dest, const char *name,
+ int flags ATTRIBUTE_UNUSED) {
int ret = -1;
+ char *ndup = NULL;
if (f == NULL)
return(-1);
+ if (dest == VIR_LOG_TO_SYSLOG || dest == VIR_LOG_TO_FILE) {
+ if (name == NULL)
+ return(-1);
+ ndup = strdup(name);
+ if (ndup == NULL)
+ return(-1);
+ }
+
virLogLock();
if (VIR_REALLOC_N(virLogOutputs, virLogNbOutputs + 1)) {
goto cleanup;
virLogOutputs[ret].c = c;
virLogOutputs[ret].data = data;
virLogOutputs[ret].priority = priority;
+ virLogOutputs[ret].dest = dest;
+ virLogOutputs[ret].name = ndup;
cleanup:
virLogUnlock();
return(ret);
}
static int virLogAddOutputToStderr(int priority) {
- if (virLogDefineOutput(virLogOutputToFd, NULL, (void *)2L, priority, 0) < 0)
+ if (virLogDefineOutput(virLogOutputToFd, NULL, (void *)2L, priority,
+ VIR_LOG_TO_STDERR, NULL, 0) < 0)
return(-1);
return(0);
}
static int virLogAddOutputToFile(int priority, const char *file) {
int fd;
- fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
+ fd = open(file, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
if (fd < 0)
return(-1);
if (virLogDefineOutput(virLogOutputToFd, virLogCloseFd, (void *)(long)fd,
- priority, 0) < 0) {
+ priority, VIR_LOG_TO_FILE, file, 0) < 0) {
close(fd);
return(-1);
}
openlog(current_ident, 0, 0);
if (virLogDefineOutput(virLogOutputToSyslog, virLogCloseSyslog, NULL,
- priority, 0) < 0) {
+ priority, VIR_LOG_TO_SYSLOG, ident, 0) < 0) {
closelog();
VIR_FREE(current_ident);
return(-1);
int virLogParseOutputs(const char *outputs) {
const char *cur = outputs, *str;
char *name;
+ char *abspath;
int prio;
int ret = -1;
int count = 0;
name = strndup(str, cur - str);
if (name == NULL)
goto cleanup;
- if (virLogAddOutputToFile(prio, name) == 0)
+ if (virFileAbsPath(name, &abspath) < 0) {
+ VIR_FREE(name);
+ return -1; /* skip warning here because setting was fine */
+ }
+ if (virLogAddOutputToFile(prio, abspath) == 0)
count++;
VIR_FREE(name);
+ VIR_FREE(abspath);
} else {
goto cleanup;
}
return (virLogDefaultPriority);
}
+/**
+ * virLogGetFilters:
+ *
+ * Returns a string listing the current filters, in the format originally
+ * specified in the config file or environment. Caller must free the
+ * result.
+ */
+char *virLogGetFilters(void) {
+ int i;
+ virBuffer filterbuf = VIR_BUFFER_INITIALIZER;
+
+ virLogLock();
+ for (i = 0; i < virLogNbFilters; i++) {
+ virBufferVSprintf(&filterbuf, "%d:%s ", virLogFilters[i].priority,
+ virLogFilters[i].match);
+ }
+ virLogUnlock();
+
+ if (virBufferError(&filterbuf))
+ return NULL;
+
+ return virBufferContentAndReset(&filterbuf);
+}
+
+/**
+ * virLogGetOutputs:
+ *
+ * Returns a string listing the current outputs, in the format originally
+ * specified in the config file or environment. Caller must free the
+ * result.
+ */
+char *virLogGetOutputs(void) {
+ int i;
+ virBuffer outputbuf = VIR_BUFFER_INITIALIZER;
+
+ virLogLock();
+ for (i = 0; i < virLogNbOutputs; i++) {
+ int dest = virLogOutputs[i].dest;
+ if (i)
+ virBufferVSprintf(&outputbuf, " ");
+ switch (dest) {
+ case VIR_LOG_TO_SYSLOG:
+ case VIR_LOG_TO_FILE:
+ virBufferVSprintf(&outputbuf, "%d:%s:%s",
+ virLogOutputs[i].priority,
+ virLogOutputString(dest),
+ virLogOutputs[i].name);
+ break;
+ default:
+ virBufferVSprintf(&outputbuf, "%d:%s",
+ virLogOutputs[i].priority,
+ virLogOutputString(dest));
+ }
+ }
+ virLogUnlock();
+
+ if (virBufferError(&outputbuf))
+ return NULL;
+
+ return virBufferContentAndReset(&outputbuf);
+}
+
/**
* virLogGetNbFilters:
*
#define __VIRTLOG_H_
#include "internal.h"
+#include "buf.h"
/*
* If configured with --enable-debug=yes then library calls
#define VIR_LOG_DEFAULT VIR_LOG_WARN
+typedef enum {
+ VIR_LOG_TO_STDERR = 1,
+ VIR_LOG_TO_SYSLOG,
+ VIR_LOG_TO_FILE,
+} virLogDestination;
+
/**
* virLogOutputFunc:
* @category: the category for the message
extern int virLogGetNbFilters(void);
extern int virLogGetNbOutputs(void);
+extern char *virLogGetFilters(void);
+extern char *virLogGetOutputs(void);
extern int virLogGetDefaultPriority(void);
extern int virLogSetDefaultPriority(int priority);
extern void virLogSetFromEnv(void);
extern int virLogDefineFilter(const char *match, int priority, int flags);
-extern int virLogDefineOutput(virLogOutputFunc f, virLogCloseFunc c,
- void *data, int priority, int flags);
+extern int virLogDefineOutput(virLogOutputFunc f, virLogCloseFunc c, void *data,
+ int priority, int dest, const char *name,
+ int flags);
/*
* Internal logging API