File indexing completed on 2024-04-28 05:46:49

0001 /*****************************************************************************
0002  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0003  *                                                                           *
0004  *   This program is free software; you can redistribute it and/or modify    *
0005  *   it under the terms of the GNU Lesser General Public License as          *
0006  *   published by the Free Software Foundation; either version 2.1 of the    *
0007  *   License, or (at your option) version 3, or any later version accepted   *
0008  *   by the membership of KDE e.V. (or its successor approved by the         *
0009  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0010  *   Section 6 of version 3 of the license.                                  *
0011  *                                                                           *
0012  *   This program is distributed in the hope that it will be useful,         *
0013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0015  *   Lesser General Public License for more details.                         *
0016  *                                                                           *
0017  *   You should have received a copy of the GNU Lesser General Public        *
0018  *   License along with this library. If not,                                *
0019  *   see <http://www.gnu.org/licenses/>.                                     *
0020  *****************************************************************************/
0021 
0022 #include <config.h>
0023 #include "log.h"
0024 #include "strs.h"
0025 #include "map.h"
0026 #include <unistd.h>
0027 #include <stdarg.h>
0028 
0029 #ifdef QTC_ENABLE_BACKTRACE
0030 #include <execinfo.h>
0031 #endif
0032 
0033 namespace QtCurve {
0034 
0035 QTC_EXPORT void
0036 backtrace()
0037 {
0038 #ifdef QTC_ENABLE_BACKTRACE
0039     void *buff[1024];
0040     size_t size = ::backtrace(buff, 1024);
0041     ::backtrace_symbols_fd(buff, size, STDERR_FILENO);
0042 #endif
0043 }
0044 
0045 namespace Log {
0046 
0047 QTC_EXPORT LogLevel
0048 level()
0049 {
0050     static LogLevel _level = [] () -> LogLevel {
0051         const char *env_debug = getenv("QTCURVE_DEBUG");
0052         if (Str::convert(env_debug, false)) {
0053             return LogLevel::Debug;
0054         }
0055         static const StrMap<LogLevel, false> level_map{
0056             {"debug", LogLevel::Debug},
0057             {"info", LogLevel::Info},
0058             {"warning", LogLevel::Warn},
0059             {"warn", LogLevel::Warn},
0060             {"error", LogLevel::Error}
0061         };
0062         LogLevel res = level_map.search(getenv("QTCURVE_LEVEL"),
0063                                         LogLevel::Error);
0064         if (Str::convert(env_debug, true) && res <= LogLevel::Debug) {
0065             return LogLevel::Info;
0066         }
0067         return res;
0068     }();
0069     return _level;
0070 }
0071 
0072 static bool
0073 useColor()
0074 {
0075     static bool color = [] () -> bool {
0076         const char *env_color = getenv("QTCURVE_LOG_COLOR");
0077         if (Str::convert(env_color, false)) {
0078             return true;
0079         } else if (!Str::convert(env_color, true)) {
0080             return false;
0081         } else if (isatty(2)) {
0082             return true;
0083         } else {
0084             return false;
0085         }
0086     }();
0087     return color;
0088 }
0089 
0090 QTC_EXPORT void
0091 logv(LogLevel _level, const char *fname, int line, const char *func,
0092      const char *fmt, va_list ap)
0093 {
0094     QTC_RET_IF_FAIL(_level >= level() && ((int)_level) >= 0 &&
0095                     _level <= LogLevel::Force);
0096     static const char *color_codes[] = {
0097         [(int)LogLevel::Debug] = "\e[01;32m",
0098         [(int)LogLevel::Info] = "\e[01;34m",
0099         [(int)LogLevel::Warn] = "\e[01;33m",
0100         [(int)LogLevel::Error] = "\e[01;31m",
0101         [(int)LogLevel::Force] = "\e[01;35m",
0102     };
0103 
0104     static const char *log_prefixes[] = {
0105         [(int)LogLevel::Debug] = "qtcDebug-",
0106         [(int)LogLevel::Info] = "qtcInfo-",
0107         [(int)LogLevel::Warn] = "qtcWarn-",
0108         [(int)LogLevel::Error] = "qtcError-",
0109         [(int)LogLevel::Force] = "qtcLog-",
0110     };
0111 
0112     const char *color_prefix = (useColor() ? color_codes[(int)_level] : "");
0113     const char *log_prefix = log_prefixes[(int)_level];
0114 
0115     fprintf(stderr, "%s%s%d (%s:%d) %s ", color_prefix, log_prefix, getpid(),
0116             fname, line, func);
0117     vfprintf(stderr, fmt, ap);
0118     if (useColor()) {
0119         fwrite("\e[0m", strlen("\e[0m"), 1, stderr);
0120     }
0121 }
0122 
0123 QTC_EXPORT void
0124 log(LogLevel _level, const char *fname, int line, const char *func,
0125     const char *fmt, ...)
0126 {
0127     va_list ap;
0128     va_start(ap, fmt);
0129     logv(_level, fname, line, func, fmt, ap);
0130     va_end(ap);
0131 }
0132 
0133 }
0134 }