* Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <syslog.h>
#include "cdma_u_log.h"
#include "cdma_u_lib.h"
static struct cdma_log_level_st g_cdma_log_level = {
CDMA_VLOG_LEVEL_INFO,
PTHREAD_MUTEX_INITIALIZER
};
#define MAX_LOG_LEN 512
#define CDMA_LOG_TAG "CDMA_LOG_TAG"
#define CDMA_LOG_ENV_STR "CDMA_LOG_LEVEL"
#define CDMA_ENV_MAX_LEN 32
static inline void cdma_default_log_func(int level, char *message)
{
syslog(level, "%s", message);
}
inline bool cdma_log_drop(enum cdma_log_level level)
{
return level > g_cdma_log_level.level;
}
enum cdma_log_level cdma_log_get_level(const char *level_string)
{
if (level_string == NULL)
return CDMA_VLOG_LEVEL_MAX;
if (strcasecmp(level_string, "fatal") == 0)
return CDMA_VLOG_LEVEL_CRIT;
if (strcasecmp(level_string, "error") == 0)
return CDMA_VLOG_LEVEL_ERR;
if (strcasecmp(level_string, "warning") == 0)
return CDMA_VLOG_LEVEL_WARNING;
if (strcasecmp(level_string, "info") == 0)
return CDMA_VLOG_LEVEL_INFO;
if (strcasecmp(level_string, "debug") == 0)
return CDMA_VLOG_LEVEL_DEBUG;
return CDMA_VLOG_LEVEL_MAX;
}
void cdma_getenv_log_level(void)
{
char *level_str = getenv(CDMA_LOG_ENV_STR);
if (level_str == NULL)
return;
if (strnlen(level_str, CDMA_ENV_MAX_LEN) >= CDMA_ENV_MAX_LEN) {
CDMA_LOG_ERR("invalid parameter: log level str\n");
return;
}
enum cdma_log_level log_level = cdma_log_get_level(level_str);
if (log_level != CDMA_VLOG_LEVEL_MAX) {
pthread_mutex_lock(&g_cdma_log_level.lock);
g_cdma_log_level.level = log_level;
pthread_mutex_unlock(&g_cdma_log_level.lock);
}
}
static __attribute__((format(printf, 4, 0)))
int cdma_vlog(const char *function, int line, enum cdma_log_level level,
const char *format, va_list va)
{
char newformat[MAX_LOG_LEN + 1] = {0};
char logmsg[MAX_LOG_LEN + 1] = {0};
int ret;
ret = snprintf(newformat, MAX_LOG_LEN, "%s|%s[%d]|%s", CDMA_LOG_TAG,
function, line, format);
if (ret <= 0 || ret >= (int)sizeof(newformat))
return ret;
ret = vsnprintf(logmsg, MAX_LOG_LEN, newformat, va);
if (ret == -1) {
(void)printf("logmsg size exceeds MAX_LOG_LEN size: %d\n",
MAX_LOG_LEN);
return ret;
}
cdma_default_log_func((int)level, logmsg);
return ret;
}
void cdma_log(const char *function, int line, enum cdma_log_level level,
const char *format, ...)
{
va_list va;
va_start(va, format);
(void)cdma_vlog(function, line, level, format, va);
va_end(va);
}
static __attribute__((constructor)) void cdma_log_init(void)
{
cdma_getenv_log_level();
CDMA_LOG_INFO("cdma version %s\n", CDMA_VERSION);
}
static __attribute__((destructor)) void cdma_log_uninit(void)
{
}