Пример #1
0
/**
 * virLogMessage:
 * @category: where is that message coming from
 * @priority: the priority level
 * @funcname: the function emitting the (debug) message
 * @linenr: line where the message was emitted
 * @flags: extra flags, 1 if coming from the error handler
 * @fmt: the string format
 * @...: the arguments
 *
 * Call the libvirt logger with some information. Based on the configuration
 * the message may be stored, sent to output or just discarded
 */
void virLogMessage(const char *category, int priority, const char *funcname,
                   long long linenr, unsigned int flags, const char *fmt, ...)
{
    static bool logVersionStderr = true;
    char *str = NULL;
    char *msg = NULL;
    char timestamp[VIR_TIME_STRING_BUFLEN];
    int fprio, i, ret;
    int saved_errno = errno;
    int emit = 1;
    va_list ap;

    if (!virLogInitialized)
        virLogStartup();

    if (fmt == NULL)
        goto cleanup;

    /*
     * check against list of specific logging patterns
     */
    fprio = virLogFiltersCheck(category);
    if (fprio == 0) {
        if (priority < virLogDefaultPriority)
            emit = 0;
    } else if (priority < fprio) {
        emit = 0;
    }

    if ((emit == 0) && ((virLogBuffer == NULL) || (virLogSize <= 0)))
        goto cleanup;

    /*
     * serialize the error message, add level and timestamp
     */
    va_start(ap, fmt);
    if (virVasprintf(&str, fmt, ap) < 0) {
        va_end(ap);
        goto cleanup;
    }
    va_end(ap);

    ret = virLogFormatString(&msg, funcname, linenr, priority, str);
    VIR_FREE(str);
    if (ret < 0)
        goto cleanup;

    if (virTimeStringNowRaw(timestamp) < 0)
        timestamp[0] = '\0';

    /*
     * Log based on defaults, first store in the history buffer,
     * then if emit push the message on the outputs defined, if none
     * use stderr.
     * NOTE: the locking is a single point of contention for multiple
     *       threads, but avoid intermixing. Maybe set up locks per output
     *       to improve paralellism.
     */
    virLogLock();
    virLogStr(timestamp);
    virLogStr(msg);
    virLogUnlock();
    if (emit == 0)
        goto cleanup;

    virLogLock();
    for (i = 0; i < virLogNbOutputs; i++) {
        if (priority >= virLogOutputs[i].priority) {
            if (virLogOutputs[i].logVersion) {
                char *ver = NULL;
                if (virLogVersionString(&ver) >= 0)
                    virLogOutputs[i].f(category, VIR_LOG_INFO,
                                       __func__, __LINE__,
                                       timestamp, ver,
                                       virLogOutputs[i].data);
                VIR_FREE(ver);
                virLogOutputs[i].logVersion = false;
            }
            virLogOutputs[i].f(category, priority, funcname, linenr,
                               timestamp, msg, virLogOutputs[i].data);
        }
    }
    if ((virLogNbOutputs == 0) && (flags != 1)) {
        if (logVersionStderr) {
            char *ver = NULL;
            if (virLogVersionString(&ver) >= 0)
                virLogOutputToFd(category, VIR_LOG_INFO,
                                 __func__, __LINE__,
                                 timestamp, ver,
                                 (void *) STDERR_FILENO);
            VIR_FREE(ver);
            logVersionStderr = false;
        }
        virLogOutputToFd(category, priority, funcname, linenr,
                         timestamp, msg, (void *) STDERR_FILENO);
    }
    virLogUnlock();

cleanup:
    VIR_FREE(msg);
    errno = saved_errno;
}
Пример #2
0
/**
 * virLogMessage:
 * @category: where is that message coming from
 * @priority: the priority level
 * @funcname: the function emitting the (debug) message
 * @linenr: line where the message was emitted
 * @flags: extra flags, 1 if coming from the error handler
 * @fmt: the string format
 * @...: the arguments
 *
 * Call the libvirt logger with some informations. Based on the configuration
 * the message may be stored, sent to output or just discarded
 */
void virLogMessage(const char *category, int priority, const char *funcname,
                   long long linenr, int flags, const char *fmt, ...) {
    char *str = NULL;
    char *msg;
    struct timeval cur_time;
    struct tm time_info;
    int len, fprio, i, ret;

    if (!virLogInitialized)
        virLogStartup();

    if (fmt == NULL)
       return;

    /*
     * check against list of specific logging patterns
     */
    fprio = virLogFiltersCheck(category);
    if (fprio == 0) {
        if (priority < virLogDefaultPriority)
            return;
    } else if (priority < fprio)
        return;

    /*
     * serialize the error message, add level and timestamp
     */
    VIR_GET_VAR_STR(fmt, str);
    if (str == NULL)
        return;
    gettimeofday(&cur_time, NULL);
    localtime_r(&cur_time.tv_sec, &time_info);

    if ((funcname != NULL)) {
        ret = virAsprintf(&msg, "%02d:%02d:%02d.%03d: %s : %s:%lld : %s\n",
                          time_info.tm_hour, time_info.tm_min,
                          time_info.tm_sec, (int) cur_time.tv_usec / 1000,
                          virLogPriorityString(priority), funcname, linenr, str);
    } else {
        ret = virAsprintf(&msg, "%02d:%02d:%02d.%03d: %s : %s\n",
                          time_info.tm_hour, time_info.tm_min,
                          time_info.tm_sec, (int) cur_time.tv_usec / 1000,
                          virLogPriorityString(priority), str);
    }
    VIR_FREE(str);
    if (ret < 0) {
        /* apparently we're running out of memory */
        return;
    }

    /*
     * Log based on defaults, first store in the history buffer
     * then push the message on the outputs defined, if none
     * use stderr.
     * NOTE: the locking is a single point of contention for multiple
     *       threads, but avoid intermixing. Maybe set up locks per output
     *       to improve paralellism.
     */
    len = strlen(msg);
    virLogStr(msg, len);
    virLogLock();
    for (i = 0; i < virLogNbOutputs;i++) {
        if (priority >= virLogOutputs[i].priority)
            virLogOutputs[i].f(category, priority, funcname, linenr,
                               msg, len, virLogOutputs[i].data);
    }
    if ((virLogNbOutputs == 0) && (flags != 1))
        ignore_value (safewrite(STDERR_FILENO, msg, len));
    virLogUnlock();

    VIR_FREE(msg);
}
Пример #3
0
/**
 * virLogVMessage:
 * @source: where is that message coming from
 * @priority: the priority level
 * @filename: file where the message was emitted
 * @linenr: line where the message was emitted
 * @funcname: the function emitting the (debug) message
 * @metadata: NULL or metadata array, terminated by an item with NULL key
 * @fmt: the string format
 * @vargs: format args
 *
 * Call the libvirt logger with some information. Based on the configuration
 * the message may be stored, sent to output or just discarded
 */
void
virLogVMessage(virLogSource source,
               virLogPriority priority,
               const char *filename,
               int linenr,
               const char *funcname,
               virLogMetadataPtr metadata,
               const char *fmt,
               va_list vargs)
{
    static bool logVersionStderr = true;
    char *str = NULL;
    char *msg = NULL;
    char timestamp[VIR_TIME_STRING_BUFLEN];
    int fprio, ret;
    size_t i;
    int saved_errno = errno;
    bool emit = true;
    unsigned int filterflags = 0;

    if (virLogInitialize() < 0)
        return;

    if (fmt == NULL)
        goto cleanup;

    /*
     * check against list of specific logging patterns
     */
    fprio = virLogFiltersCheck(filename, &filterflags);
    if (fprio == 0) {
        if (priority < virLogDefaultPriority)
            emit = false;
    } else if (priority < fprio) {
        emit = false;
    }

    if (!emit && ((virLogBuffer == NULL) || (virLogSize <= 0)))
        goto cleanup;

    /*
     * serialize the error message, add level and timestamp
     */
    if (virVasprintfQuiet(&str, fmt, vargs) < 0) {
        goto cleanup;
    }

    ret = virLogFormatString(&msg, linenr, funcname, priority, str);
    if (ret < 0)
        goto cleanup;

    if (virTimeStringNowRaw(timestamp) < 0)
        timestamp[0] = '\0';

    /*
     * Log based on defaults, first store in the history buffer,
     * then if emit push the message on the outputs defined, if none
     * use stderr.
     * NOTE: the locking is a single point of contention for multiple
     *       threads, but avoid intermixing. Maybe set up locks per output
     *       to improve paralellism.
     */
    virLogLock();
    virLogStr(timestamp);
    virLogStr(": ");
    virLogStr(msg);
    virLogUnlock();
    if (!emit)
        goto cleanup;

    virLogLock();
    for (i = 0; i < virLogNbOutputs; i++) {
        if (priority >= virLogOutputs[i].priority) {
            if (virLogOutputs[i].logVersion) {
                const char *rawver;
                char *ver = NULL;
                if (virLogVersionString(&rawver, &ver) >= 0)
                    virLogOutputs[i].f(VIR_LOG_FROM_FILE, VIR_LOG_INFO,
                                       __FILE__, __LINE__, __func__,
                                       timestamp, NULL, 0, rawver, ver,
                                       virLogOutputs[i].data);
                VIR_FREE(ver);
                virLogOutputs[i].logVersion = false;
            }
            virLogOutputs[i].f(source, priority,
                               filename, linenr, funcname,
                               timestamp, metadata, filterflags,
                               str, msg, virLogOutputs[i].data);
        }
    }
    if ((virLogNbOutputs == 0) && (source != VIR_LOG_FROM_ERROR)) {
        if (logVersionStderr) {
            const char *rawver;
            char *ver = NULL;
            if (virLogVersionString(&rawver, &ver) >= 0)
                virLogOutputToFd(VIR_LOG_FROM_FILE, VIR_LOG_INFO,
                                 __FILE__, __LINE__, __func__,
                                 timestamp, NULL, 0, rawver, ver,
                                 (void *) STDERR_FILENO);
            VIR_FREE(ver);
            logVersionStderr = false;
        }
        virLogOutputToFd(source, priority,
                         filename, linenr, funcname,
                         timestamp, metadata, filterflags,
                         str, msg, (void *) STDERR_FILENO);
    }
    virLogUnlock();

cleanup:
    VIR_FREE(str);
    VIR_FREE(msg);
    errno = saved_errno;
}