File indexing completed on 2024-05-19 13:35:40
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 }