mirror of
https://gitee.com/openharmony/developtools_profiler
synced 2025-02-17 09:18:37 +00:00
!1168 修复hilog插件日志可能丢失,且不能过滤fatal级别日志的问题
Merge pull request !1168 from 集川/master
This commit is contained in:
commit
7dd9284383
@ -21,7 +21,6 @@ ohos_source_set("hiebpfplugin_source") {
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"${OHOS_PROFILER_DIR}/device/base/include",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
"//base/hiviewdfx/hilog/frameworks/native/include",
|
||||
]
|
||||
deps = [
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
|
@ -27,7 +27,6 @@ ohos_source_set("hilogplugin_source") {
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"${OHOS_PROFILER_DIR}/device/base/include",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
"//base/hiviewdfx/hilog/frameworks/native/include",
|
||||
]
|
||||
deps = [
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
|
@ -56,8 +56,6 @@ private:
|
||||
bool RemoveSpaces(char** p);
|
||||
bool FindFirstSpace(char** p);
|
||||
|
||||
static FILE* CustomPopen(const char* command, const char* type);
|
||||
static int CustomPclose(FILE* fp);
|
||||
bool StringToL(const char* word, long& value);
|
||||
// for ut
|
||||
void SetConfig(HilogConfig& config)
|
||||
@ -65,13 +63,8 @@ private:
|
||||
protoConfig_ = config;
|
||||
return;
|
||||
}
|
||||
std::string GetFullCmd()
|
||||
{
|
||||
return fullCmd_;
|
||||
}
|
||||
|
||||
template <typename T> void FlushData(const T hilogLineProto);
|
||||
|
||||
template <typename T> void FlushDataOptimize(const T hilogLineProto);
|
||||
|
||||
private:
|
||||
@ -79,15 +72,14 @@ private:
|
||||
std::vector<char> protoBuffer_;
|
||||
std::vector<char> dataBuffer_;
|
||||
WriterStruct* resultWriter_ = nullptr;
|
||||
|
||||
std::mutex mutex_;
|
||||
std::thread workThread_;
|
||||
std::atomic<bool> running_ = true;
|
||||
|
||||
std::string fullCmd_;
|
||||
|
||||
std::unique_ptr<FILE, int (*)(FILE*)> fp_;
|
||||
std::vector<std::string> fullCmd_;
|
||||
std::unique_ptr<FILE, std::function<int (FILE*)>> fp_;
|
||||
std::unique_ptr<FileCache> fileCache_ = nullptr;
|
||||
int pipeFds_[2] = {-1, -1};
|
||||
volatile pid_t childPid_ = -1;
|
||||
};
|
||||
|
||||
#endif // !HILOG_PLUGIN_H
|
@ -36,15 +36,12 @@ const int TIME_SEC_WIDTH = 14;
|
||||
const int TIME_NS_WIDTH = 24;
|
||||
const int FILE_NAME_LEN = 15;
|
||||
const int TIME_BUFF_LEN = 32;
|
||||
const int BUF_MAX_LEN = 512;
|
||||
const int PIPE_SIZE_RATIO = 8;
|
||||
const int BYTE_BUFFER_SIZE = 1024;
|
||||
const int BASE_YEAR = 1900;
|
||||
const int MAX_BUFFER_LEN = 8192;
|
||||
const std::string DEFAULT_LOG_PATH("/data/local/tmp/");
|
||||
FileCache g_fileCache(DEFAULT_LOG_PATH);
|
||||
static pid_t volatile g_child;
|
||||
const int READ = 0;
|
||||
const int WRITE = 1;
|
||||
const int PIPE_LEN = 2;
|
||||
const std::string BIN_COMMAND("/system/bin/hilog");
|
||||
} // namespace
|
||||
|
||||
@ -75,11 +72,11 @@ int HilogPlugin::Start(const uint8_t* configData, uint32_t configSize)
|
||||
{
|
||||
CHECK_TRUE(protoConfig_.ParseFromArray(configData, configSize) > 0, -1, "HilogPlugin: ParseFromArray failed");
|
||||
if (protoConfig_.need_clear()) {
|
||||
fullCmd_ = "hilog -r";
|
||||
std::vector<std::string> cmdArg;
|
||||
COMMON::SplitString(fullCmd_, " ", cmdArg);
|
||||
cmdArg.emplace(cmdArg.begin(), BIN_COMMAND);
|
||||
|
||||
cmdArg.emplace_back(BIN_COMMAND); // exe file path
|
||||
cmdArg.emplace_back("hilog"); // exe file name
|
||||
cmdArg.emplace_back("-r");
|
||||
volatile pid_t childPid = -1;
|
||||
int pipeFds[2] = {-1, -1};
|
||||
FILE* fp = COMMON::CustomPopen(cmdArg, "r", pipeFds, childPid);
|
||||
@ -88,8 +85,11 @@ int HilogPlugin::Start(const uint8_t* configData, uint32_t configSize)
|
||||
}
|
||||
|
||||
InitHilogCmd();
|
||||
fp_ = std::unique_ptr<FILE, int (*)(FILE*)>(CustomPopen(fullCmd_.c_str(), "r"), CustomPclose);
|
||||
CHECK_NOTNULL(fp_.get(), -1, "HilogPlugin: open(%s) Failed, errno(%d)", fullCmd_.c_str(), errno);
|
||||
fp_ = std::unique_ptr<FILE, std::function<int (FILE*)>>(
|
||||
COMMON::CustomPopen(fullCmd_, "r", pipeFds_, childPid_, true), [this](FILE* fp) -> int {
|
||||
return COMMON::CustomPclose(fp, pipeFds_, childPid_, true);
|
||||
});
|
||||
|
||||
if (protoConfig_.need_record()) {
|
||||
OpenLogFile();
|
||||
}
|
||||
@ -101,6 +101,12 @@ int HilogPlugin::Start(const uint8_t* configData, uint32_t configSize)
|
||||
std::unique_lock<std::mutex> locker(mutex_);
|
||||
running_ = true;
|
||||
locker.unlock();
|
||||
|
||||
int oldPipeSize = fcntl(fileno(fp_.get()), F_GETPIPE_SZ);
|
||||
fcntl(fileno(fp_.get()), F_SETPIPE_SZ, oldPipeSize * PIPE_SIZE_RATIO);
|
||||
int pipeSize = fcntl(fileno(fp_.get()), F_GETPIPE_SZ);
|
||||
HILOG_INFO(LOG_CORE, "{fp = %d, pipeSize=%d, oldPipeSize=%d}", fileno(fp_.get()), pipeSize, oldPipeSize);
|
||||
|
||||
workThread_ = std::thread(&HilogPlugin::Run, this);
|
||||
|
||||
return 0;
|
||||
@ -111,10 +117,15 @@ int HilogPlugin::Stop()
|
||||
HILOG_INFO(LOG_CORE, "HilogPlugin: ready stop thread!");
|
||||
std::unique_lock<std::mutex> locker(mutex_);
|
||||
running_ = false;
|
||||
COMMON::CustomPUnblock(pipeFds_);
|
||||
locker.unlock();
|
||||
if (workThread_.joinable()) {
|
||||
workThread_.join();
|
||||
}
|
||||
if (protoConfig_.need_record() && !dataBuffer_.empty()) {
|
||||
g_fileCache.Write(dataBuffer_.data(), dataBuffer_.size());
|
||||
dataBuffer_.erase(dataBuffer_.begin(), dataBuffer_.end());
|
||||
}
|
||||
HILOG_INFO(LOG_CORE, "HilogPlugin: stop thread success!");
|
||||
if (protoConfig_.need_record()) {
|
||||
g_fileCache.Close();
|
||||
@ -140,15 +151,6 @@ bool HilogPlugin::OpenLogFile()
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::string HilogPlugin::GetPidCmd()
|
||||
{
|
||||
std::string pidCmd = "";
|
||||
if (protoConfig_.pid() > 0) {
|
||||
pidCmd = std::to_string(protoConfig_.pid());
|
||||
}
|
||||
return pidCmd;
|
||||
}
|
||||
|
||||
std::string HilogPlugin::GetlevelCmd()
|
||||
{
|
||||
std::string levelCmd = "";
|
||||
@ -165,6 +167,9 @@ std::string HilogPlugin::GetlevelCmd()
|
||||
case WARN:
|
||||
levelCmd = "W";
|
||||
break;
|
||||
case FATAL:
|
||||
levelCmd = "F";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -174,24 +179,26 @@ std::string HilogPlugin::GetlevelCmd()
|
||||
|
||||
void HilogPlugin::InitHilogCmd()
|
||||
{
|
||||
fullCmd_ = "hilog";
|
||||
if (GetPidCmd().length() > 0) {
|
||||
fullCmd_ += " -P ";
|
||||
fullCmd_ += GetPidCmd();
|
||||
fullCmd_.emplace_back(BIN_COMMAND); // exe file path
|
||||
fullCmd_.emplace_back("hilog"); // exe file name
|
||||
|
||||
if (protoConfig_.pid() > 0) {
|
||||
fullCmd_.emplace_back("-P");
|
||||
fullCmd_.emplace_back(std::to_string(protoConfig_.pid()));
|
||||
}
|
||||
if (GetlevelCmd().length() > 0) {
|
||||
fullCmd_ += " -L ";
|
||||
fullCmd_ += GetlevelCmd();
|
||||
fullCmd_.emplace_back("-L");
|
||||
fullCmd_.emplace_back(GetlevelCmd());
|
||||
}
|
||||
|
||||
fullCmd_ = fullCmd_ + std::string(" --format nsec");
|
||||
HILOG_INFO(LOG_CORE, "HilogPlugin: hilog cmd(%s)", fullCmd_.c_str());
|
||||
fullCmd_.emplace_back("--format");
|
||||
fullCmd_.emplace_back("nsec");
|
||||
}
|
||||
|
||||
void HilogPlugin::Run(void)
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "HilogPlugin::Run start!");
|
||||
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(BUF_MAX_LEN);
|
||||
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(MAX_BUFFER_LEN);
|
||||
|
||||
std::unique_ptr<HilogInfo> dataProto = nullptr;
|
||||
std::unique_ptr<ProtoEncoder::HilogInfo> hilogInfo = nullptr;
|
||||
@ -200,12 +207,16 @@ void HilogPlugin::Run(void)
|
||||
} else {
|
||||
hilogInfo = std::make_unique<ProtoEncoder::HilogInfo>(resultWriter_->startReport(resultWriter_));
|
||||
}
|
||||
fcntl(fileno(fp_.get()), F_SETFL, O_NONBLOCK);
|
||||
|
||||
while (running_) {
|
||||
if (fgets(reinterpret_cast<char*>(buffer.get()), BUF_MAX_LEN - 1, fp_.get()) == nullptr) {
|
||||
if (fgets(reinterpret_cast<char*>(buffer.get()), MAX_BUFFER_LEN - 1, fp_.get()) == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((strlen(reinterpret_cast<char*>(buffer.get())) + 1) == (MAX_BUFFER_LEN - 1)) {
|
||||
HILOG_ERROR(LOG_CORE, "HilogPlugin:data length is greater than the MAX_BUFFER_LEN(%d)", MAX_BUFFER_LEN);
|
||||
}
|
||||
|
||||
auto cptr = reinterpret_cast<char*>(buffer.get());
|
||||
if (resultWriter_->isProtobufSerialize) {
|
||||
ParseLogLineData(cptr, strlen(cptr), dataProto.get());
|
||||
@ -238,11 +249,6 @@ void HilogPlugin::Run(void)
|
||||
FlushDataOptimize(hilogInfo.get());
|
||||
hilogInfo.reset();
|
||||
}
|
||||
|
||||
if (protoConfig_.need_record() && !dataBuffer_.empty()) {
|
||||
g_fileCache.Write(dataBuffer_.data(), dataBuffer_.size());
|
||||
dataBuffer_.erase(dataBuffer_.begin(), dataBuffer_.end());
|
||||
}
|
||||
HILOG_INFO(LOG_CORE, "HilogPlugin::Run done!");
|
||||
}
|
||||
|
||||
@ -459,76 +465,6 @@ int HilogPlugin::GetDateTime(char* psDateTime, uint32_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE* HilogPlugin::CustomPopen(const char* command, const char* type)
|
||||
{
|
||||
CHECK_TRUE(command != nullptr && type != nullptr, nullptr, "HilogPlugin:%s param invalid", __func__);
|
||||
|
||||
int fd[PIPE_LEN];
|
||||
pipe(fd);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// child process
|
||||
if (pid == 0) {
|
||||
if (!strncmp(type, "r", strlen(type))) {
|
||||
close(fd[READ]);
|
||||
dup2(fd[WRITE], 1); // Redirect stdout to pipe
|
||||
dup2(fd[WRITE], 2); // 2: Redirect stderr to pipe
|
||||
} else {
|
||||
close(fd[WRITE]);
|
||||
dup2(fd[READ], 0); // Redirect stdin to pipe
|
||||
}
|
||||
setpgid(pid, pid);
|
||||
std::vector<std::string> cmdArg;
|
||||
COMMON::SplitString(std::string(command), " ", cmdArg);
|
||||
std::vector<char*> vectArgv;
|
||||
for (auto& item : cmdArg) {
|
||||
vectArgv.push_back(const_cast<char*>(item.c_str()));
|
||||
}
|
||||
// execv : the last argv must be nullptr.
|
||||
vectArgv.push_back(nullptr);
|
||||
execv(BIN_COMMAND.c_str(), &vectArgv[0]);
|
||||
exit(0);
|
||||
} else {
|
||||
if (!strncmp(type, "r", strlen(type))) {
|
||||
// Close the WRITE end of the pipe since parent's fd is read-only
|
||||
close(fd[WRITE]);
|
||||
} else {
|
||||
// Close the READ end of the pipe since parent's fd is write-only
|
||||
close(fd[READ]);
|
||||
}
|
||||
}
|
||||
|
||||
g_child = pid;
|
||||
|
||||
if (!strncmp(type, "r", strlen(type))) {
|
||||
return fdopen(fd[READ], "r");
|
||||
}
|
||||
|
||||
return fdopen(fd[WRITE], "w");
|
||||
}
|
||||
|
||||
int HilogPlugin::CustomPclose(FILE* fp)
|
||||
{
|
||||
CHECK_NOTNULL(fp, -1, "HilogPlugin:%s fp is null", __func__);
|
||||
int stat;
|
||||
|
||||
int ret = fclose(fp);
|
||||
CHECK_TRUE(ret == 0, -1, "HilogPlugin:%s fclose failed! errno(%d)", __func__, errno);
|
||||
kill(g_child, SIGKILL);
|
||||
if (waitpid(g_child, &stat, 0) == -1) {
|
||||
if (errno != EINTR) {
|
||||
stat = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
template <typename T> void HilogPlugin::FlushData(const T hilogLineProto)
|
||||
{
|
||||
protoBuffer_.resize(hilogLineProto->ByteSizeLong());
|
||||
|
@ -159,64 +159,6 @@ uint64_t GetSec(HilogPlugin& plugin, const char* data)
|
||||
return mktime(&tmTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test valid full cmd
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestValidFullCmd, TestSize.Level1)
|
||||
{
|
||||
HilogConfig config;
|
||||
HilogPlugin plugin;
|
||||
|
||||
plugin.SetConfig(config);
|
||||
plugin.InitHilogCmd();
|
||||
EXPECT_STRNE(plugin.GetFullCmd().c_str(), "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test InitHilogCmd
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestInitHilogCmd, TestSize.Level1)
|
||||
{
|
||||
HilogConfig config;
|
||||
HilogPlugin plugin;
|
||||
int32_t pid = 1;
|
||||
|
||||
config.set_pid(pid);
|
||||
config.set_log_level(Level::ERROR);
|
||||
plugin.SetConfig(config);
|
||||
plugin.InitHilogCmd();
|
||||
|
||||
std::string target;
|
||||
target = "hilog -P " + std::to_string(pid) + " -L E --format nsec";
|
||||
EXPECT_STREQ(plugin.GetFullCmd().c_str(), target.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test InitHilogCmd with clear
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestInitHilogCmdClear, TestSize.Level1)
|
||||
{
|
||||
HilogConfig config;
|
||||
HilogPlugin plugin;
|
||||
int32_t pid = 1;
|
||||
|
||||
config.set_pid(pid);
|
||||
config.set_log_level(Level::ERROR);
|
||||
config.set_need_clear(true);
|
||||
plugin.SetConfig(config);
|
||||
plugin.InitHilogCmd();
|
||||
|
||||
std::string target;
|
||||
target = "hilog -P " + std::to_string(pid) + " -L E --format nsec";
|
||||
EXPECT_STREQ(plugin.GetFullCmd().c_str(), target.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test valid level cmd
|
||||
@ -845,85 +787,7 @@ HWTEST_F(HilogPluginTest, TestRemoveSpaces5, TestSize.Level1)
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test CustomPopen
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestCustomPopen, TestSize.Level1)
|
||||
{
|
||||
HilogPlugin plugin;
|
||||
const char* cmd = nullptr;
|
||||
const char* type = nullptr;
|
||||
|
||||
EXPECT_EQ(plugin.CustomPopen(cmd, type), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test CustomPopen write
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestCustomPopenNullW, TestSize.Level1)
|
||||
{
|
||||
HilogPlugin plugin;
|
||||
const char* cmd = "";
|
||||
const char* type = "w";
|
||||
FILE* fp = plugin.CustomPopen(cmd, type);
|
||||
|
||||
EXPECT_NE(fp, nullptr);
|
||||
plugin.CustomPclose(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test CustomPopen write
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestCustomPopenW, TestSize.Level1)
|
||||
{
|
||||
HilogPlugin plugin;
|
||||
const char* cmd = "echo this is a test!";
|
||||
const char* type = "w";
|
||||
FILE* fp = plugin.CustomPopen(cmd, type);
|
||||
|
||||
EXPECT_NE(fp, nullptr);
|
||||
plugin.CustomPclose(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test CustomPopen read
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestCustomPopenNullR, TestSize.Level1)
|
||||
{
|
||||
HilogPlugin plugin;
|
||||
const char* cmd = "";
|
||||
const char* type = "r";
|
||||
FILE* fp = plugin.CustomPopen(cmd, type);
|
||||
|
||||
EXPECT_NE(fp, nullptr);
|
||||
plugin.CustomPclose(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test CustomPopen read
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestCustomPopenR, TestSize.Level1)
|
||||
{
|
||||
HilogPlugin plugin;
|
||||
const char* cmd = "ls";
|
||||
const char* type = "r";
|
||||
FILE* fp = plugin.CustomPopen(cmd, type);
|
||||
|
||||
EXPECT_NE(fp, nullptr);
|
||||
plugin.CustomPclose(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: hilog plugin
|
||||
* @tc.desc: Test CustomPopen write
|
||||
* @tc.desc: Test write
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HilogPluginTest, TestFileOperation, TestSize.Level1)
|
||||
|
@ -26,7 +26,6 @@ ohos_source_set("hisyseventplugin_source") {
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"${OHOS_PROFILER_DIR}/device/base/include",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
"//base/hiviewdfx/hilog/frameworks/native/include",
|
||||
]
|
||||
deps = [
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
|
@ -26,6 +26,7 @@ enum Level {
|
||||
INFO = 2;
|
||||
DEBUG = 3;
|
||||
WARN = 4;
|
||||
FATAL = 5;
|
||||
}
|
||||
|
||||
message HilogConfig {
|
||||
|
Loading…
x
Reference in New Issue
Block a user