1 /*
2 * Copyright (C) 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "hal_event_logger.h"
18
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include <fcntl.h>
22 #include <sys/stat.h>
23
24 #include <cstring>
25 #include <ctime>
26
27 #include "config.h"
28 #include "hal_config.h"
29
30 #define TIMESTAMP_BUFFER_SIZE 64
31 #define HAL_LOG_FILE_SIZE 32 * 1024 * 1024
32 #define HAL_MEM_BUFFER_SIZE 256 * 1024
33
getInstance()34 HalEventLogger& HalEventLogger::getInstance() {
35 static HalEventLogger nfc_event_eventLogger;
36 return nfc_event_eventLogger;
37 }
log()38 HalEventLogger& HalEventLogger::log() {
39 struct timespec tv;
40 clock_gettime(CLOCK_REALTIME, &tv);
41 time_t rawtime = tv.tv_sec;
42 struct tm* timeinfo;
43 char buffer[TIMESTAMP_BUFFER_SIZE];
44 char timestamp[TIMESTAMP_BUFFER_SIZE];
45 timeinfo = localtime(&rawtime);
46 int milliseconds = tv.tv_nsec / 1000000;
47 strftime(buffer, sizeof(buffer), "%m-%d %H:%M:%S", timeinfo);
48 sprintf(timestamp, "%s.%03d", buffer, milliseconds);
49 if (ss.str().size() > HAL_MEM_BUFFER_SIZE) {
50 std::string currentString = ss.str();
51 currentString =
52 currentString.substr(currentString.size() - HAL_MEM_BUFFER_SIZE);
53 std::ostringstream newBuffer;
54 newBuffer << currentString;
55 newBuffer << timestamp << ": ";
56 ss.str("");
57 ss.clear();
58 ss << newBuffer.str();
59 } else {
60 ss << timestamp << ": ";
61 }
62 return getInstance();
63 }
64
initialize()65 void HalEventLogger::initialize() {
66 LOG(DEBUG) << __func__;
67 unsigned long num = 0;
68 char HalLogPath[256];
69
70 if (GetNumValue(NAME_HAL_EVENT_LOG_DEBUG_ENABLED, &num, sizeof(num))) {
71 logging_enabled = (num == 1) ? true : false;
72 }
73 LOG(INFO) << __func__ << " logging_enabled: " << logging_enabled;
74 if (!logging_enabled) {
75 return;
76 }
77 if (!GetStrValue(NAME_HAL_EVENT_LOG_STORAGE, (char*)HalLogPath,
78 sizeof(HalLogPath))) {
79 LOG(WARNING) << __func__
80 << " HAL log path not found in conf. use default location "
81 "/data/vendor/nfc";
82 strcpy(HalLogPath, "/data/vendor/nfc");
83 }
84 EventFilePath = HalLogPath;
85 EventFilePath += "/hal_event_log.txt";
86 }
87
store_log()88 void HalEventLogger::store_log() {
89 LOG(DEBUG) << __func__;
90 if (!logging_enabled) return;
91 std::ofstream logFile;
92 if (std::filesystem::exists(EventFilePath) &&
93 std::filesystem::file_size(EventFilePath) > HAL_LOG_FILE_SIZE) {
94 logFile.open(EventFilePath, std::ios::out | std::ios::trunc);
95 } else {
96 logFile.open(EventFilePath, std::ios::app);
97 }
98 if (logFile.is_open()) {
99 logFile << ss.rdbuf();
100 logFile.close();
101 ss.str("");
102 ss.clear();
103 } else {
104 LOG(ERROR) << __func__ << " EventEventLogger: Log file " << EventFilePath
105 << " couldn't be opened! errno: " << errno;
106 }
107 }
108
dump_log(int fd)109 void HalEventLogger::dump_log(int fd) {
110 LOG(DEBUG) << __func__;
111 if (!logging_enabled) return;
112 std::ostringstream oss;
113 if (std::filesystem::exists(EventFilePath) &&
114 std::filesystem::file_size(EventFilePath) > 0) {
115 std::ifstream readFile(EventFilePath);
116 if (readFile.is_open()) {
117 oss << readFile.rdbuf() << ss.str();
118 readFile.close();
119 } else {
120 LOG(ERROR) << __func__ << " EventEventLogger: Failed to open log file "
121 << EventFilePath << " for reading!";
122 oss << ss.str();
123 }
124 } else {
125 LOG(INFO) << __func__ << " EventEventLogger: Log file " << EventFilePath
126 << " not exists or no content";
127 oss << ss.str();
128 }
129
130 dprintf(fd, "===== Nfc HAL Event Log v1 =====\n");
131 ::android::base::WriteStringToFd(oss.str(), fd);
132 dprintf(fd, "===== Nfc HAL Event Log v1 =====\n");
133 fsync(fd);
134 }