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