<commit_before>/**
 * @file   logger.c
 * @author <NAME>
 * @date   02 Mar 2016
 * @brief  Logger implementation.
 */

#include "logger.h"
#include "manip_date.h"
#include "manip_string.h"
#include "rwlock_instance.h"

#include <stdarg.h>
#include <stdio.h>

static enum logger_level       static_level = LOGGER_LEVEL_ALL;
static struct rwlock_instance  lock;
static struct output_if_ops   *output_if = NULL;

/**
 * @see See header file for interface comments.
 */
bool logger_create(void)
{
    return rwlock_instance_create(&lock);
}

/**
 * @see See header file for interface comments.
 */
bool logger_destroy(void)
{
    return rwlock_instance_destroy(&lock);
}

/**
 * @see See header file for interface comments.
 */
bool logger_set_output(struct output_if_ops * const instance)
{
    bool retval = false;

    if (instance != NULL)
    {
        output_if = instance;
        retval = true;
    }

    return retval;
}

/**
 * @see See header file for interface comments.
 */
bool logger_set_level(const enum logger_level level)
{
    bool retval = false;

    if ((level >= LOGGER_LEVEL_MIN) && (level <= LOGGER_LEVEL_MAX))
    {
        rwlock_instance_wrlock(&lock);
        static_level = level;
        rwlock_instance_unlock(&lock);
        retval = true;
    }

    return retval;
}

/**
 * @brief Get a character string representation of an enumerated log level.
 *
 * @param[in] level The enumerated log level.
 *
 * @return A character string representation of an enumerated log level (NULL on
 *         error).
 */
static char *logger_get_level_string(const enum logger_level level)
{
    char *retval = NULL;

    switch (level)
    {
        case LOGGER_LEVEL_OFF:
            retval = "OFF";
            break;
        case LOGGER_LEVEL_ALL:
            retval = "ALL";
            break;
        case LOGGER_LEVEL_TRACE:
            retval = "TRACE";
            break;
        case LOGGER_LEVEL_DEBUG:
            retval = "DEBUG";
            break;
        case LOGGER_LEVEL_INFO:
            retval = "INFO";
            break;
        case LOGGER_LEVEL_WARN:
            retval = "WARN";
            break;
        case LOGGER_LEVEL_ERROR:
            retval = "ERROR";
            break;
        default:
            retval = NULL;
    }

    return retval;
}

/**
 * @see See header file for interface comments.
 */
void logger_printf(const enum logger_level level, const char *format, ...)
{
    int32_t error = 0;
    char msgbuf[128], outbuf[256], timebuf[32];
    va_list args;
    uint64_t sec = 0, nsec = 0;
    rwlock_instance_rdlock(&lock);
    enum logger_level setlevel = static_level;
    rwlock_instance_unlock(&lock);

    if ((output_if != NULL) && (setlevel != LOGGER_LEVEL_OFF) &&
        ((level >= setlevel) || (setlevel == LOGGER_LEVEL_ALL)))
    {
        va_start(args, format);
        error = vsnprintf(msgbuf, sizeof(msgbuf), format, args);
        va_end(args);

        if (error >= 0)
        {
            manip_date_time(DATE_CLOCK_REALTIME, &sec, &nsec);
            manip_date_time_format(sec,
                                   UNIT_TIME_SEC,
                                   "%Y-%m-%dT%H:%M:%S",
                                   timebuf,
                                   sizeof(timebuf));

            manip_string_concat(outbuf,
                                sizeof(outbuf),
                                "%s.%06u [%-5s]: %s",
                                timebuf,
                                (uint32_t)nsec / 1000,
                                logger_get_level_string(level),
                                msgbuf);

            output_if->oio_send(outbuf, sizeof(outbuf));
        }<commit_msg>logger: updated utility function names<commit_after>/**
 * @file   logger.c
 * @author <NAME>
 * @date   02 Mar 2016
 * @brief  Logger implementation.
 */

#include "logger.h"
#include "util_date.h"
#include "util_string.h"
#include "rwlock_instance.h"

#include <stdarg.h>
#include <stdio.h>

static enum logger_level       static_level = LOGGER_LEVEL_ALL;
static struct rwlock_instance  lock;
static struct output_if_ops   *output_if = NULL;

/**
 * @see See header file for interface comments.
 */
bool logger_create(void)
{
    return rwlock_instance_create(&lock);
}

/**
 * @see See header file for interface comments.
 */
bool logger_destroy(void)
{
    return rwlock_instance_destroy(&lock);
}

/**
 * @see See header file for interface comments.
 */
bool logger_set_output(struct output_if_ops * const instance)
{
    bool retval = false;

    if (instance != NULL)
    {
        output_if = instance;
        retval = true;
    }

    return retval;
}

/**
 * @see See header file for interface comments.
 */
bool logger_set_level(const enum logger_level level)
{
    bool retval = false;

    if ((level >= LOGGER_LEVEL_MIN) && (level <= LOGGER_LEVEL_MAX))
    {
        rwlock_instance_wrlock(&lock);
        static_level = level;
        rwlock_instance_unlock(&lock);
        retval = true;
    }

    return retval;
}

/**
 * @brief Get a character string representation of an enumerated log level.
 *
 * @param[in] level The enumerated log level.
 *
 * @return A character string representation of an enumerated log level (NULL on
 *         error).
 */
static char *logger_get_level_string(const enum logger_level level)
{
    char *retval = NULL;

    switch (level)
    {
        case LOGGER_LEVEL_OFF:
            retval = "OFF";
            break;
        case LOGGER_LEVEL_ALL:
            retval = "ALL";
            break;
        case LOGGER_LEVEL_TRACE:
            retval = "TRACE";
            break;
        case LOGGER_LEVEL_DEBUG:
            retval = "DEBUG";
            break;
        case LOGGER_LEVEL_INFO:
            retval = "INFO";
            break;
        case LOGGER_LEVEL_WARN:
            retval = "WARN";
            break;
        case LOGGER_LEVEL_ERROR:
            retval = "ERROR";
            break;
        default:
            retval = NULL;
    }

    return retval;
}

/**
 * @see See header file for interface comments.
 */
void logger_printf(const enum logger_level level, const char *format, ...)
{
    int32_t error = 0;
    char msgbuf[128], outbuf[256], timebuf[32];
    va_list args;
    uint64_t sec = 0, nsec = 0;
    rwlock_instance_rdlock(&lock);
    enum logger_level setlevel = static_level;
    rwlock_instance_unlock(&lock);

    if ((output_if != NULL) && (setlevel != LOGGER_LEVEL_OFF) &&
        ((level >= setlevel) || (setlevel == LOGGER_LEVEL_ALL)))
    {
        va_start(args, format);
        error = vsnprintf(msgbuf, sizeof(msgbuf), format, args);
        va_end(args);

        if (error >= 0)
        {
            util_date_time(DATE_CLOCK_REALTIME, &sec, &nsec);
            util_date_time_format(sec,
                                  UNIT_TIME_SEC,
                                  "%Y-%m-%dT%H:%M:%S",
                                  timebuf,
                                  sizeof(timebuf));

            util_string_concat(outbuf,
                               sizeof(outbuf),
                               "%s.%06u [%-5s]: %s",
                               timebuf,
                               (uint32_t)nsec / 1000,
                               logger_get_level_string(level),
                               msgbuf);

            output_if->oio_send(outbuf, sizeof(outbuf));
        }
{'fraction_non_alphanumeric': 0.10401410360726879, 'fraction_numerical': 0.008407919717927854, 'mean_word_length': 1.873003506038177, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1489863', 'n_tokens_mistral': 2256, 'n_tokens_neox': 2191, 'n_words': 540}