1/* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "init_log.h" 17 18#include <errno.h> 19#include <fcntl.h> 20#include <stdarg.h> 21#include <sys/stat.h> 22#include <time.h> 23#include <sys/time.h> 24 25#include "init_utils.h" 26#include "securec.h" 27#ifdef OHOS_LITE 28#ifndef INIT_LOG_INIT 29#define INIT_LOG_INIT LOG_CORE 30#endif 31#include "hilog/log.h" 32#endif 33#ifdef INIT_AGENT 34#include "hilog_base/log_base.h" 35#endif 36 37#define DEF_LOG_SIZE 128 38#define BASE_YEAR 1900 39 40static InitLogLevel g_logLevel = INIT_INFO; 41#ifdef INIT_FILE 42static void LogToFile(const char *logFile, const char *tag, const char *info) 43{ 44 struct timespec curr = {0}; 45 if (clock_gettime(CLOCK_REALTIME, &curr) != 0) { 46 return; 47 } 48 FILE *outfile = NULL; 49 INIT_CHECK_ONLY_RETURN((outfile = fopen(logFile, "a+")) != NULL); 50 struct tm t; 51 char dateTime[80] = {"00-00-00 00:00:00"}; // 80 data time 52 if (localtime_r(&curr.tv_sec, &t) != NULL) { 53 strftime(dateTime, sizeof(dateTime), "%Y-%m-%d %H:%M:%S", &t); 54 } 55 (void)fprintf(outfile, "[%s.%ld][pid=%d %d][%s]%s \n", dateTime, curr.tv_nsec, getpid(), gettid(), tag, info); 56 (void)fflush(outfile); 57 (void)fclose(outfile); 58 return; 59} 60#endif 61 62#ifdef INIT_DMESG 63static int g_fd = -1; 64INIT_LOCAL_API void OpenLogDevice(void) 65{ 66 int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 67 if (fd >= 0) { 68 g_fd = fd; 69 } 70 return; 71} 72 73void LogToDmesg(InitLogLevel logLevel, const char *tag, const char *info) 74{ 75 static const char *LOG_LEVEL_STR[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" }; 76 static const char *LOG_KLEVEL_STR[] = { "<7>", "<6>", "<4>", "<3>", "<3>" }; 77 78 if (UNLIKELY(g_fd < 0)) { 79 OpenLogDevice(); 80 if (g_fd < 0) { 81 return; 82 } 83 } 84 char logInfo[DEF_LOG_SIZE + DEF_LOG_SIZE] = {0}; 85 if (snprintf_s(logInfo, sizeof(logInfo), sizeof(logInfo) - 1, "%s[pid=%d][%s][%s]%s", 86 LOG_KLEVEL_STR[logLevel], getpid(), tag, LOG_LEVEL_STR[logLevel], info) == -1) { 87 logInfo[sizeof(logInfo) - 2] = '\n'; // 2 add \n to tail 88 logInfo[sizeof(logInfo) - 1] = '\0'; 89 return; 90 } 91 if (write(g_fd, logInfo, strlen(logInfo)) < 0) { 92 printf("%s\n", logInfo); 93 } 94 return; 95} 96 97INIT_PUBLIC_API int GetKmsgFd() 98{ 99 return g_fd; 100} 101#endif 102 103static void PrintLog(InitLogLevel logLevel, unsigned int domain, const char *tag, const char *logInfo) 104{ 105#if defined(__LITEOS_A__) || defined(__LINUX__) 106 static const LogLevel LOG_LEVEL[] = { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL }; 107 (void)HiLogPrint(INIT_LOG_INIT, LOG_LEVEL[logLevel], domain, tag, "%s", logInfo); 108#endif 109#ifdef INIT_DMESG 110 LogToDmesg(logLevel, tag, logInfo); 111#endif 112#ifdef INIT_AGENT 113 static const LogLevel LOG_LEVEL[] = { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL }; 114 HiLogBasePrint(LOG_CORE, LOG_LEVEL[logLevel], domain, tag, "%{public}s", logInfo); 115#endif 116#ifdef INIT_FILE 117 LogToFile(INIT_LOG_PATH"begetctl.log", tag, logInfo); 118#endif 119} 120 121static void PrintLogFmt(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs) 122{ 123 char tmpFmt[DEF_LOG_SIZE] = {0}; 124 if (vsnprintf_s(tmpFmt, sizeof(tmpFmt), sizeof(tmpFmt) - 1, fmt, vargs) == -1) { 125 tmpFmt[sizeof(tmpFmt) - 2] = '\n'; // 2 add \n to tail 126 tmpFmt[sizeof(tmpFmt) - 1] = '\0'; 127 } 128 PrintLog((InitLogLevel)logLevel, domain, tag, tmpFmt); 129} 130 131INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs) 132{ 133 if ((int)g_logLevel > logLevel) { 134 return; 135 } 136 PrintLogFmt((InitLogLevel)logLevel, domain, tag, fmt, vargs); 137} 138 139INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level) 140{ 141 if (level <= INIT_FATAL) { 142 g_logLevel = level; 143 } 144 return; 145} 146 147INIT_LOCAL_API void EnableInitLog(InitLogLevel level) 148{ 149 g_logLevel = level; 150 SetInitCommLog(InitLog); 151} 152 153INIT_PUBLIC_API InitLogLevel GetInitLogLevel() 154{ 155 return g_logLevel; 156} 157