From dd15e1277c9a6d3c00b19e2a60662abdfed4ca76 Mon Sep 17 00:00:00 2001 From: chenwei Date: Tue, 13 Jun 2023 19:36:57 +0800 Subject: [PATCH 1/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- bundle.json | 3 +- frameworks/hitrace_ndk/BUILD.gn | 29 ++ frameworks/hitrace_ndk/hitrace_meter_ndk.c | 41 ++ frameworks/include/hitrace_meter_wrapper.h | 40 ++ interfaces/native/innerkits/BUILD.gn | 6 +- .../innerkits/src/hitrace_meter_wrapper.cpp | 50 ++ interfaces/native/kits/BUILD.gn | 26 ++ .../native/kits/include/hitrace/trace.h | 138 ++++++ interfaces/native/kits/libhitrace.ndk.json | 17 + test/BUILD.gn | 29 ++ .../hitrace_meter/hitrace_capi_test.cpp | 439 ++++++++++++++++++ 11 files changed, 816 insertions(+), 2 deletions(-) create mode 100644 frameworks/hitrace_ndk/BUILD.gn create mode 100644 frameworks/hitrace_ndk/hitrace_meter_ndk.c create mode 100644 frameworks/include/hitrace_meter_wrapper.h create mode 100644 interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp create mode 100644 interfaces/native/kits/BUILD.gn create mode 100644 interfaces/native/kits/include/hitrace/trace.h create mode 100644 interfaces/native/kits/libhitrace.ndk.json create mode 100644 test/unittest/hitrace_meter/hitrace_capi_test.cpp diff --git a/bundle.json b/bundle.json index 7598a37..225debe 100644 --- a/bundle.json +++ b/bundle.json @@ -40,7 +40,8 @@ "//base/hiviewdfx/hitrace/interfaces/native/innerkits:libhitracechain", "//base/hiviewdfx/hitrace/interfaces/js/kits:hitrace_napi", "//base/hiviewdfx/hitrace/interfaces/rust/innerkits/hitracechain:hitracechain_rust", - "//base/hiviewdfx/hitrace/interfaces/rust/innerkits/hitrace_meter:hitrace_meter_rust" + "//base/hiviewdfx/hitrace/interfaces/rust/innerkits/hitrace_meter:hitrace_meter_rust", + "//base/hiviewdfx/hitrace/frameworks/hitrace_ndk:hitrace_ndk" ], "inner_kits": [ { diff --git a/frameworks/hitrace_ndk/BUILD.gn b/frameworks/hitrace_ndk/BUILD.gn new file mode 100644 index 0000000..86dfa76 --- /dev/null +++ b/frameworks/hitrace_ndk/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +ohos_shared_library("hitrace_ndk") { + include_dirs = [ + "../include/", + "../../interfaces/native/kits/include/", + ] + + sources = [ "hitrace_meter_ndk.c" ] + + deps = [ "../../interfaces/native/innerkits:hitrace_meter" ] + + innerapi_tags = [ "ndk" ] + part_name = "hitrace_native" + subsystem_name = "hiviewdfx" +} diff --git a/frameworks/hitrace_ndk/hitrace_meter_ndk.c b/frameworks/hitrace_ndk/hitrace_meter_ndk.c new file mode 100644 index 0000000..26656e3 --- /dev/null +++ b/frameworks/hitrace_ndk/hitrace_meter_ndk.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-2022 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 "hitrace_meter_wrapper.h" + +void OH_HiTrace_StartTrace(const char *name) +{ + StartTraceCwrapper(name); +} + +void OH_HiTrace_FinishTrace() +{ + FinishTraceCwrapper(); +} + +void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId) +{ + StartAsyncTraceCwrapper(name, taskId); +} + +void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId) +{ + FinishAsyncTraceCwrapper(name, taskId); +} + +void OH_HiTrace_CountTrace(const char *name, int64_t count) +{ + CountTraceCwrapper(name, count); +} \ No newline at end of file diff --git a/frameworks/include/hitrace_meter_wrapper.h b/frameworks/include/hitrace_meter_wrapper.h new file mode 100644 index 0000000..21c46fa --- /dev/null +++ b/frameworks/include/hitrace_meter_wrapper.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef HITRACE_METER_WRAPPER_H +#define HITRACE_METER_WRAPPER_H + +#include + +#include "hitrace/trace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void StartTraceCwrapper(const char *value); + +void FinishTraceCwrapper(); + +void StartAsyncTraceCwrapper(const char *value, int32_t taskId); + +void FinishAsyncTraceCwrapper(const char *value, int32_t taskId); + +void CountTraceCwrapper(const char *value, int64_t count); + +#ifdef __cplusplus +} +#endif +#endif /* HITRACE_METER_WRAPPER_H */ diff --git a/interfaces/native/innerkits/BUILD.gn b/interfaces/native/innerkits/BUILD.gn index 9b65867..234b4f4 100644 --- a/interfaces/native/innerkits/BUILD.gn +++ b/interfaces/native/innerkits/BUILD.gn @@ -51,11 +51,15 @@ config("hitrace_meter_config") { include_dirs = [ "include/hitrace_meter", "include", + "../../../frameworks/include/", ] } ohos_static_library("hitrace_inner") { - sources = [ "src/hitrace_meter.cpp" ] + sources = [ + "src/hitrace_meter.cpp", + "src/hitrace_meter_wrapper.cpp", + ] public_configs = [ ":hitrace_meter_config" ] external_deps = [ "hilog_native:libhilog", diff --git a/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp b/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp new file mode 100644 index 0000000..99ae56d --- /dev/null +++ b/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 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 "hitrace_meter_wrapper.h" +#include "hitrace_meter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void StartTraceCwrapper(const char *value) +{ + StartTrace(HITRACE_TAG_APP, value); +} + +void FinishTraceCwrapper() +{ + FinishTrace(HITRACE_TAG_APP); +} + +void StartAsyncTraceCwrapper(const char *value, int32_t taskId) +{ + StartAsyncTrace(HITRACE_TAG_APP, value, taskId); +} + +void FinishAsyncTraceCwrapper(const char *value, int32_t taskId) +{ + FinishAsyncTrace(HITRACE_TAG_APP, value, taskId); +} + +void CountTraceCwrapper(const char *value, int64_t count) +{ + CountTrace(HITRACE_TAG_APP, value, count); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/interfaces/native/kits/BUILD.gn b/interfaces/native/kits/BUILD.gn new file mode 100644 index 0000000..c48a187 --- /dev/null +++ b/interfaces/native/kits/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libhitrace_ndk") { + output_name = "hitrace_ndk" + ndk_description_file = "./libhitrace.ndk.json" + min_compact_version = "1" + system_capability = "SystemCapability.HiviewDFX.HiTrace" +} + +ohos_ndk_headers("hitrace_header") { + dest_dir = "$ndk_headers_out_dir/hitrace" + sources = [ "./include/hitrace/trace.h" ] +} diff --git a/interfaces/native/kits/include/hitrace/trace.h b/interfaces/native/kits/include/hitrace/trace.h new file mode 100644 index 0000000..771d1c8 --- /dev/null +++ b/interfaces/native/kits/include/hitrace/trace.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef HIVIEWDFX_HITRACE_H +#define HIVIEWDFX_HITRACE_H +/** + * @addtogroup Hitrace + * @{ + * + * @brief hiTraceMeter provides APIs for system performance trace. + * + * You can call the APIs provided by hiTraceMeter in your own service logic to effectively + * track service processes and check the system performance. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * + * @since 10 + */ + +/** + * @file trace.h + * + * @brief Defines APIs of the HiTraceMeter module for performance trace. + * + * Sample code:\n + * Synchronous timeslice trace event:\n + * OH_HiTrace_StartTrace("hitraceTest");\n + * OH_HiTrace_FinishTrace();\n + * Output: \n + * <...>-1668 (-------) [003] .... 135.059377: tracing_mark_write: B|1668|H:hitraceTest\n + * <...>-1668 (-------) [003] .... 135.059415: tracing_mark_write: E|1668|\n + * Asynchronous timeslice trace event:\n + * OH_HiTrace_StartAsyncTrace("hitraceTest", 123);\n + * OH_HiTrace_FinishAsyncTrace("hitraceTest", 123);\n + * Output: \n + * <...>-2477 (-------) [001] .... 396.427165: tracing_mark_write: S|2477|H:hitraceTest 123\n + * <...>-2477 (-------) [001] .... 396.427196: tracing_mark_write: F|2477|H:hitraceTest 123\n + * Integer value trace event:\n + * OH_HiTrace_CountTrace("hitraceTest", 500);\n + * Output: \n + * <...>-2638 (-------) [002] .... 458.904382: tracing_mark_write: C|2638|H:hitraceTest 500\n + * + * @since 10 + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Marks the start of a synchronous trace task. + * + * The OH_HiTrace_StartTrace and OH_HiTrace_FinishTrace APIs must be used in pairs. + * The two APIs can be used in nested mode. The stack data structure is used for matching during trace data parsing. + * + * @param name Name of a trace task. + * + * @since 10 + */ +void OH_HiTrace_StartTrace(const char *name); + +/** + * @brief Marks the end of a synchronous trace task. + * + * This API must be used with OH_HiTrace_StartTrace in pairs. During trace data parsing, the system matches + * it with the OH_HiTrace_StartTrace API recently invoked in the service process. + * + * @since 10 + */ +void OH_HiTrace_FinishTrace(void); + +/** + * @brief Marks the start of an asynchronous trace task. + * + * This API is called to implement performance trace in asynchronous manner. The start and end of an asynchronous + * trace task do not occur in sequence. Therefore, a unique taskId is required to ensure proper data parsing. + * It is passed as an input parameter for the asynchronous API. + * This API is used with OH_HiTrace_FinishAsyncTrace in pairs. The two APIs that have the same name and + * task ID together form an asynchronous timeslice trace task. + * If multiple trace tasks with the same name need to be performed at the same time or a trace task needs to be + * performed multiple times concurrently, different task IDs must be specified in OH_HiTrace_StartTrace. + * If the trace tasks with the same name are not performed at the same time, the same taskId can be used. + * + * @param name Name of the asynchronous trace task. + * @param taskId ID of the asynchronous trace task. The start and end of an asynchronous trace task do not occur in + * sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the + * unique task ID together. + * + * @since 10 + */ +void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); + +/** + * @brief Marks the end of an asynchronous trace task. + * + * This API is called in the callback function after an asynchronous trace is complete. + * It is used with OH_HiTrace_StartAsyncTrace in pairs. Its name and task ID must be the same as those of + * OH_HiTrace_StartAsyncTrace. + * + * @param name Name of the asynchronous trace task. + * @param taskId ID of the asynchronous trace task. The start and end of an asynchronous trace task do not occur in + * sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the + * unique task ID together. + * + * @since 10 + */ +void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); + +/** + * @brief Traces the value change of an integer variable based on its name. + * + * This API can be executed for multiple times to trace the value change of a given integer variable at different + * time points. + * + * @param name Name of the integer variable. It does not need to be the same as the real variable name. + * @param count Integer value. Generally, an integer variable can be passed. + * + * @since 10 + */ +void OH_HiTrace_CountTrace(const char *name, int64_t count); + +#ifdef __cplusplus +} +#endif +#endif // HIVIEWDFX_HITRACE_H diff --git a/interfaces/native/kits/libhitrace.ndk.json b/interfaces/native/kits/libhitrace.ndk.json new file mode 100644 index 0000000..accfdcd --- /dev/null +++ b/interfaces/native/kits/libhitrace.ndk.json @@ -0,0 +1,17 @@ +[ + { + "name": "OH_HiTrace_StartTrace" + }, + { + "name": "OH_HiTrace_FinishTrace" + }, + { + "name": "OH_HiTrace_StartAsyncTrace" + }, + { + "name": "OH_HiTrace_FinishAsyncTrace" + }, + { + "name": "OH_HiTrace_CountTrace" + } +] \ No newline at end of file diff --git a/test/BUILD.gn b/test/BUILD.gn index 0253f23..91fd05f 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -58,6 +58,35 @@ ohos_unittest("HitraceCppTest") { ] } +config("hitrace_capi_test_config") { + visibility = [ ":*" ] + + include_dirs = [ + ".", + "../interfaces/native/kits/include/", + ] +} + +ohos_unittest("HitraceCapiTest") { + module_out_path = module_output_path + + configs = [ ":hitrace_capi_test_config" ] + + sources = [ "./unittest/hitrace_meter/hitrace_capi_test.cpp" ] + + deps = [ + "../cmd:hitrace_osal_inner", + "../frameworks/hitrace_ndk:hitrace_ndk", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ + "c_utils:utils", + "hilog_native:libhilog", + "init:libbegetutil", + ] +} + config("HitraceNDKTest_config") { visibility = [ ":*" ] diff --git a/test/unittest/hitrace_meter/hitrace_capi_test.cpp b/test/unittest/hitrace_meter/hitrace_capi_test.cpp new file mode 100644 index 0000000..8b5c681 --- /dev/null +++ b/test/unittest/hitrace_meter/hitrace_capi_test.cpp @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2023 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 +#include +#include +#include +#include +#include +#include "securec.h" +#include "hitrace/trace.h" +#include "hitrace_osal.h" +#include "parameters.h" + +using namespace testing::ext; +using namespace std; +using namespace OHOS::HiviewDFX; +using namespace OHOS::HiviewDFX::HitraceOsal; + +#define EXPECTANTLY(exp) (__builtin_expect(!!(exp), true)) + +namespace OHOS { +namespace HiviewDFX { +namespace HitraceTest { +const string TRACE_MARKER_PATH = "trace_marker"; +const string TRACING_ON = "tracing_on"; +const string TRACE_MARK_WRITE = "tracing_mark_write"; +const string TRACE_PATH = "trace"; +const string TRACE_PATTERN = "\\s*(.*?)-(.*?)\\s+(.*?)\\[(\\d+?)\\]\\s+(.*?)\\s+((\\d+).(\\d+)?):\\s+" + + TRACE_MARK_WRITE + ": "; +const string TRACE_START = TRACE_PATTERN + "B\\|(.*?)\\|H:"; +const string TRACE_ASYNC_START = TRACE_PATTERN + "S\\|(.*?)\\|H:"; +const string TRACE_ASYNC_FINISH = TRACE_PATTERN + "F\\|(.*?)\\|H:"; +const string TRACE_COUNT = TRACE_PATTERN + "C\\|(.*?)\\|H:"; +const string TRACE_PROPERTY = "debug.hitrace.tags.enableflags"; +constexpr uint32_t TASK = 1; +constexpr uint32_t TGID = 3; +constexpr uint32_t TID = 2; +constexpr uint32_t CPU = 4; +constexpr uint32_t DNH2 = 5; +constexpr uint32_t TIMESTAMP = 6; +constexpr uint32_t PID = 9; +constexpr uint32_t NUM = 11; +constexpr uint32_t TRACE_NAME = 10; +constexpr uint32_t TRACE_FMA12 = 12; +constexpr uint32_t TRACE_FMA11 = 11; + +constexpr uint64_t HITRACE_TAG = 0xD002D33; +const constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HITRACE_TAG, "Hitrace_TEST"}; +const uint64_t TAG = (1ULL << 62); +static string g_traceRootPath; + +bool SetProperty(const string& property, const string& value); +string GetProperty(const string& property, const string& value); +bool CleanFtrace(); +bool CleanTrace(); +bool SetFtrace(const string& filename, bool enabled); + +class HitraceNDKTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown() {} // empty function +}; + +void HitraceNDKTest::SetUpTestCase() +{ + const string tracefsDir = "/sys/kernel/tracing/"; + const string debugfsDir = "/sys/kernel/debug/tracing/"; + if (access((debugfsDir + TRACE_MARKER_PATH).c_str(), F_OK) != -1) { + g_traceRootPath = debugfsDir; + } else if (access((tracefsDir + TRACE_MARKER_PATH).c_str(), F_OK) != -1) { + g_traceRootPath = tracefsDir; + } else { + HiLog::Error(LABEL, "Error: Finding trace folder failed."); + } + CleanFtrace(); +} + +void HitraceNDKTest::TearDownTestCase() +{ + SetFtrace(TRACING_ON, false); + SetProperty(TRACE_PROPERTY, "0"); + CleanTrace(); +} + +void HitraceNDKTest::SetUp() +{ + ASSERT_TRUE(CleanTrace()); + ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Setting tracing_on 1 failed."; + string value = to_string(TAG); + SetProperty(TRACE_PROPERTY, value); + HiLog::Info(LABEL, "current tag is %{public}s", GetProperty(TRACE_PROPERTY, "0").c_str()); + ASSERT_TRUE(GetProperty(TRACE_PROPERTY, "-123") == value); +} + +struct Param { + string mTask; + string mTid; + string mTgid; + string mCpu; + string mDnh2; + string mTimeStamp; + string mPid; + string mTraceName; + string mNum; +}; + +class MyTrace { + Param mParam; + bool mLoaded = false; +public: + MyTrace() : mLoaded(false) + { + mParam.mTask = ""; + mParam.mTid = ""; + mParam.mTgid = ""; + mParam.mCpu = ""; + mParam.mDnh2 = ""; + mParam.mTimeStamp = ""; + mParam.mPid = ""; + mParam.mTraceName = ""; + mParam.mNum = ""; + } + + ~MyTrace() + { + } + + // task-pid ( tig) [cpu] ...1 timestamp: tracing_mark_write: B|pid|traceName + // task-pid ( tig) [cpu] ...1 timestamp: tracing_mark_write: E|pid + void Load(const Param& param) + { + mParam.mTask = param.mTask; + mParam.mPid = param.mPid; + mParam.mTid = param.mTid; + mParam.mTgid = param.mTgid; + mParam.mCpu = param.mCpu; + mParam.mDnh2 = param.mDnh2; + mParam.mTimeStamp = param.mTimeStamp; + mParam.mTraceName = param.mTraceName; + mParam.mNum = param.mNum; + mLoaded = true; + } + + string GetTask() + { + return mParam.mTask; + } + + string GetPid() + { + if (mLoaded) { + return mParam.mPid; + } + return ""; + } + + string GetTgid() + { + if (mLoaded) { + return mParam.mTgid; + } + return ""; + } + + string GetCpu() + { + if (mLoaded) { + return mParam.mCpu; + } + return ""; + } + + string GetDnh2() + { + if (mLoaded) { + return mParam.mDnh2; + } + return ""; + } + + string GetTimestamp() + { + if (mLoaded) { + return mParam.mTimeStamp; + } + return ""; + } + + string GetTraceName() + { + if (mLoaded) { + return mParam.mTraceName; + } + return ""; + } + + string GetNum() + { + if (mLoaded) { + return mParam.mNum; + } + return ""; + } + + string GetTid() + { + if (mLoaded) { + return mParam.mTid; + } + return ""; + } + + bool IsLoaded() const + { + return mLoaded; + } +}; + +string GetProperty(const string& property, const string& value) +{ + return OHOS::system::GetParameter(property, value); +} + +bool SetProperty(const string& property, const string& value) +{ + bool result = false; + result = OHOS::system::SetParameter(property, value); + if (!result) { + // SetParameter failed + HiLog::Error(LABEL, "Error: setting %s failed", property.c_str()); + return false; + } + return true; +} + +MyTrace GetTraceResult(const string& checkContent, const vector& list) +{ + MyTrace trace; + if (list.empty() || checkContent.empty()) { + return trace; + } + smatch match; + regex pattern(checkContent); + Param param {""}; + for (int i = list.size() - 1; i >= 0; i--) { + if (regex_match(list[i], match, pattern)) { + param.mTask = match[TASK]; + param.mTid = match[TID]; + param.mTgid = match[TGID]; + param.mCpu = match[CPU]; + param.mDnh2 = match[DNH2]; + param.mTimeStamp = match[TIMESTAMP]; + param.mPid = match[PID]; + if (match.size() == TRACE_FMA11) { + param.mTraceName = match[TRACE_NAME], + param.mNum = ""; + } else if (match.size() == TRACE_FMA12) { + param.mTraceName = match[TRACE_NAME], + param.mNum = match[NUM]; + } else { + param.mTraceName = ""; + param.mNum = ""; + } + trace.Load(param); + break; + } + } + return trace; +} + +static bool WriteStringToFile(const string& fileName, const string& str) +{ + if (g_traceRootPath == "") { + HiLog::Error(LABEL, "Error: trace path not found."); + return false; + } + ofstream out; + out.open(g_traceRootPath + fileName, ios::out); + out << str; + out.close(); // release resources + return true; +} + +static stringstream ReadFile(const string& filename) +{ + stringstream ss; + char resolvedPath[PATH_MAX] = {}; + if (realpath(filename.c_str(), resolvedPath) == nullptr) { + fprintf(stderr, "Error: _fullpath %s failed.", filename.c_str()); + return ss; + } + ifstream fin(resolvedPath); + if (!fin.is_open()) { + fprintf(stderr, "opening file: %s failed.", filename.c_str()); + return ss; + } + ss << fin.rdbuf(); + fin.close(); + return ss; +} + +bool CleanTrace() +{ + // trace is not mounted + if (g_traceRootPath == "") { + HiLog::Error(LABEL, "Error: trace path not found!"); + return false; + } + ofstream ofs; + ofs.open(g_traceRootPath + TRACE_PATH, ofstream::out); + if (!ofs.is_open()) { + HiLog::Error(LABEL, "Error: opening trace path failed!"); + return false; + } + ofs << ""; + ofs.close(); // release resources + return true; +} + +static bool IsFileExisting(const string& filename) +{ + return access(filename.c_str(), F_OK) != -1; +} + +bool SetFtrace(const string& filename, bool enabled) +{ + // true represents 1 + return WriteStringToFile(filename, enabled ? "1" : "0"); +} + +bool CleanFtrace() +{ + return WriteStringToFile("set_event", ""); +} + +vector ReadFile2string(const string& filename) +{ + vector list; + if (!IsFileExisting(filename)) { + return list; + } else { + string line; + stringstream ss = ReadFile(filename); + while (getline(ss, line)) { + list.emplace_back(move(line)); + } + } + return list; +} + +vector ReadTrace() +{ + // read trace from /sys/kernel/debug/tracing/trace + return ReadFile2string(g_traceRootPath + TRACE_PATH); +} + +string GetFinishTraceRegex(MyTrace& trace) +{ + if (trace.IsLoaded()) { + return "\\s*(.*?)-(" + trace.GetTid() + "?)\\s+(.*?)\\[(\\d+?)\\]\\s+(.*?)\\s+" + "((\\d+).(\\d+)?):\\s+" + + TRACE_MARK_WRITE + ": E\\|(" + trace.GetPid() + ")|(.*)"; + } else { + return ""; + } +} + +/** + * @tc.name: Hitrace + * @tc.desc: test function OH_HiTrace_StartTrace OH_HiTrace_FinishTrace. + * @tc.type: FUNC + */ +HWTEST_F(HitraceNDKTest, StartTrace_001, TestSize.Level0) +{ + ASSERT_TRUE(CleanTrace()); + ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Hitrace Setting tracing_on failed."; + OH_HiTrace_StartTrace("HitraceStartTrace001"); + OH_HiTrace_FinishTrace(); + ASSERT_TRUE(SetFtrace(TRACING_ON, false)) << "Hitrace Setting tracing_on failed."; + vector list = ReadTrace(); + MyTrace startTrace = GetTraceResult(TRACE_START + "(HitraceStartTrace001) ", list); + ASSERT_TRUE(startTrace.IsLoaded()) << "Hitrace Can't find \"B|pid|HitraceStartTrace001\" from trace."; + MyTrace finishTrace = GetTraceResult(GetFinishTraceRegex(startTrace), list); + ASSERT_TRUE(finishTrace.IsLoaded()) << "Hitrace Can't find \"E|\" from trace."; +} + +/** + * @tc.name: Hitrace + * @tc.desc: test function OH_HiTrace_StartAsyncTrace OH_HiTrace_FinishAsyncTrace. + * @tc.type: FUNC + */ +HWTEST_F(HitraceNDKTest, StartTrace_002, TestSize.Level0) +{ + ASSERT_TRUE(CleanTrace()); + ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Setting tracing_on failed."; + OH_HiTrace_StartAsyncTrace("countTraceTest002", 123); + OH_HiTrace_FinishAsyncTrace("countTraceTest002", 123); + ASSERT_TRUE(SetFtrace(TRACING_ON, false)) << "Setting tracing_on failed."; + vector list = ReadTrace(); + MyTrace startTrace = GetTraceResult(TRACE_ASYNC_START + "(countTraceTest002) (.*)", list); + ASSERT_TRUE(startTrace.IsLoaded()) << "Can't find \"S|pid|countTraceTest002\" from trace."; + MyTrace finishTrace = + GetTraceResult(TRACE_ASYNC_FINISH + startTrace.GetTraceName() + " " + startTrace.GetNum(), list); + ASSERT_TRUE(finishTrace.IsLoaded()) << "Can't find \"F|\" from trace."; +} + +/** + * @tc.name: Hitrace + * @tc.desc: test function OH_HiTrace_CountTrace. + * @tc.type: FUNC + */ +HWTEST_F(HitraceNDKTest, StartTrace_003, TestSize.Level0) +{ + ASSERT_TRUE(CleanTrace()); + ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Setting tracing_on failed."; + OH_HiTrace_CountTrace("countTraceTest003", 1); + ASSERT_TRUE(SetFtrace(TRACING_ON, false)) << "Setting tracing_on failed."; + vector list = ReadTrace(); + MyTrace countTrace = GetTraceResult(TRACE_COUNT + "(countTraceTest003) (.*)", list); + ASSERT_TRUE(countTrace.IsLoaded()) << "Can't find \"C|\" from trace."; +} + +} // namespace HitraceTest +} // namespace HiviewDFX +} // namespace OHOS \ No newline at end of file From c38de8b7fe15eb03ae69f0ff5c3f74af79b2390b Mon Sep 17 00:00:00 2001 From: chenwei Date: Wed, 14 Jun 2023 09:42:17 +0800 Subject: [PATCH 2/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- frameworks/hitrace_ndk/hitrace_meter_ndk.c | 2 +- frameworks/include/hitrace_meter_wrapper.h | 2 +- interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/hitrace_ndk/hitrace_meter_ndk.c b/frameworks/hitrace_ndk/hitrace_meter_ndk.c index 26656e3..51cb40b 100644 --- a/frameworks/hitrace_ndk/hitrace_meter_ndk.c +++ b/frameworks/hitrace_ndk/hitrace_meter_ndk.c @@ -20,7 +20,7 @@ void OH_HiTrace_StartTrace(const char *name) StartTraceCwrapper(name); } -void OH_HiTrace_FinishTrace() +void OH_HiTrace_FinishTrace(void) { FinishTraceCwrapper(); } diff --git a/frameworks/include/hitrace_meter_wrapper.h b/frameworks/include/hitrace_meter_wrapper.h index 21c46fa..deef7a1 100644 --- a/frameworks/include/hitrace_meter_wrapper.h +++ b/frameworks/include/hitrace_meter_wrapper.h @@ -26,7 +26,7 @@ extern "C" { void StartTraceCwrapper(const char *value); -void FinishTraceCwrapper(); +void FinishTraceCwrapper(void); void StartAsyncTraceCwrapper(const char *value, int32_t taskId); diff --git a/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp b/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp index 99ae56d..b728558 100644 --- a/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp +++ b/interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp @@ -25,7 +25,7 @@ void StartTraceCwrapper(const char *value) StartTrace(HITRACE_TAG_APP, value); } -void FinishTraceCwrapper() +void FinishTraceCwrapper(void) { FinishTrace(HITRACE_TAG_APP); } From c7d5d9ce7d4f2bb9a4553d6dae41058446c065aa Mon Sep 17 00:00:00 2001 From: chenwei Date: Mon, 19 Jun 2023 17:49:35 +0800 Subject: [PATCH 3/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- bundle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundle.json b/bundle.json index 225debe..cbf41cb 100644 --- a/bundle.json +++ b/bundle.json @@ -1,5 +1,5 @@ { - "name": "@ohos/hitrace_native", + "name": "@ohos/hitrace", "description": "cross-thread, cross-process, and cross-device service call chain", "version": "4.0", "license": "Apache License 2.0", From 18d93c65f5738634bb8a99493ef1e2d4957dd9da Mon Sep 17 00:00:00 2001 From: chenwei Date: Mon, 19 Jun 2023 17:53:27 +0800 Subject: [PATCH 4/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- bundle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundle.json b/bundle.json index cbf41cb..225debe 100644 --- a/bundle.json +++ b/bundle.json @@ -1,5 +1,5 @@ { - "name": "@ohos/hitrace", + "name": "@ohos/hitrace_native", "description": "cross-thread, cross-process, and cross-device service call chain", "version": "4.0", "license": "Apache License 2.0", From 30cf303702c6a090593c0517cc2e4f572a981557 Mon Sep 17 00:00:00 2001 From: chenwei Date: Tue, 20 Jun 2023 10:39:36 +0800 Subject: [PATCH 5/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- interfaces/native/kits/include/hitrace/trace.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interfaces/native/kits/include/hitrace/trace.h b/interfaces/native/kits/include/hitrace/trace.h index 771d1c8..ea52a7a 100644 --- a/interfaces/native/kits/include/hitrace/trace.h +++ b/interfaces/native/kits/include/hitrace/trace.h @@ -62,6 +62,7 @@ extern "C" { /** * @brief Marks the start of a synchronous trace task. + * @syscap SystemCapability.HiviewDFX.HiTrace * * The OH_HiTrace_StartTrace and OH_HiTrace_FinishTrace APIs must be used in pairs. * The two APIs can be used in nested mode. The stack data structure is used for matching during trace data parsing. @@ -74,6 +75,7 @@ void OH_HiTrace_StartTrace(const char *name); /** * @brief Marks the end of a synchronous trace task. + * @syscap SystemCapability.HiviewDFX.HiTrace * * This API must be used with OH_HiTrace_StartTrace in pairs. During trace data parsing, the system matches * it with the OH_HiTrace_StartTrace API recently invoked in the service process. @@ -84,6 +86,7 @@ void OH_HiTrace_FinishTrace(void); /** * @brief Marks the start of an asynchronous trace task. + * @syscap SystemCapability.HiviewDFX.HiTrace * * This API is called to implement performance trace in asynchronous manner. The start and end of an asynchronous * trace task do not occur in sequence. Therefore, a unique taskId is required to ensure proper data parsing. @@ -105,6 +108,7 @@ void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); /** * @brief Marks the end of an asynchronous trace task. + * @syscap SystemCapability.HiviewDFX.HiTrace * * This API is called in the callback function after an asynchronous trace is complete. * It is used with OH_HiTrace_StartAsyncTrace in pairs. Its name and task ID must be the same as those of @@ -121,6 +125,7 @@ void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); /** * @brief Traces the value change of an integer variable based on its name. + * @syscap SystemCapability.HiviewDFX.HiTrace * * This API can be executed for multiple times to trace the value change of a given integer variable at different * time points. From 3405ba880dd131ff0310e1707e833ac553c9d540 Mon Sep 17 00:00:00 2001 From: chenwei Date: Tue, 20 Jun 2023 10:52:32 +0800 Subject: [PATCH 6/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- .../native/kits/include/hitrace/trace.h | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/interfaces/native/kits/include/hitrace/trace.h b/interfaces/native/kits/include/hitrace/trace.h index ea52a7a..abf3097 100644 --- a/interfaces/native/kits/include/hitrace/trace.h +++ b/interfaces/native/kits/include/hitrace/trace.h @@ -34,24 +34,26 @@ * * @brief Defines APIs of the HiTraceMeter module for performance trace. * - * Sample code:\n - * Synchronous timeslice trace event:\n + * Sample code: \n + * Synchronous timeslice trace event: \n * OH_HiTrace_StartTrace("hitraceTest");\n - * OH_HiTrace_FinishTrace();\n + * OH_HiTrace_FinishTrace();\n * Output: \n - * <...>-1668 (-------) [003] .... 135.059377: tracing_mark_write: B|1668|H:hitraceTest\n - * <...>-1668 (-------) [003] .... 135.059415: tracing_mark_write: E|1668|\n + * <...>-1668 (-------) [003] .... 135.059377: tracing_mark_write: B|1668|H:hitraceTest \n + * <...>-1668 (-------) [003] .... 135.059415: tracing_mark_write: E|1668| \n * Asynchronous timeslice trace event:\n - * OH_HiTrace_StartAsyncTrace("hitraceTest", 123);\n - * OH_HiTrace_FinishAsyncTrace("hitraceTest", 123);\n + * OH_HiTrace_StartAsyncTrace("hitraceTest", 123); \n + * OH_HiTrace_FinishAsyncTrace("hitraceTest", 123); \n * Output: \n - * <...>-2477 (-------) [001] .... 396.427165: tracing_mark_write: S|2477|H:hitraceTest 123\n - * <...>-2477 (-------) [001] .... 396.427196: tracing_mark_write: F|2477|H:hitraceTest 123\n + * <...>-2477 (-------) [001] .... 396.427165: tracing_mark_write: S|2477|H:hitraceTest 123 \n + * <...>-2477 (-------) [001] .... 396.427196: tracing_mark_write: F|2477|H:hitraceTest 123 \n * Integer value trace event:\n - * OH_HiTrace_CountTrace("hitraceTest", 500);\n + * OH_HiTrace_CountTrace("hitraceTest", 500); \n * Output: \n - * <...>-2638 (-------) [002] .... 458.904382: tracing_mark_write: C|2638|H:hitraceTest 500\n + * <...>-2638 (-------) [002] .... 458.904382: tracing_mark_write: C|2638|H:hitraceTest 500 \n * + * @syscap SystemCapability.HiviewDFX.HiTrace + * * @since 10 */ #include @@ -62,31 +64,32 @@ extern "C" { /** * @brief Marks the start of a synchronous trace task. - * @syscap SystemCapability.HiviewDFX.HiTrace * * The OH_HiTrace_StartTrace and OH_HiTrace_FinishTrace APIs must be used in pairs. * The two APIs can be used in nested mode. The stack data structure is used for matching during trace data parsing. * * @param name Name of a trace task. * + * @syscap SystemCapability.HiviewDFX.HiTrace + * * @since 10 */ void OH_HiTrace_StartTrace(const char *name); /** * @brief Marks the end of a synchronous trace task. - * @syscap SystemCapability.HiviewDFX.HiTrace * * This API must be used with OH_HiTrace_StartTrace in pairs. During trace data parsing, the system matches * it with the OH_HiTrace_StartTrace API recently invoked in the service process. * + * @syscap SystemCapability.HiviewDFX.HiTrace + * * @since 10 */ void OH_HiTrace_FinishTrace(void); /** * @brief Marks the start of an asynchronous trace task. - * @syscap SystemCapability.HiviewDFX.HiTrace * * This API is called to implement performance trace in asynchronous manner. The start and end of an asynchronous * trace task do not occur in sequence. Therefore, a unique taskId is required to ensure proper data parsing. @@ -102,13 +105,14 @@ void OH_HiTrace_FinishTrace(void); * sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the * unique task ID together. * + * @syscap SystemCapability.HiviewDFX.HiTrace + * * @since 10 */ void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); /** * @brief Marks the end of an asynchronous trace task. - * @syscap SystemCapability.HiviewDFX.HiTrace * * This API is called in the callback function after an asynchronous trace is complete. * It is used with OH_HiTrace_StartAsyncTrace in pairs. Its name and task ID must be the same as those of @@ -119,13 +123,14 @@ void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); * sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the * unique task ID together. * + * @syscap SystemCapability.HiviewDFX.HiTrace + * * @since 10 */ void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); /** * @brief Traces the value change of an integer variable based on its name. - * @syscap SystemCapability.HiviewDFX.HiTrace * * This API can be executed for multiple times to trace the value change of a given integer variable at different * time points. @@ -133,6 +138,8 @@ void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); * @param name Name of the integer variable. It does not need to be the same as the real variable name. * @param count Integer value. Generally, an integer variable can be passed. * + * @syscap SystemCapability.HiviewDFX.HiTrace + * * @since 10 */ void OH_HiTrace_CountTrace(const char *name, int64_t count); From 41b31c10c848973edc8e74cd678314dd1427e66d Mon Sep 17 00:00:00 2001 From: chenwei Date: Tue, 20 Jun 2023 11:33:00 +0800 Subject: [PATCH 7/7] =?UTF-8?q?hitraceMeter=E6=9A=B4=E9=9C=B2C=20API?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88NDK=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenwei --- interfaces/native/kits/include/hitrace/trace.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/interfaces/native/kits/include/hitrace/trace.h b/interfaces/native/kits/include/hitrace/trace.h index abf3097..a57b34b 100644 --- a/interfaces/native/kits/include/hitrace/trace.h +++ b/interfaces/native/kits/include/hitrace/trace.h @@ -53,7 +53,6 @@ * <...>-2638 (-------) [002] .... 458.904382: tracing_mark_write: C|2638|H:hitraceTest 500 \n * * @syscap SystemCapability.HiviewDFX.HiTrace - * * @since 10 */ #include @@ -71,7 +70,6 @@ extern "C" { * @param name Name of a trace task. * * @syscap SystemCapability.HiviewDFX.HiTrace - * * @since 10 */ void OH_HiTrace_StartTrace(const char *name); @@ -83,7 +81,6 @@ void OH_HiTrace_StartTrace(const char *name); * it with the OH_HiTrace_StartTrace API recently invoked in the service process. * * @syscap SystemCapability.HiviewDFX.HiTrace - * * @since 10 */ void OH_HiTrace_FinishTrace(void); @@ -106,7 +103,6 @@ void OH_HiTrace_FinishTrace(void); * unique task ID together. * * @syscap SystemCapability.HiviewDFX.HiTrace - * * @since 10 */ void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); @@ -124,7 +120,6 @@ void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); * unique task ID together. * * @syscap SystemCapability.HiviewDFX.HiTrace - * * @since 10 */ void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); @@ -139,7 +134,6 @@ void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); * @param count Integer value. Generally, an integer variable can be passed. * * @syscap SystemCapability.HiviewDFX.HiTrace - * * @since 10 */ void OH_HiTrace_CountTrace(const char *name, int64_t count);