• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
40 static InitLogLevel g_logLevel = INIT_INFO;
41 #ifdef INIT_FILE
LogToFile(const char * logFile,const char * tag,const char * info)42 static 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     fclose(outfile);
58     return;
59 }
60 #endif
61 
62 #ifdef INIT_DMESG
63 static int g_fd = -1;
OpenLogDevice(void)64 INIT_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 
LogToDmesg(InitLogLevel logLevel,const char * tag,const char * info)73 void 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 #endif
97 
PrintLog(InitLogLevel logLevel,unsigned int domain,const char * tag,const char * logInfo)98 static void PrintLog(InitLogLevel logLevel, unsigned int domain, const char *tag, const char *logInfo)
99 {
100 #if defined(__LITEOS_A__) || defined(__LINUX__)
101     static const LogLevel LOG_LEVEL[] = { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
102     (void)HiLogPrint(INIT_LOG_INIT, LOG_LEVEL[logLevel], domain, tag, "%s", logInfo);
103 #endif
104 #ifdef INIT_DMESG
105     LogToDmesg(logLevel, tag, logInfo);
106 #endif
107 #ifdef INIT_AGENT
108     static const LogLevel LOG_LEVEL[] = { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
109     HiLogBasePrint(LOG_CORE, LOG_LEVEL[logLevel], domain, tag, "%{public}s", logInfo);
110 #endif
111 #ifdef INIT_FILE
112     LogToFile(INIT_LOG_PATH"begetctl.log", tag, logInfo);
113 #endif
114 }
115 
PrintLogFmt(int logLevel,unsigned int domain,const char * tag,const char * fmt,va_list vargs)116 static void PrintLogFmt(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs)
117 {
118     char tmpFmt[DEF_LOG_SIZE] = {0};
119     if (vsnprintf_s(tmpFmt, sizeof(tmpFmt), sizeof(tmpFmt) - 1, fmt, vargs) == -1) {
120         tmpFmt[sizeof(tmpFmt) - 2] = '\n'; // 2 add \n to tail
121         tmpFmt[sizeof(tmpFmt) - 1] = '\0';
122     }
123     PrintLog((InitLogLevel)logLevel, domain, tag, tmpFmt);
124 }
125 
InitLog(int logLevel,unsigned int domain,const char * tag,const char * fmt,va_list vargs)126 INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs)
127 {
128     if ((int)g_logLevel > logLevel) {
129         return;
130     }
131     PrintLogFmt((InitLogLevel)logLevel, domain, tag, fmt, vargs);
132 }
133 
SetInitLogLevel(InitLogLevel level)134 INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level)
135 {
136     if (level <= INIT_FATAL) {
137         g_logLevel = level;
138     }
139     return;
140 }
141 
EnableInitLog(InitLogLevel level)142 INIT_LOCAL_API void EnableInitLog(InitLogLevel level)
143 {
144     g_logLevel = level;
145     SetInitCommLog(InitLog);
146 }
147 
GetInitLogLevel()148 INIT_PUBLIC_API InitLogLevel GetInitLogLevel()
149 {
150     return g_logLevel;
151 }
152