112d44d9创建于 2023年8月14日历史提交
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstdio>
#include <ctime>
#include <sstream>

#include <sys/time.h>


#include "libbpf_logger.h"
#include "hhlog.h"

static constexpr int FILE_MODE = 0644;

std::unique_ptr<LIBBPFLogger> LIBBPFLogger::MakeUnique(const std::string& logFile, int logLevel)
{
    std::unique_ptr<LIBBPFLogger> logger {new(std::nothrow) LIBBPFLogger {logLevel}};
    if (logger == nullptr) {
        return nullptr;
    }
#if defined(BPF_LOGGER_DEBUG) || defined(BPF_LOGGER_INFO) || defined(BPF_LOGGER_WARN) ||   \
    defined(BPF_LOGGER_ERROR) || defined(BPF_LOGGER_FATAL)
    if (logger->OpenLogFile(logFile) != 0) {
        return nullptr;
    }
#endif
    return logger;
}

int LIBBPFLogger::Printf(int logLevel, const char* format, va_list args)
{
    HHLOGI(true, "current libbpf log level = %d, target level = %d", logLevel, logLevel_);
    if (logLevel > logLevel_) {
        return 0;
    }
#if defined(BPF_LOGGER_DEBUG) || defined(BPF_LOGGER_INFO) || defined(BPF_LOGGER_WARN) ||   \
    defined(BPF_LOGGER_ERROR) || defined(BPF_LOGGER_FATAL)
    return vdprintf(fd_, format, args);
#else
    return 0;
#endif
}

int LIBBPFLogger::OpenLogFile(const std::string& logFile)
{
    if (logFile.compare("stdout") == 0) {
        if (fcntl(STDOUT_FILENO, F_GETFL)) {
            fd_ = open("/dev/stdout", O_WRONLY);
        } else {
            fd_ = STDOUT_FILENO;
        }
        if (fd_ < 0) {
            return -1;
        }
        return 0;
    }
    auto fileName = GetLogFileName();
    if (fileName.length() == 0) {
        return -1;
    }
    fileName = "/data/local/tmp/" + fileName;
    fd_ = open(fileName.c_str(), O_WRONLY | O_CREAT, FILE_MODE);
    if (fd_ < 0) {
        return -1;
    }
    unlink(logFile.c_str());
    if (link(fileName.c_str(), logFile.c_str()) != 0) {
        return -1;
    }

    return 0;
}

std::string LIBBPFLogger::GetLogFileName() const
{
    struct timeval timer;
    gettimeofday(&timer, nullptr);
    time_t now = (time_t) timer.tv_sec;
    struct tm* tmPtr {nullptr};
    tmPtr = localtime(&now);
    CHECK_NOTNULL(tmPtr, "", "GetLogFileName fail");
    std::stringstream ss;
    constexpr int yearStart {1900};
    constexpr int monthStart {1};
    ss << std::to_string(tmPtr->tm_year + yearStart) << ".";
    ss << std::to_string(tmPtr->tm_mon + monthStart) << ".";
    ss << std::to_string(tmPtr->tm_mday) << "_";
    ss << std::to_string(tmPtr->tm_hour) << ".";
    ss << std::to_string(tmPtr->tm_min) << ".";
    ss << std::to_string(tmPtr->tm_sec) << ".libbpf.log";
    return ss.str();
}