Yyuhaoqiang告警清理
b3761673创建于 11 天前历史提交
/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * 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 "kernel_snapshot_task.h"

#include <dlfcn.h>
#include <fcntl.h>
#include <string>

#include "dfx_log.h"
#include "parameters.h"
#include "smart_fd.h"
#include "dfx_util.h"

namespace OHOS {
namespace HiviewDFX {

namespace {
std::string ReadKernelSnapshot()
{
#ifdef FAULTLOGGERD_TEST
    constexpr auto kernelKboxSnapshot = "/data/test/resource/testdata/kernel_snapshot_execption.txt";
#else
    constexpr auto kernelKboxSnapshot = "/sys/kbox/snapshot_clear";
#endif
    SmartFd fd(open(kernelKboxSnapshot, O_RDONLY));
    if (!fd) {
        DFXLOGE("open snapshot %{public}s failed %{public}d", kernelKboxSnapshot, errno);
        return "";
    }
    constexpr int buffLength = 1024;
    char buffer[buffLength] = {0};
    std::string snapshotCont;
    ssize_t ret = 0;
    do {
        ret = read(fd.GetFd(), buffer, buffLength - 1);
        if (ret > 0) {
            snapshotCont.append(buffer, static_cast<size_t>(ret));
        }
        if (ret < 0) {
            DFXLOGE("read snapshot failed %{public}d", errno);
        }
    } while (ret > 0);
    return snapshotCont;
}
}

ReadKernelSnapshotTask::ReadKernelSnapshotTask()
{
    constexpr int minInterval = 3;
    constexpr auto kernelSnapshotInterval = "kernel_snapshot_check_interval";
    // Read snapshot interval log version is 1 minute, nolog version is 5 minutes.
    int defaultInterval = OHOS::HiviewDFX::IsBetaVersion() ? 60 : 300;
    int interval = std::max(system::GetIntParameter(kernelSnapshotInterval, defaultInterval), minInterval);
#ifdef FAULTLOGGERD_TEST
    SetTimeOption(minInterval, interval);
#else
    SetTimeOption(interval, interval);
#endif
}

bool ReadKernelSnapshotTask::OnTimer()
{
    const std::string snapshotCont = ReadKernelSnapshot();
    if (snapshotCont.empty()) {
        DFXLOGD("the snapshot file does not exist or is empty.");
        return true;
    }
    DFXLOGI("read snapshot begin with %{public}s", snapshotCont.substr(0, 25).c_str()); // 25 : only need 25
    constexpr auto kernelSnapshotLibraryName = "libkernel_snapshot.z.so";
    void* handle = dlopen(kernelSnapshotLibraryName, RTLD_LAZY);
    if (handle == nullptr) {
        DFXLOGE("failed dlopen library %{public}s for error %{public}d", kernelSnapshotLibraryName, errno);
        return true;
    }
    constexpr auto methodName = "ProcessKernelSnapShot";
    auto processKernelSnapShot = reinterpret_cast<void (*)(const std::string&)>(dlsym(handle, methodName));
    if (processKernelSnapShot == nullptr) {
        DFXLOGE("can't find method %{public}s in %{public}s, just exit", methodName, kernelSnapshotLibraryName);
        dlclose(handle);
        return true;
    }
    processKernelSnapShot(snapshotCont);
    dlclose(handle);
    return true;
}
}
}