• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "securec.h"
24 
25 #define UNUSED(x) \
26     do { \
27         (void)(x) \
28     } while (0)
29 
30 #define MAX_LOG_SIZE 128
31 #define BASE_YEAR 1900
32 
33 static InitLogLevel g_logLevel = INIT_ERROR;
34 static const char *LOG_LEVEL_STR[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
35 
SetInitLogLevel(InitLogLevel logLevel)36 void SetInitLogLevel(InitLogLevel logLevel)
37 {
38     g_logLevel = logLevel;
39 }
40 
41 #ifdef OHOS_LITE
ConvertToHiLog(InitLogLevel level)42 static LogLevel ConvertToHiLog(InitLogLevel level)
43 {
44     switch (level) {
45         case INIT_DEBUG:
46             return LOG_DEBUG;
47         case INIT_INFO:
48             return LOG_INFO;
49         case INIT_WARN:
50             return LOG_WARN;
51         case INIT_ERROR:
52             return LOG_ERROR;
53         case INIT_FATAL:
54             return LOG_FATAL;
55         // Unexpected log level, set level as lowest
56         default:
57             return LOG_DEBUG;
58     }
59 }
60 
InitToHiLog(InitLogLevel logLevel,const char * fmt,...)61 void InitToHiLog(InitLogLevel logLevel, const char *fmt, ...)
62 {
63     if (logLevel < g_logLevel) {
64         return;
65     }
66 
67     va_list list;
68     va_start(list, fmt);
69     char tmpFmt[MAX_LOG_SIZE];
70     if (vsnprintf_s(tmpFmt, MAX_LOG_SIZE, MAX_LOG_SIZE - 1, fmt, list) == -1) {
71         va_end(list);
72         return;
73     }
74     (void)HiLogPrint(LOG_CORE, ConvertToHiLog(logLevel), LOG_DOMAIN, INIT_LOG_TAG, "%{public}s", tmpFmt);
75     va_end(list);
76     return;
77 }
78 #endif
79 
80 static int g_fd = -1;
OpenLogDevice(void)81 void OpenLogDevice(void)
82 {
83     int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IRGRP);
84     if (fd >= 0) {
85         g_fd = fd;
86     }
87     return;
88 }
89 
InitLogInit(const char * outFileName,InitLogLevel logLevel,const char * kLevel,const char * fmt,...)90 void InitLogInit(const char *outFileName, InitLogLevel logLevel, const char *kLevel, const char *fmt, ...)
91 {
92     if (logLevel < g_logLevel) {
93         return;
94     }
95 
96     if (UNLIKELY(g_fd < 0)) {
97         OpenLogDevice();
98         if (g_fd < 0) {
99             return;
100         }
101     }
102     va_list vargs;
103     va_start(vargs, fmt);
104     char tmpFmt[MAX_LOG_SIZE];
105     if (vsnprintf_s(tmpFmt, MAX_LOG_SIZE, MAX_LOG_SIZE - 1, fmt, vargs) == -1) {
106         close(g_fd);
107         g_fd = -1;
108         va_end(vargs);
109         return;
110     }
111 
112     char logInfo[MAX_LOG_SIZE];
113     if (snprintf_s(logInfo, MAX_LOG_SIZE, MAX_LOG_SIZE - 1, "%s[pid=%d][%s][%s] %s",
114         kLevel, getpid(), "INIT", LOG_LEVEL_STR[logLevel], tmpFmt) == -1) {
115         close(g_fd);
116         g_fd = -1;
117         va_end(vargs);
118         return;
119     }
120     va_end(vargs);
121 
122     if (write(g_fd, logInfo, strlen(logInfo)) < 0) {
123         close(g_fd);
124         g_fd = -1;
125     }
126     return;
127 }
128 
InitLogAgent(const char * outFileName,InitLogLevel logLevel,const char * kLevel,const char * fmt,...)129 void InitLogAgent(const char *outFileName, InitLogLevel logLevel, const char *kLevel, const char *fmt, ...)
130 {
131     if (logLevel < g_logLevel) {
132         return;
133     }
134     time_t second = time(0);
135     INIT_CHECK_ONLY_RETURN(second >= 0 && outFileName != NULL);
136     struct tm *t = localtime(&second);
137     INIT_CHECK_ONLY_RETURN(t != NULL);
138     FILE *outfile = fopen(outFileName, "a+");
139     INIT_CHECK_ONLY_RETURN(outfile != NULL);
140     (void)fprintf(outfile, "[%d-%d-%d %d:%d:%d][pid=%d][%s][%s] ",
141         (t->tm_year + BASE_YEAR), (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
142         getpid(), kLevel, LOG_LEVEL_STR[logLevel]);
143     va_list list;
144     va_start(list, fmt);
145     (void)vfprintf(outfile, fmt, list);
146     va_end(list);
147     (void)fflush(outfile);
148     fclose(outfile);
149     return;
150 }
151