提交 63dd79ca 编写于 作者: C cheng_jinsong

sys event add

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
上级 4f069347
......@@ -22,6 +22,9 @@
],
"rom": "",
"ram": "",
"hisysevent_config": [
"//base/startup/init/services/modules/sysevent/init_events.yaml"
],
"deps": {
"components": [
"startup",
......
......@@ -18,5 +18,6 @@
{ "name": "DoJobNow" },
{ "name": "GetServiceExtData" },
{ "name": "UpdateMiscMessage" },
{ "name": "AddRebootCmdExecutor" }
{ "name": "AddRebootCmdExecutor" },
{ "name": "GetBootEventList" }
]
......@@ -39,6 +39,7 @@ group("modulesgroup") {
deps = [
"bootchart:bootchart",
"reboot:rebootmodule",
"sysevent:eventmodule",
"trace:inittrace",
"udid:udidmodule",
]
......
......@@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bootevent.h"
#include <stdbool.h>
#include "init_module_engine.h"
......@@ -26,34 +27,9 @@
#include "init_utils.h"
#include "init_cmds.h"
#define BOOT_EVENT_PARA_PREFIX "bootevent."
#define BOOT_EVENT_PARA_PREFIX_LEN 10
#define BOOT_EVENT_TIMESTAMP_MAX_LEN 50
#define BOOT_EVENT_FILEPATH_MAX_LEN 60
#define BOOT_EVENT_FINISH 2
#define SECTOMSEC 1000000
#define SECTONSEC 1000000000
#define MSECTONSEC 1000
#define SAVEINITBOOTEVENTMSEC 100000
#define BOOTEVENT_OUTPUT_PATH "/data/service/el0/startup/init/"
static int g_bootEventNum = 0;
// check bootevent enable
static int g_bootEventEnable = 1;
enum {
BOOTEVENT_FORK,
BOOTEVENT_READY,
BOOTEVENT_MAX
};
typedef struct tagBOOT_EVENT_PARAM_ITEM {
ListNode node;
char *paramName;
int pid;
struct timespec timestamp[BOOTEVENT_MAX];
} BOOT_EVENT_PARAM_ITEM;
static ListNode bootEventList = {&bootEventList, &bootEventList};
static int BootEventParaListCompareProc(ListNode *node, void *data)
......@@ -106,6 +82,7 @@ static int AddServiceBootEvent(const char *serviceName, const char *paramName)
INIT_LOGI("strdup failed");
return -1;
}
item->flags = BOOTEVENT_TYPE_SERVICE;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return 0;
}
......@@ -134,6 +111,7 @@ static void AddInitBootEvent(const char *bootEventName)
free(item);
return;
}
item->flags = BOOTEVENT_TYPE_JOB;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return;
}
......@@ -223,6 +201,16 @@ static int SaveServiceBootEvent()
return 0;
}
static void ReportSysEvent(void)
{
if (!GetBootEventEnable()) {
return;
}
InitModuleMgrInstall("eventmodule");
InitModuleMgrUnInstall("eventmodule");
return;
}
static void BootEventParaFireByName(const char *paramName)
{
ListNode *found = NULL;
......@@ -251,6 +239,8 @@ static void BootEventParaFireByName(const char *paramName)
SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true");
g_bootEventEnable = BOOT_EVENT_FINISH;
SaveServiceBootEvent();
// report complete event
ReportSysEvent();
const char *clearBootEventArgv[] = {"bootevent"};
// clear servie extra data
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
......@@ -322,6 +312,7 @@ static void AddCmdBootEvent(int argc, const char **argv)
for (int i = 1; i < 3; i++) { // 3 cmd content end
INIT_CHECK_ONLY_ELOG(strcat_s(item->paramName, cmdLen, argv[i]) >= 0, "combine cmd args failed");
}
item->flags = BOOTEVENT_TYPE_CMD;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return;
}
......@@ -419,6 +410,11 @@ int GetBootEventEnable(void)
return 0;
}
ListNode *GetBootEventList(void)
{
return &bootEventList;
}
static int RecordInitCmd(const HOOK_INFO *info, void *cookie)
{
INIT_CMD_INFO *cmdCtx = (INIT_CMD_INFO *)cookie;
......
/*
* 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.
*/
#ifndef PLUGIN_BOOT_EVENT_H
#define PLUGIN_BOOT_EVENT_H
#include <sys/types.h>
#include "init_module_engine.h"
#include "list.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define BOOTEVENT_TYPE_CMD 1
#define BOOTEVENT_TYPE_JOB 2
#define BOOTEVENT_TYPE_SERVICE 3
#define BOOT_EVENT_PARA_PREFIX "bootevent."
#define BOOT_EVENT_PARA_PREFIX_LEN 10
#define BOOT_EVENT_TIMESTAMP_MAX_LEN 50
#define BOOT_EVENT_FILEPATH_MAX_LEN 60
#define BOOT_EVENT_FINISH 2
#define SECTOMSEC 1000000
#define SECTONSEC 1000000000
#define MSECTONSEC 1000
#define SAVEINITBOOTEVENTMSEC 100000
#define BOOTEVENT_OUTPUT_PATH "/data/service/el0/startup/init/"
enum {
BOOTEVENT_FORK,
BOOTEVENT_READY,
BOOTEVENT_MAX
};
typedef struct tagBOOT_EVENT_PARAM_ITEM {
ListNode node;
char *paramName;
int pid;
struct timespec timestamp[BOOTEVENT_MAX];
int flags;
} BOOT_EVENT_PARAM_ITEM;
int GetBootEventEnable(void);
ListNode *GetBootEventList(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif /* PLUGIN_BOOT_EVENT_H */
......@@ -55,5 +55,10 @@ enum HOOK_ID_ {
HOOKID(BOOTEVENT_MAX) = HOOK_ID_BOOTEVENT + 10,
};
int GetBootEventEnable(void);
#ifdef STARTUP_INIT_TEST
#define PLUGIN_STATIC
#else
#define PLUGIN_STATIC static
#endif
#endif
# 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.
import("//build/ohos.gni")
ohos_shared_library("eventmodule") {
sources = [
"startup_time_event.c",
"sys_event.c",
]
include_dirs = [
".",
"..",
"../bootevent",
"../init_hook",
"../../include/param",
]
deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
external_deps = [
"hisysevent_native:libhisysevent",
"init:libinit_module_engine",
]
part_name = "init"
subsystem_name = "startup"
if (target_cpu == "arm64") {
module_install_dir = "lib64/init"
} else {
module_install_dir = "lib/init"
}
}
# 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.
domain: INIT
STARTUP_TIME:
__BASE: {type: BEHAVIOR, level: CRITICAL, tag: PERFORMANCE, desc: Startup Time}
TOTAL_TIME: {type: INT64, desc: Total Time Required}
DETAILED_TIME: {type: STRING, desc: Time required by each phase}
REASON : {type: STRING, desc: Startup Reason}
ISFRIST: {type: STRING, desc: use time}
/*
* 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 "sys_event.h"
#include <inttypes.h>
#include <time.h>
#include <sys/time.h>
#include "bootevent.h"
#include "init_module_engine.h"
#include "init_param.h"
#include "plugin_adapter.h"
#include "securec.h"
typedef struct {
char *buffer;
uint32_t bufferLen;
uint32_t currLen;
} EventArgs;
static int GetServiceName(const char *paramName, char *buffer, size_t buffSize)
{
size_t len = strlen(paramName);
size_t i = 0;
for (size_t index = strlen("bootevent."); index < len; index++) {
if (i > buffSize) {
return -1;
}
if (*(paramName + index) == '.') {
break;
}
buffer[i++] = *(paramName + index);
}
return (int)i;
}
static int TraversalEvent(ListNode *node, void *root)
{
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
if (item->flags != BOOTEVENT_TYPE_SERVICE) {
return 0;
}
EventArgs *args = (EventArgs *)root;
int len = GetServiceName(item->paramName, args->buffer + args->currLen, args->bufferLen - args->currLen);
PLUGIN_CHECK(len > 0 && ((len + args->currLen) < args->bufferLen), return -1,
"Failed to format service name %s", item->paramName);
args->currLen += len;
len = sprintf_s(args->buffer + args->currLen, args->bufferLen - args->currLen, ",%u:%u,%u:%u;",
(uint32_t)item->timestamp[BOOTEVENT_FORK].tv_sec,
(uint32_t)(item->timestamp[BOOTEVENT_FORK].tv_nsec / MSECTONSEC),
(uint32_t)item->timestamp[BOOTEVENT_READY].tv_sec,
(uint32_t)(item->timestamp[BOOTEVENT_READY].tv_nsec / MSECTONSEC));
PLUGIN_CHECK(len > 0 && ((len + args->currLen) < args->bufferLen), return -1,
"Failed to format service time %s", item->paramName);
args->currLen += len;
return 0;
}
PLUGIN_STATIC void ReportBootEventComplete(ListNode *events)
{
PLUGIN_CHECK(events != NULL, return, "Invalid events");
struct timespec curr;
if (clock_gettime(CLOCK_MONOTONIC, &curr) != 0) {
return;
}
char *buffer = (char *)calloc(MAX_BUFFER_FOR_EVENT + PARAM_VALUE_LEN_MAX, 1);
PLUGIN_CHECK(buffer != NULL, return, "Failed to get memory for sys event ");
EventArgs args = { buffer, MAX_BUFFER_FOR_EVENT, 0 };
OH_ListTraversal(events, (void *)&args, TraversalEvent, 0);
if ((args.currLen > 1) && (args.currLen < MAX_BUFFER_FOR_EVENT)) {
buffer[args.currLen - 1] = '\0';
}
StartupTimeEvent startupTime = {};
startupTime.event.type = STARTUP_TIME;
startupTime.totalTime = curr.tv_sec;
startupTime.totalTime = startupTime.totalTime * SECTOMSEC;
startupTime.totalTime += curr.tv_nsec / MSECTONSEC;
startupTime.detailTime = buffer;
char *reason = buffer + MAX_BUFFER_FOR_EVENT;
uint32_t size = PARAM_VALUE_LEN_MAX;
int ret = SystemReadParam("ohos.boot.bootreason", reason, &size);
if (ret == 0) {
startupTime.reason = reason;
startupTime.firstStart = 1;
} else {
startupTime.reason = "";
startupTime.firstStart = 0;
}
PLUGIN_LOGI("SysEventInit %u.%u detailTime len %u '%s'",
(uint32_t)curr.tv_sec, (uint32_t)(curr.tv_nsec / MSECTONSEC), args.currLen, startupTime.detailTime);
ReportSysEvent(&startupTime.event);
free(buffer);
}
#ifndef STARTUP_INIT_TEST // do not install
MODULE_CONSTRUCTOR(void)
{
ReportBootEventComplete(GetBootEventList());
}
#endif
/*
* 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 "sys_event.h"
#include "init_module_engine.h"
#include "hisysevent_c.h"
#include "plugin_adapter.h"
#define STARTUP_DOMAIN "INIT"
#define KEY_TOTAL_TIME "TOTAL_TIME"
#define KEY_DETAILED_TIME "DETAILED_TIME"
#define KEY_REASON "REASON"
#define KEY_FIRST "ISFIRST"
static void ReportStartupTimeEvent(const StartupTimeEvent *startupTime)
{
HiSysEventParam params[] = {
{
.name = KEY_TOTAL_TIME,
.t = HISYSEVENT_INT64,
.v = { .i64 = startupTime->totalTime },
.arraySize = 0,
},
{
.name = KEY_DETAILED_TIME,
.t = HISYSEVENT_STRING,
.v = { .s = startupTime->detailTime },
.arraySize = 0,
},
{
.name = KEY_REASON,
.t = HISYSEVENT_STRING,
.v = { .s = startupTime->reason },
.arraySize = 0,
},
{
.name = KEY_FIRST,
.t = HISYSEVENT_INT32,
.v = { .i32 = startupTime->firstStart },
.arraySize = 0,
}
};
int ret = OH_HiSysEvent_Write(STARTUP_DOMAIN, "STARTUP_TIME",
HISYSEVENT_BEHAVIOR, params, sizeof(params) / sizeof(params[0]));
if (ret != 0) {
PLUGIN_LOGE("Failed to write event ret %d", ret);
}
}
void ReportSysEvent(const StartupEvent *event)
{
PLUGIN_CHECK(event != NULL, return, "Invalid events");
if (event->type == STARTUP_TIME) {
StartupTimeEvent *startupTime = (StartupTimeEvent *)(event);
ReportStartupTimeEvent(startupTime);
}
}
/*
* 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.
*/
#ifndef PLUGIN_SYS_EVENT_H
#define PLUGIN_SYS_EVENT_H
#include <stdint.h>
#include <sys/types.h>
#include "init_module_engine.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define MAX_BUFFER_FOR_EVENT 1024
typedef enum {
STARTUP_TIME = 0,
STARTUP_EVENT_MAX
} StartupEventType;
typedef struct {
StartupEventType type;
} StartupEvent;
typedef struct {
StartupEvent event;
int64_t totalTime;
char *detailTime;
char *reason;
int firstStart;
char *page;
} StartupTimeEvent;
void ReportSysEvent(const StartupEvent *event);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif /* PLUGIN_SYS_EVENT_H */
......@@ -16,6 +16,7 @@ import("//build/ohos.gni")
comm_include = [
".",
"..",
"../bootevent",
"../../include",
"../../include/param",
]
......
......@@ -14,6 +14,7 @@
*/
#include <string.h>
#include "init_module_engine.h"
#include "bootevent.h"
#include "plugin_adapter.h"
static int InitTraceEarlyHook(const HOOK_INFO *info, void *cookie)
......
......@@ -302,6 +302,7 @@ ohos_unittest("init_unittest") {
external_deps = [
"c_utils:utils",
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
"init:libinit_module_engine",
]
......@@ -379,5 +380,18 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/modules/trace/init_trace_static.c",
"//base/startup/init/test/unittest/modules/trace_unittest.cpp",
]
# for sysevent
sources += [
"//base/startup/init/services/modules/sysevent/startup_time_event.c",
"//base/startup/init/services/modules/sysevent/sys_event.c",
"//base/startup/init/test/unittest/modules/sysevent_unittest.cpp",
]
include_dirs += [
"//base/startup/init/services/modules/bootevent",
"//base/startup/init/services/modules/sysevent",
]
cflags_cc = [ "-fexceptions" ]
}
/*
* 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 <cinttypes>
#include <ctime>
#include <sys/time.h>
#include "bootevent.h"
#include "init_utils.h"
#include "list.h"
#include "param_stub.h"
#include "securec.h"
#include "sys_event.h"
using namespace std;
using namespace testing::ext;
extern "C" {
extern void ReportBootEventComplete(ListNode *events);
}
static void AddBootEvent(ListNode *events, const char *name, int32_t type)
{
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)calloc(1, sizeof(BOOT_EVENT_PARAM_ITEM));
if (item == NULL) {
return;
}
OH_ListInit(&item->node);
item->paramName = strdup(name);
if (item->paramName == NULL) {
free(item);
return;
}
(void)clock_gettime(CLOCK_MONOTONIC, &(item->timestamp[BOOTEVENT_FORK]));
(void)clock_gettime(CLOCK_MONOTONIC, &(item->timestamp[BOOTEVENT_READY]));
item->flags = type;
OH_ListAddTail(events, (ListNode *)&item->node);
}
static void BootEventDestroyProc(ListNode *node)
{
if (node == NULL) {
return;
}
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
OH_ListRemove(node);
OH_ListInit(node);
free(item->paramName);
free(item);
}
namespace init_ut {
class SysEventUnitTest : public testing::Test {
public:
static void SetUpTestCase(void) {};
static void TearDownTestCase(void) {};
void SetUp() {};
void TearDown() {};
};
HWTEST_F(SysEventUnitTest, SysEventTest_001, TestSize.Level1)
{
ReportBootEventComplete(nullptr);
}
HWTEST_F(SysEventUnitTest, SysEventTest_002, TestSize.Level1)
{
ListNode events = { &events, &events };
// empty event
ReportBootEventComplete(&events);
}
HWTEST_F(SysEventUnitTest, SysEventTest_003, TestSize.Level1)
{
ListNode events = { &events, &events };
// create event and report
AddBootEvent(&events, "bootevent.11111.xxxx", BOOTEVENT_TYPE_JOB);
AddBootEvent(&events, "bootevent.22222222.xxxx", BOOTEVENT_TYPE_SERVICE);
AddBootEvent(&events, "bootevent.33333333333.xxxx", BOOTEVENT_TYPE_SERVICE);
AddBootEvent(&events, "bootevent.44444444444444", BOOTEVENT_TYPE_SERVICE);
AddBootEvent(&events, "bootevent.44444444444444.6666666666.777777", BOOTEVENT_TYPE_SERVICE);
ReportBootEventComplete(&events);
OH_ListRemoveAll(&events, BootEventDestroyProc);
}
HWTEST_F(SysEventUnitTest, SysEventTest_004, TestSize.Level1)
{
struct timespec curr;
if (clock_gettime(CLOCK_MONOTONIC, &curr) != 0) {
return;
}
StartupTimeEvent startupTime = {};
startupTime.event.type = STARTUP_TIME;
startupTime.totalTime = curr.tv_sec;
startupTime.totalTime = startupTime.totalTime * SECTOMSEC;
startupTime.totalTime += curr.tv_nsec / MSECTONSEC;
startupTime.detailTime = const_cast<char *>("buffer");
startupTime.reason = const_cast<char *>("");
startupTime.firstStart = 1;
ReportSysEvent(&startupTime.event);
}
HWTEST_F(SysEventUnitTest, SysEventTest_005, TestSize.Level1)
{
struct timespec curr;
if (clock_gettime(CLOCK_MONOTONIC, &curr) != 0) {
return;
}
StartupTimeEvent startupTime = {};
startupTime.event.type = STARTUP_EVENT_MAX;
startupTime.totalTime = curr.tv_sec;
startupTime.totalTime = startupTime.totalTime * SECTOMSEC;
startupTime.totalTime += curr.tv_nsec / MSECTONSEC;
startupTime.detailTime = const_cast<char *>("buffer");
startupTime.reason = const_cast<char *>("");
startupTime.firstStart = 1;
ReportSysEvent(&startupTime.event);
}
} // namespace init_ut
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册