* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This file is part of the MindStudio project.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------*/
#include "analysis/csrc/application/timeline/host_usage_assembler.h"
#include <unordered_map>
#include "analysis/csrc/domain/services/environment/context.h"
namespace Analysis
{
namespace Application
{
using namespace Analysis::Application;
using namespace Analysis::Infra;
using namespace Analysis::Domain::Environment;
using namespace Analysis::Utils;
namespace
{
const std::string USAGE = "Usage(%)";
}
OSRuntimeApiAssembler::OSRuntimeApiAssembler() : HostUsageAssembler(PROCESS_OS_RUNTIME_API) {}
uint8_t OSRuntimeApiAssembler::GenerateDataTrace(DataInventory &dataInventory, uint32_t pid)
{
auto runtimeApiData = dataInventory.GetPtr<std::vector<OSRuntimeApiData>>();
if (runtimeApiData == nullptr)
{
WARN("Can't get host runtime api data from dataInventory.");
return DATA_NOT_EXIST;
}
std::set<int> tidMap;
double dur;
std::shared_ptr<DurationEvent> event;
for (const auto &data : *runtimeApiData)
{
dur = static_cast<double>(data.endTime - data.timestamp) / Analysis::Common::NS_TO_US;
MAKE_SHARED_RETURN_VALUE(event, DurationEvent, ASSEMBLE_FAILED, pid, static_cast<int>(data.tid), dur,
DivideByPowersOfTenWithPrecision(data.timestamp), data.name);
res_.push_back(event);
tidMap.insert(static_cast<int>(data.tid));
}
std::shared_ptr<MetaDataNameEvent> threadNameEvent;
for (const auto &tid : tidMap)
{
MAKE_SHARED_RETURN_VALUE(threadNameEvent, MetaDataNameEvent, ASSEMBLE_FAILED, pid, tid, META_DATA_THREAD_NAME,
"Thread " + std::to_string(tid));
res_.push_back(threadNameEvent);
}
return ASSEMBLE_SUCCESS;
}
NetworkUsageAssembler::NetworkUsageAssembler() : HostUsageAssembler(PROCESS_NETWORK_USAGE) {}
uint8_t NetworkUsageAssembler::GenerateDataTrace(DataInventory &dataInventory, uint32_t pid)
{
auto usageData = dataInventory.GetPtr<std::vector<NetWorkUsageData>>();
if (usageData == nullptr)
{
WARN("Can't get host network data from dataInventory.");
return DATA_NOT_EXIST;
}
std::shared_ptr<CounterEvent> event;
for (const auto &data : *usageData)
{
MAKE_SHARED_RETURN_VALUE(event, CounterEvent, ASSEMBLE_FAILED, pid, DEFAULT_TID,
DivideByPowersOfTenWithPrecision(data.timestamp), "Network Usage");
event->SetSeriesDValue(USAGE, data.usage);
res_.push_back(event);
}
return ASSEMBLE_SUCCESS;
}
DiskUsageAssembler::DiskUsageAssembler() : HostUsageAssembler(PROCESS_DISK_USAGE) {}
uint8_t DiskUsageAssembler::GenerateDataTrace(DataInventory &dataInventory, uint32_t pid)
{
auto usageData = dataInventory.GetPtr<std::vector<DiskUsageData>>();
if (usageData == nullptr)
{
WARN("Can't get host disk data from dataInventory.");
return DATA_NOT_EXIST;
}
std::shared_ptr<CounterEvent> event;
for (const auto &data : *usageData)
{
MAKE_SHARED_RETURN_VALUE(event, CounterEvent, ASSEMBLE_FAILED, pid, DEFAULT_TID,
DivideByPowersOfTenWithPrecision(data.timestamp), "Disk Usage");
event->SetSeriesDValue(USAGE, data.usage);
res_.push_back(event);
}
return ASSEMBLE_SUCCESS;
}
MemUsageAssembler::MemUsageAssembler() : HostUsageAssembler(PROCESS_MEMORY_USAGE) {}
uint8_t MemUsageAssembler::GenerateDataTrace(DataInventory &dataInventory, uint32_t pid)
{
auto usageData = dataInventory.GetPtr<std::vector<MemUsageData>>();
if (usageData == nullptr)
{
WARN("Can't get host memory data from dataInventory");
return DATA_NOT_EXIST;
}
std::shared_ptr<CounterEvent> event;
for (const auto &data : *usageData)
{
MAKE_SHARED_RETURN_VALUE(event, CounterEvent, ASSEMBLE_FAILED, pid, DEFAULT_TID,
DivideByPowersOfTenWithPrecision(data.timestamp), "Memory Usage");
event->SetSeriesDValue(USAGE, data.usage);
res_.push_back(event);
}
return ASSEMBLE_SUCCESS;
}
CpuUsageAssembler::CpuUsageAssembler() : HostUsageAssembler(PROCESS_CPU_USAGE) {}
uint8_t CpuUsageAssembler::GenerateDataTrace(DataInventory &dataInventory, uint32_t pid)
{
auto usageData = dataInventory.GetPtr<std::vector<CpuUsageData>>();
if (usageData == nullptr)
{
WARN("Can't get host cpu data from dataInventory");
return DATA_NOT_EXIST;
}
std::shared_ptr<CounterEvent> event;
for (const auto &data : *usageData)
{
MAKE_SHARED_RETURN_VALUE(event, CounterEvent, ASSEMBLE_FAILED, pid, DEFAULT_TID,
DivideByPowersOfTenWithPrecision(data.timestamp), "CPU " + data.cpuNo);
event->SetSeriesDValue(USAGE, data.usage);
res_.push_back(event);
}
return ASSEMBLE_SUCCESS;
}
HostUsageAssembler::HostUsageAssembler(const std::string &assembleName)
: JsonAssembler(assembleName, {{MSPROF_JSON_FILE, FileCategory::MSPROF}})
{
}
uint8_t HostUsageAssembler::AssembleData(DataInventory &dataInventory, JsonWriter &ostream, const std::string &profPath)
{
INFO("Begin to assemble % data.", processorName_);
auto layerInfo = GetLayerInfo(processorName_);
auto pid = Context::GetInstance().GetPidFromInfoJson(HOST_ID, profPath);
auto formatPid = JsonAssembler::GetFormatPid(pid, layerInfo.sortIndex);
auto generateFlag = GenerateDataTrace(dataInventory, formatPid);
if (generateFlag != ASSEMBLE_SUCCESS)
{
return generateFlag;
}
if (res_.empty())
{
ERROR("Can't Generate any % data.", processorName_);
return ASSEMBLE_FAILED;
}
std::unordered_map<uint16_t, uint32_t> pidMap = {{HOST_ID, formatPid}};
GenerateHWMetaData(pidMap, layerInfo, res_);
for (const auto &node : res_)
{
node->DumpJson(ostream);
}
ostream << ",";
INFO("Assemble % data success.", processorName_);
return ASSEMBLE_SUCCESS;
}
}
}