1d96309c9Sopenharmony_ci/* 2d96309c9Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd. 3d96309c9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d96309c9Sopenharmony_ci * you may not use this file except in compliance with the License. 5d96309c9Sopenharmony_ci * You may obtain a copy of the License at 6d96309c9Sopenharmony_ci * 7d96309c9Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d96309c9Sopenharmony_ci * 9d96309c9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d96309c9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d96309c9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d96309c9Sopenharmony_ci * See the License for the specific language governing permissions and 13d96309c9Sopenharmony_ci * limitations under the License. 14d96309c9Sopenharmony_ci */ 15d96309c9Sopenharmony_ci 16d96309c9Sopenharmony_ci#include <errno.h> 17d96309c9Sopenharmony_ci#include <fcntl.h> 18d96309c9Sopenharmony_ci#include <securec.h> 19d96309c9Sopenharmony_ci#include <string.h> 20d96309c9Sopenharmony_ci#include <sys/stat.h> 21d96309c9Sopenharmony_ci#include <sys/types.h> 22d96309c9Sopenharmony_ci#include <time.h> 23d96309c9Sopenharmony_ci#include <unistd.h> 24d96309c9Sopenharmony_ci 25d96309c9Sopenharmony_ci#include "hilog_command.h" 26d96309c9Sopenharmony_ci 27d96309c9Sopenharmony_ci#define HILOG_LOGBUFFER 2048 28d96309c9Sopenharmony_ci#ifndef HILOG_DIR 29d96309c9Sopenharmony_ci#define HILOG_DIR "/storage/data/log" 30d96309c9Sopenharmony_ci#endif 31d96309c9Sopenharmony_ci#define HILOG_PATH1 HILOG_DIR "/hilog1.txt" 32d96309c9Sopenharmony_ci#define HILOG_PATH2 HILOG_DIR "/hilog2.txt" 33d96309c9Sopenharmony_ci 34d96309c9Sopenharmony_ci#undef LOG_TAG 35d96309c9Sopenharmony_ci#define LOG_TAG "apphilogcat" 36d96309c9Sopenharmony_ci 37d96309c9Sopenharmony_cistatic int file1Size = 0; 38d96309c9Sopenharmony_cistatic int file2Size = 0; 39d96309c9Sopenharmony_ci 40d96309c9Sopenharmony_ciint FlushAndSync(FILE *fp); 41d96309c9Sopenharmony_ci 42d96309c9Sopenharmony_cistatic int FileSize(const char *filename) 43d96309c9Sopenharmony_ci{ 44d96309c9Sopenharmony_ci FILE *fp = fopen(filename, "r"); 45d96309c9Sopenharmony_ci if (!fp) { 46d96309c9Sopenharmony_ci return -1; 47d96309c9Sopenharmony_ci } 48d96309c9Sopenharmony_ci 49d96309c9Sopenharmony_ci int size = 0; 50d96309c9Sopenharmony_ci int ret = fseek(fp, 0L, SEEK_END); 51d96309c9Sopenharmony_ci if (ret == 0) { 52d96309c9Sopenharmony_ci size = ftell(fp); 53d96309c9Sopenharmony_ci } 54d96309c9Sopenharmony_ci fclose(fp); 55d96309c9Sopenharmony_ci 56d96309c9Sopenharmony_ci return size; 57d96309c9Sopenharmony_ci} 58d96309c9Sopenharmony_ci 59d96309c9Sopenharmony_cistatic FILE *FileClear(FILE **fp, const char *filename) 60d96309c9Sopenharmony_ci{ 61d96309c9Sopenharmony_ci if (*fp != NULL) { 62d96309c9Sopenharmony_ci fclose(*fp); 63d96309c9Sopenharmony_ci } 64d96309c9Sopenharmony_ci *fp = fopen(filename, "w"); 65d96309c9Sopenharmony_ci if (*fp == NULL) { 66d96309c9Sopenharmony_ci return NULL; 67d96309c9Sopenharmony_ci } 68d96309c9Sopenharmony_ci printf("write file switch %s\n", filename); 69d96309c9Sopenharmony_ci return *fp; 70d96309c9Sopenharmony_ci} 71d96309c9Sopenharmony_ci 72d96309c9Sopenharmony_ciFILE *SelectWriteFile(FILE **fp1, FILE *fp2) 73d96309c9Sopenharmony_ci{ 74d96309c9Sopenharmony_ci file1Size = FileSize(HILOG_PATH1); 75d96309c9Sopenharmony_ci file2Size = FileSize(HILOG_PATH2); 76d96309c9Sopenharmony_ci if (file1Size < HILOG_MAX_FILELEN) { 77d96309c9Sopenharmony_ci return *fp1; 78d96309c9Sopenharmony_ci } else if (file2Size < HILOG_MAX_FILELEN) { 79d96309c9Sopenharmony_ci return fp2; 80d96309c9Sopenharmony_ci } else { // clear file1 write file 1 81d96309c9Sopenharmony_ci file1Size = 0; 82d96309c9Sopenharmony_ci return FileClear(fp1, HILOG_PATH1); 83d96309c9Sopenharmony_ci } 84d96309c9Sopenharmony_ci} 85d96309c9Sopenharmony_ci 86d96309c9Sopenharmony_ciFILE *SwitchWriteFile(FILE **fp1, FILE **fp2, FILE *curFp) 87d96309c9Sopenharmony_ci{ 88d96309c9Sopenharmony_ci // select file, if file1 is full, record file2, file2 is full, record file1 89d96309c9Sopenharmony_ci if (file1Size < HILOG_MAX_FILELEN) { 90d96309c9Sopenharmony_ci return *fp1; 91d96309c9Sopenharmony_ci } else if (file2Size < HILOG_MAX_FILELEN) { 92d96309c9Sopenharmony_ci return *fp2; 93d96309c9Sopenharmony_ci } else if (curFp == *fp2) { // clear file1 write file 1 94d96309c9Sopenharmony_ci FlushAndSync(*fp2); 95d96309c9Sopenharmony_ci file1Size = 0; 96d96309c9Sopenharmony_ci return FileClear(fp1, HILOG_PATH1); 97d96309c9Sopenharmony_ci } else { 98d96309c9Sopenharmony_ci FlushAndSync(*fp1); 99d96309c9Sopenharmony_ci file2Size = 0; 100d96309c9Sopenharmony_ci return FileClear(fp2, HILOG_PATH2); 101d96309c9Sopenharmony_ci } 102d96309c9Sopenharmony_ci} 103d96309c9Sopenharmony_ci 104d96309c9Sopenharmony_ciint FlushAndSync(FILE *fp) 105d96309c9Sopenharmony_ci{ 106d96309c9Sopenharmony_ci if (fp == NULL) { 107d96309c9Sopenharmony_ci return 0; 108d96309c9Sopenharmony_ci } 109d96309c9Sopenharmony_ci if (fflush(fp) != 0) { 110d96309c9Sopenharmony_ci return -1; 111d96309c9Sopenharmony_ci } 112d96309c9Sopenharmony_ci int fd = fileno(fp); 113d96309c9Sopenharmony_ci if (fsync(fd) != 0) { 114d96309c9Sopenharmony_ci return -1; 115d96309c9Sopenharmony_ci } 116d96309c9Sopenharmony_ci return 0; 117d96309c9Sopenharmony_ci} 118d96309c9Sopenharmony_ci 119d96309c9Sopenharmony_cibool NeedFlush(const char *buf) 120d96309c9Sopenharmony_ci{ 121d96309c9Sopenharmony_ci#define FLUSH_LOG_ARG_0 0 122d96309c9Sopenharmony_ci#define FLUSH_LOG_ARG_1 1 123d96309c9Sopenharmony_ci#define FLUSH_LOG_FLAG 0x07 124d96309c9Sopenharmony_ci if (buf[FLUSH_LOG_ARG_0] == FLUSH_LOG_FLAG && buf[FLUSH_LOG_ARG_1] == FLUSH_LOG_FLAG) { 125d96309c9Sopenharmony_ci return true; 126d96309c9Sopenharmony_ci } 127d96309c9Sopenharmony_ci return false; 128d96309c9Sopenharmony_ci} 129d96309c9Sopenharmony_ci 130d96309c9Sopenharmony_cistatic void FileClose(FILE *file) 131d96309c9Sopenharmony_ci{ 132d96309c9Sopenharmony_ci if (file != NULL) { 133d96309c9Sopenharmony_ci fclose(file); 134d96309c9Sopenharmony_ci } 135d96309c9Sopenharmony_ci} 136d96309c9Sopenharmony_ci 137d96309c9Sopenharmony_ciint main(int argc, char *argv[]) 138d96309c9Sopenharmony_ci{ 139d96309c9Sopenharmony_ci#define HILOG_UMASK 0027 140d96309c9Sopenharmony_ci int fd = -1; 141d96309c9Sopenharmony_ci int ret = -1; 142d96309c9Sopenharmony_ci FILE *fpWrite = NULL; 143d96309c9Sopenharmony_ci bool printFlag = true; 144d96309c9Sopenharmony_ci 145d96309c9Sopenharmony_ci if (argc > 1) { 146d96309c9Sopenharmony_ci ret = HilogCmdProc(LOG_TAG, argc, argv); 147d96309c9Sopenharmony_ci if (ret == -1) { 148d96309c9Sopenharmony_ci return 0; 149d96309c9Sopenharmony_ci } 150d96309c9Sopenharmony_ci } 151d96309c9Sopenharmony_ci 152d96309c9Sopenharmony_ci fd = open(HILOG_DRIVER, O_RDONLY | O_CLOEXEC); 153d96309c9Sopenharmony_ci if (fd < 0) { 154d96309c9Sopenharmony_ci printf("hilog fd failed %s\n", strerror(errno)); 155d96309c9Sopenharmony_ci return 0; 156d96309c9Sopenharmony_ci } 157d96309c9Sopenharmony_ci 158d96309c9Sopenharmony_ci umask(HILOG_UMASK); 159d96309c9Sopenharmony_ci FILE *fp1 = fopen(HILOG_PATH1, "at"); 160d96309c9Sopenharmony_ci if (fp1 == NULL) { 161d96309c9Sopenharmony_ci printf("open err fp1 %s\n", strerror(errno)); 162d96309c9Sopenharmony_ci close(fd); 163d96309c9Sopenharmony_ci return 0; 164d96309c9Sopenharmony_ci } 165d96309c9Sopenharmony_ci 166d96309c9Sopenharmony_ci FILE *fp2 = fopen(HILOG_PATH2, "at"); 167d96309c9Sopenharmony_ci if (fp2 == NULL) { 168d96309c9Sopenharmony_ci printf("open err fp2 %s\n", strerror(errno)); 169d96309c9Sopenharmony_ci FileClose(fp1); 170d96309c9Sopenharmony_ci close(fd); 171d96309c9Sopenharmony_ci return 0; 172d96309c9Sopenharmony_ci } 173d96309c9Sopenharmony_ci // First select 174d96309c9Sopenharmony_ci fpWrite = SelectWriteFile(&fp1, fp2); 175d96309c9Sopenharmony_ci if (fpWrite == NULL) { 176d96309c9Sopenharmony_ci printf("SelectWriteFile open err\n"); 177d96309c9Sopenharmony_ci close(fd); 178d96309c9Sopenharmony_ci FileClose(fp1); 179d96309c9Sopenharmony_ci FileClose(fp2); 180d96309c9Sopenharmony_ci return 0; 181d96309c9Sopenharmony_ci } 182d96309c9Sopenharmony_ci char *buf = malloc(HILOG_LOGBUFFER + 1); 183d96309c9Sopenharmony_ci if (buf == NULL) { 184d96309c9Sopenharmony_ci close(fd); 185d96309c9Sopenharmony_ci FileClose(fp1); 186d96309c9Sopenharmony_ci FileClose(fp2); 187d96309c9Sopenharmony_ci return 0; 188d96309c9Sopenharmony_ci } 189d96309c9Sopenharmony_ci while (1) { 190d96309c9Sopenharmony_ci (void)memset_s(buf, HILOG_LOGBUFFER + 1, 0, HILOG_LOGBUFFER + 1); 191d96309c9Sopenharmony_ci ret = read(fd, buf, HILOG_LOGBUFFER); 192d96309c9Sopenharmony_ci if (ret < 0 || ret < sizeof(struct HiLogEntry)) { 193d96309c9Sopenharmony_ci continue; 194d96309c9Sopenharmony_ci } 195d96309c9Sopenharmony_ci struct HiLogEntry *head = (struct HiLogEntry *)buf; 196d96309c9Sopenharmony_ci 197d96309c9Sopenharmony_ci if (NeedFlush(head->msg)) { 198d96309c9Sopenharmony_ci if (FlushAndSync(fpWrite) != 0) { 199d96309c9Sopenharmony_ci printf("flush and sync file err\n"); 200d96309c9Sopenharmony_ci } 201d96309c9Sopenharmony_ci continue; 202d96309c9Sopenharmony_ci } 203d96309c9Sopenharmony_ci 204d96309c9Sopenharmony_ci time_t rawtime; 205d96309c9Sopenharmony_ci struct tm *info = NULL; 206d96309c9Sopenharmony_ci struct tm nowTime = {0}; 207d96309c9Sopenharmony_ci unsigned int sec = head->sec; 208d96309c9Sopenharmony_ci rawtime = (time_t)sec; 209d96309c9Sopenharmony_ci /* Get local time */ 210d96309c9Sopenharmony_ci info = localtime_r(&rawtime, &nowTime); 211d96309c9Sopenharmony_ci 212d96309c9Sopenharmony_ci printFlag = FilterLevelLog(g_hiviewConfig.level, *(head->msg)); 213d96309c9Sopenharmony_ci if (!printFlag) { 214d96309c9Sopenharmony_ci continue; 215d96309c9Sopenharmony_ci } 216d96309c9Sopenharmony_ci#define MODULE_OFFSET 2 217d96309c9Sopenharmony_ci printFlag = FilterModuleLog(g_hiviewConfig.logOutputModule, (head->msg) + MODULE_OFFSET); 218d96309c9Sopenharmony_ci if (!printFlag) { 219d96309c9Sopenharmony_ci continue; 220d96309c9Sopenharmony_ci } 221d96309c9Sopenharmony_ci 222d96309c9Sopenharmony_ci if (info == NULL) { 223d96309c9Sopenharmony_ci continue; 224d96309c9Sopenharmony_ci } 225d96309c9Sopenharmony_ci buf[HILOG_LOGBUFFER - 1] = '\0'; 226d96309c9Sopenharmony_ci 227d96309c9Sopenharmony_ci if (g_hiviewConfig.silenceMod == SILENT_MODE_OFF) { 228d96309c9Sopenharmony_ci printf("%02d-%02d %02d:%02d:%02d.%03d %d %d %s\n", info->tm_mon + 1, info->tm_mday, info->tm_hour, 229d96309c9Sopenharmony_ci info->tm_min, info->tm_sec, head->nsec / NANOSEC_PER_MIRCOSEC, head->pid, head->taskId, head->msg); 230d96309c9Sopenharmony_ci } 231d96309c9Sopenharmony_ci 232d96309c9Sopenharmony_ci ret = 233d96309c9Sopenharmony_ci fprintf(fpWrite, "%02d-%02d %02d:%02d:%02d.%03d %d %d %s\n", info->tm_mon + 1, info->tm_mday, info->tm_hour, 234d96309c9Sopenharmony_ci info->tm_min, info->tm_sec, head->nsec / NANOSEC_PER_MIRCOSEC, head->pid, head->taskId, head->msg); 235d96309c9Sopenharmony_ci if (ret < 0) { 236d96309c9Sopenharmony_ci printf("[FATAL]File can't write fpWrite %s\n", strerror(errno)); 237d96309c9Sopenharmony_ci free(buf); 238d96309c9Sopenharmony_ci close(fd); 239d96309c9Sopenharmony_ci FileClose(fp1); 240d96309c9Sopenharmony_ci FileClose(fp2); 241d96309c9Sopenharmony_ci return 0; 242d96309c9Sopenharmony_ci } 243d96309c9Sopenharmony_ci if (fpWrite == fp1) { 244d96309c9Sopenharmony_ci file1Size += ret; 245d96309c9Sopenharmony_ci } else if (fpWrite == fp2) { 246d96309c9Sopenharmony_ci file2Size += ret; 247d96309c9Sopenharmony_ci } 248d96309c9Sopenharmony_ci // select file, if file1 is full, record file2, file2 is full, record file1 249d96309c9Sopenharmony_ci fpWrite = SwitchWriteFile(&fp1, &fp2, fpWrite); 250d96309c9Sopenharmony_ci if (fpWrite == NULL) { 251d96309c9Sopenharmony_ci printf("[FATAL]SwitchWriteFile failed\n"); 252d96309c9Sopenharmony_ci free(buf); 253d96309c9Sopenharmony_ci close(fd); 254d96309c9Sopenharmony_ci FileClose(fp1); 255d96309c9Sopenharmony_ci FileClose(fp2); 256d96309c9Sopenharmony_ci return 0; 257d96309c9Sopenharmony_ci } 258d96309c9Sopenharmony_ci } 259d96309c9Sopenharmony_ci free(buf); 260d96309c9Sopenharmony_ci close(fd); 261d96309c9Sopenharmony_ci FileClose(fp1); 262d96309c9Sopenharmony_ci FileClose(fp2); 263d96309c9Sopenharmony_ci return 0; 264d96309c9Sopenharmony_ci} 265