• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <cstdio>
17 #include <ctime>
18 #include <sstream>
19 
20 #include <sys/time.h>
21 
22 
23 #include "libbpf_logger.h"
24 #include "hhlog.h"
25 
26 static constexpr int FILE_MODE = 0644;
27 
MakeUnique(const std::string & logFile,int logLevel)28 std::unique_ptr<LIBBPFLogger> LIBBPFLogger::MakeUnique(const std::string& logFile, int logLevel)
29 {
30     std::unique_ptr<LIBBPFLogger> logger {new(std::nothrow) LIBBPFLogger {logLevel}};
31     if (logger == nullptr) {
32         return nullptr;
33     }
34 #if defined(BPF_LOGGER_DEBUG) || defined(BPF_LOGGER_INFO) || defined(BPF_LOGGER_WARN) ||   \
35     defined(BPF_LOGGER_ERROR) || defined(BPF_LOGGER_FATAL)
36     if (logger->OpenLogFile(logFile) != 0) {
37         return nullptr;
38     }
39 #endif
40     return logger;
41 }
42 
Printf(int logLevel,const char * format,va_list args)43 int LIBBPFLogger::Printf(int logLevel, const char* format, va_list args)
44 {
45     HHLOGI(true, "current libbpf log level = %d, target level = %d", logLevel, logLevel_);
46     if (logLevel > logLevel_) {
47         return 0;
48     }
49 #if defined(BPF_LOGGER_DEBUG) || defined(BPF_LOGGER_INFO) || defined(BPF_LOGGER_WARN) ||   \
50     defined(BPF_LOGGER_ERROR) || defined(BPF_LOGGER_FATAL)
51     return vdprintf(fd_, format, args);
52 #else
53     return 0;
54 #endif
55 }
56 
OpenLogFile(const std::string & logFile)57 int LIBBPFLogger::OpenLogFile(const std::string& logFile)
58 {
59     if (logFile.compare("stdout") == 0) {
60         if (fcntl(STDOUT_FILENO, F_GETFL)) {
61             fd_ = open("/dev/stdout", O_WRONLY);
62         } else {
63             fd_ = STDOUT_FILENO;
64         }
65         if (fd_ < 0) {
66             return -1;
67         }
68         return 0;
69     }
70     auto fileName = GetLogFileName();
71     if (fileName.length() == 0) {
72         return -1;
73     }
74     fileName = "/data/local/tmp/" + fileName;
75     fd_ = open(fileName.c_str(), O_WRONLY | O_CREAT, FILE_MODE);
76     if (fd_ < 0) {
77         return -1;
78     }
79     unlink(logFile.c_str());
80     if (link(fileName.c_str(), logFile.c_str()) != 0) {
81         return -1;
82     }
83 
84     return 0;
85 }
86 
GetLogFileName() const87 std::string LIBBPFLogger::GetLogFileName() const
88 {
89     struct timeval timer;
90     gettimeofday(&timer, nullptr);
91     time_t now = (time_t) timer.tv_sec;
92     struct tm* tmPtr {nullptr};
93     tmPtr = localtime(&now);
94     CHECK_NOTNULL(tmPtr, "", "GetLogFileName fail");
95     std::stringstream ss;
96     constexpr int yearStart {1900};
97     constexpr int monthStart {1};
98     ss << std::to_string(tmPtr->tm_year + yearStart) << ".";
99     ss << std::to_string(tmPtr->tm_mon + monthStart) << ".";
100     ss << std::to_string(tmPtr->tm_mday) << "_";
101     ss << std::to_string(tmPtr->tm_hour) << ".";
102     ss << std::to_string(tmPtr->tm_min) << ".";
103     ss << std::to_string(tmPtr->tm_sec) << ".libbpf.log";
104     return ss.str();
105 }