Skip to content
Snippets Groups Projects
Select Git revision
  • 2628406750c34b7a6fc6ea4390af7ea03bf320f1
  • consistent_config default protected
2 results

scheduler.py

Blame
  • logging.c 8.73 KiB
    /*
     * SPDX-License-Identifier: GPL-3.0-or-later
     *
     * logging.c
     *
     * Copyright (C) 2011-2022, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer.
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or (at
     * your option) any later version.
     *
     * This program is distributed in the hope that it will be useful, but
     * WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     *
     */
    
    #include <stdbool.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    #include <stdarg.h>
    #include <stdlib.h>
    #include "logging.h"
    #include "memory/cats_memory.h"
    #include "cats_time/cats_time.h"
    #include "misc/misc.h"
    
    
    enum cats_log_level internal_current_log_level = LOG_INFO;
    int32_t logging_mpi_rank = -1;
    struct cats_time cats_logging_start_time;
    FILE *cats_log_file = NULL;
    char *cats_log_file_name = NULL;
    const char *logging_module_name = NULL;
    bool time_initialized = false;
    bool logging_quiet = false;
    
    
    const char *get_log_level_name(enum cats_log_level level)
    {
            switch (level) {
                    case LOG_DEBUG:
                            return " DBG";
                    case LOG_INFO:
                            return "INFO";
                    case LOG_RAW:
                    case LOG_EMPTY:
                            return "";
                    case LOG_MARK:
                            return "";
                    case LOG_IMPORTANT:
                            return "IMPT";
                    case LOG_WARNING:
                            return "WARN";
                    case LOG_ERROR:
                            return " ERR";
                    case LOG_MPI:
                            return " MPI";
                    case LOG_UNIMPLEMENTED:
                            return "NOT IMPLEMENTED";
                    case LOG_UNKNOWN:
                            return "UNKN";
            }
            return "UNKN";
    }
    
    
    const char *get_log_level_color(enum cats_log_level level)
    {
            switch (level) {
                    case LOG_RAW:
                    case LOG_DEBUG:
                            return C_RESET;
                    case LOG_INFO:
                            return C_RESET;
                    case LOG_EMPTY:
                            return C_RESET;
                    case LOG_MARK:
                            return C_RESET;
                    case LOG_IMPORTANT:
                            return C_YELLOW;
                    case LOG_WARNING:
                            return C_YELLOW;
                    case LOG_ERROR:
                            return C_RED;
                    case LOG_MPI:
                            return C_RED;
                    case LOG_UNIMPLEMENTED:
                            return C_RED;
                    case LOG_UNKNOWN:
                            return C_RED;
            }
    
            return C_RESET;
    }
    
    
    void set_log_level(enum cats_log_level new_level)
    {
            internal_current_log_level = new_level;
    }
    
    
    
    // - mpi world rank can be added later
    // FIXME: if start_time is NULL, generate
    void logging_initialize(enum cats_log_level level, const struct cats_time *start_time, const char *log_file_name, bool quiet)
    {
            set_log_level(level);
            logging_quiet = quiet;
            if (start_time != NULL) {
                    cats_logging_start_time = *start_time;
                    time_initialized = true;
            }
    
            if (log_file_name != NULL) {
                    cats_log_file_name = strdup(log_file_name);
                    cats_log_file = fopen(log_file_name, "w");
                    ENSURE_FILE_OPENED(cats_log_file, cats_log_file_name)
            }
    
    }
    
    
    void logging_set_module_name(const char *name)
    {
            logging_module_name = name;
    }
    
    
    void logging_set_mpi_rank(int mpi_world_rank)
    {
            logging_mpi_rank = mpi_world_rank;
    }
    
    // actual logging function(s), only to be called from log_message
    void log_msg(const char *msg, enum cats_log_level loglevel);
    void log_msg_simple(const char *msg, enum cats_log_level loglevel);
    
    // logging wrapper function
    __attribute__ ((__format__ (__printf__, 2, 3)))
    void log_message(enum cats_log_level level, const char *fmt, ...)
    {
            if (level < internal_current_log_level) return;
    
            char *message = NULL;
    
            va_list arg_p;
            va_start(arg_p, fmt);
            int count = vsnprintf(NULL, 0, fmt, arg_p) + 1;
            va_end(arg_p);
    
            message = malloc_or_die(count);
    
            va_start(arg_p, fmt);
            vsnprintf(message, count, fmt, arg_p);
            va_end(arg_p);
            log_msg(message, level);
            free(message);
    }
    
    
    enum cats_log_level get_log_level(void)
    {
            return internal_current_log_level;
    }
    
    
    void log_message_simple(enum cats_log_level level, const char *fmt, ...)
    {
            if (level < internal_current_log_level) return;
            char *message = NULL;
            va_list arg_p;
    
            va_start(arg_p, fmt);
            int count = vsnprintf(NULL, 0, fmt, arg_p) + 1;
            va_end(arg_p);
            message = malloc_or_die(count);
    
            va_start(arg_p, fmt);
            vsnprintf(message, count, fmt, arg_p);
            va_end(arg_p);
            log_msg_simple(message, level);
            free(message);
    }
    
    
    void log_msg(const char *msg, enum cats_log_level loglevel)
    {
            if (loglevel < internal_current_log_level) return;
    
            if (loglevel == LOG_RAW) {
                    if (! logging_quiet) fprintf(stdout, "%s", msg);
                    if (cats_log_file != NULL) fprintf(cats_log_file, "%s", msg);
                    return;
            }
    
            if (loglevel == LOG_EMPTY) {
                    if (! logging_quiet) fprintf(stdout, "\n");
                    if (cats_log_file != NULL) fprintf(cats_log_file, "\n");
                    return;
            }
    
            const char *color = get_log_level_color(loglevel);
            if (loglevel == LOG_MARK) {
                    if (! logging_quiet)  fprintf(stdout, "%s%s%s\n", color, msg, C_RESET);
                    if (cats_log_file != NULL)  fprintf(cats_log_file, "%s%s%s\n", color, msg, C_RESET);
                    return;
            }
            const char *log_default = "unknown";
    
            const char *loglevel_name = log_default;
    
            if (loglevel <= LOG_UNKNOWN && loglevel >= LOG_DEBUG) {
                    loglevel_name = get_log_level_name(loglevel);
            }
    
    
            if (logging_mpi_rank >= 0) {
                    if (! logging_quiet) fprintf(stdout, "(%02d)::", logging_mpi_rank);
                    if (cats_log_file != NULL) fprintf(cats_log_file, "(%02d)::", logging_mpi_rank);
            }
    
            if (time_initialized) {
                    double secs = seconds_monotonic_since(&cats_logging_start_time);
                    if (cats_log_file != NULL) {
                            fprintf(cats_log_file, "% 16.4f::", secs);
                    }
                    if (! logging_quiet) fprintf(stdout, "% 16.4f::", secs);
            } else {
                    if (cats_log_file != NULL) {
                            fprintf(cats_log_file, "                ::");
                    }
                    if (! logging_quiet)  fprintf(stdout, "                ::");
            }
    
            if (logging_module_name != NULL) {
                    if (! logging_quiet) fprintf(stdout, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET);
                    if (cats_log_file) fprintf(cats_log_file, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET);
    
            } else {
                    if (! logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
                    if (cats_log_file)   fprintf(cats_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
    
            }
    
    }
    
    
    void log_msg_simple(const char *msg, enum cats_log_level loglevel)
    {
            if (loglevel < internal_current_log_level) return;
            const char *log_default = "unknown";
            const char *loglevel_name = log_default;
    
            if (loglevel <= LOG_UNKNOWN && loglevel >= LOG_DEBUG) {
                    loglevel_name = get_log_level_name(loglevel);
            }
    
            const char *color = get_log_level_color(loglevel);
            if (logging_mpi_rank >= 0) {
                    if (! logging_quiet)        fprintf(stdout, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET);
                    if (cats_log_file != NULL)  fprintf(cats_log_file, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET);
    
            } else {
                    if (! logging_quiet)        fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
                    if (cats_log_file != NULL)  fprintf(cats_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
    
            }
    
    }