/** * @copyright * * Tencent is pleased to support the open source community by making IoT Hub available. * Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved. * * Licensed under the MIT License(the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://opensource.org/licenses/MIT * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions and * limitations under the License. * * @file utils_log.c * @brief different level log generator * @author fancyxu (fancyxu@tencent.com) * @version 1.0 * @date 2021-05-28 * * @par Change Log: * *
Date Version Author Description *
2021-05-28 1.0 fancyxu first commit *
*/ #include "utils_log.h" static const char *LEVEL_STR[] = {"DIS", "ERR", "WRN", "INF", "DBG"}; static LogHandleFunc sg_log_handle_func; static char *sg_log_buffer; static int sg_log_max_size; static void *sg_log_mutex; static LogLevel sg_log_print_level = LOG_LEVEL_DEBUG; extern LogLevel sg_log_upload_level; /** * @brief Get file name form path. * * @param[in] path file path * @return file name */ static const char *_get_filename(const char *path) { #ifdef WIN32 char ch = '\\'; #else char ch = '/'; #endif const char *q = strrchr(path, ch); if (!q) { q = path; } else { q++; } return q; } /** * @brief Init log with func, log level, max log size. * * @param[in] func function should be implement for utils log * @param[in] log_level @see LogLevel * @param[in] max_log_size max size of log to print * @return 0 for success */ int utils_log_init(LogHandleFunc func, LogLevel log_level, int max_log_size) { sg_log_handle_func = func; sg_log_print_level = log_level; sg_log_max_size = max_log_size; if (func.log_mutex_create) { sg_log_mutex = func.log_mutex_create(); if (!sg_log_mutex) { return -1; } } if (func.log_malloc) { sg_log_buffer = func.log_malloc(max_log_size); if (!sg_log_buffer) { if (sg_log_mutex) { func.log_mutex_destroy(sg_log_mutex); } } } return !sg_log_buffer; } /** * @brief Deinit log. * */ void utils_log_deinit(void) { sg_log_handle_func.log_free(sg_log_buffer); if (sg_log_mutex) { sg_log_handle_func.log_mutex_destroy(sg_log_mutex); } sg_log_mutex = NULL; sg_log_buffer = NULL; } /** * @brief Set log level. * * @param log_level @see LogLevel */ void utils_log_set_level(LogLevel log_level) { sg_log_print_level = log_level; } /** * @brief Get log level. * * @return @see LogLevel */ LogLevel utils_log_get_level(void) { return sg_log_print_level; } /** * @brief Generate log if level higher than set. * * @param[in] file file path * @param[in] func function where generate log * @param[in] line line of source file where genertate log * @param[in] level @see LogLevel * @param[in] fmt format of log content */ void utils_log_gen(const char *file, const char *func, const int line, const int level, const char *fmt, ...) { if (level > sg_log_print_level) { return; } if (sg_log_mutex) { sg_log_handle_func.log_mutex_lock(sg_log_mutex); } /* format log content */ const char *file_name = _get_filename(file); char *o = sg_log_buffer; memset(sg_log_buffer, 0, sg_log_max_size); o += snprintf(sg_log_buffer, sg_log_max_size, "%s|%s|%s|%s(%d): ", LEVEL_STR[level], sg_log_handle_func.log_get_current_time_str(), file_name, func, line); va_list ap; va_start(ap, fmt); vsnprintf(o, sg_log_max_size - 2 - strlen(sg_log_buffer), fmt, ap); va_end(ap); strncat(sg_log_buffer, "\r\n", sg_log_max_size - strlen(sg_log_buffer) - 1); if (level <= sg_log_print_level) { if (sg_log_handle_func.log_handle) { sg_log_handle_func.log_handle(sg_log_buffer); } sg_log_handle_func.log_printf("%s", sg_log_buffer); } /* append to upload buffer */ if (sg_log_handle_func.log_upload) { sg_log_handle_func.log_upload(level, sg_log_buffer); } if (sg_log_mutex) { sg_log_handle_func.log_mutex_unlock(sg_log_mutex); } return; }