You need to enable JavaScript to run this app.
文档中心
应用性能监控全链路版

应用性能监控全链路版

复制全文
下载 pdf
SDK 接入
自定义事件/自定义日志
复制全文
下载 pdf
自定义事件/自定义日志
自定义事件和自定义日志是APMPlus PC提供的埋点功能,支持多进程多实例调用。自定义事件记录数值型数据,如cpu使用率指标,启动耗时指标等等。自定义日志记录字符串型数据,一般用于记录用户行为,产品行为,用于单点追查用户反馈的问题等等。自定义事件/自定义日志都可以在APMPlus PC的日志查询中查看。
接入要求
  • 提供有权限的文件夹绝对路径,作为Parfait初始化时的Rootpath,parfait在此路径下存储自定义事件/自定义日志。
  • 初始化Parfait SDK。持有初始化成功的parfait_wrapper_ptr指针。
注意
单条自定义事件/自定义日志长度是有限制的,超出限制可能导致写入失败。
  • 自定义事件下Category+Metric+Extra的总大小不要超过900KB。
  • 自定义日志下Category+Log的总大小不要超过900KB。
全部流程
  1. 在APMPlus PC平台上创建项目。
  1. 初始化SDK。
  1. 开启间隔循环上报。
  1. 写入自定义事件/自定义日志。
  1. 过一段时间后,数据上传。具体什么时候上传,是依据业务方设置的Report Interval & Recorder Flush Interval而定的。
  1. 在APMPlus PC平台的日志查询上搜查自定义事件/自定义日志。
  1. 问题排查。
  • 如果没有查询到结果,一般是以下原因:
  • 数据未写入:查看RootPathName路径下是否有lock/prepare/ready文件夹生成,一般是因为SDK未初始化,或者RootPathName设置不当,没有写入数据的权限。
  • 数据未上报:未调用Upload()或者UploadWithFlushImmediately()方法上传数据。
  • 平台数据堆积:数据已上报但是未展示,请联系研发人员进行反馈。
写入数据
自定义事件
  1. 创建自定义事件recorder。您可以长期持有此recorder。
  • enum RECORD_INTERVAL {
    INTERVAL_1 = 1 * 1000, // 最高优先级
    INTERVAL_10 = 10 * 1000,
    INTERVAL_15 = 15 * 1000,
    INTERVAL_30 = 30 * 1000 // 最低优先级
    };
    /**
    * 生成‘自定义事件’的recorder,业务方可用返回的recorder写自定义事件
    * @param interval 数据flush间隔,flush越短,越快被上报
    * @param service_name 事件名称
    * @return ‘自定义事件’的recorder指针
    */
    ParfaitRecorderBase* CreateRecorder(enum RECORD_INTERVAL interval, const char* service_name);
  • interval:数据flush的间隔,可理解为优先级,间隔越短,优先级越高,越能更快被上报。
  • service_name:事件名称,可在日志查询中查看。
  1. 调用WriteXXX()方法记录Category、Metric、Extra数据。
  • 数据
    说明
    示例
    Category
    (optional)可枚举数据类型。
    • key:value中的value必须是字符串类型。
    • 用于过滤metrics数据。主要用于指标查询中,给同一事件下的数据分组。
    • 不支持嵌套json数据。
    {
    "is_scanning": "false",
    "error_code:" "-1",
    "file_type": "txt"
    }
    Metric
    数据指标。
    • key:value中的value必须是整形/浮点形而不是字符串或者别的数据类型,不然上报成功,但是平台搜不到。
    • 不支持嵌套json数据。
    {
    "cpu": 0.01851585025,
    "os_use_cpu": 4,
    "os_use_memory": 9205.6953125
    }
    Extra
    备注信息。
    • key:value中的value必须是字符串类型。
    • 不支持嵌套json数据。
    {
    "info": "This is extra info."
    }
  • 传入的参数必须是已序列化的json数据。最后调用DoRecord()确认写入数据。可重复这步写入新数据。
  • 该步骤只是写入数据,并不代表数据上传。DoRecord()后不会清空Category、Metric、Extra数据。如果下次写事件时,不需要写入Extra数据,需要显示调用WriteExtra()清除Extra。
  • 示例代码:
  • ParfaitRecorderBase& ParfaitRecorderBase::WriteCategory(char *json);
    ParfaitRecorderBase& ParfaitRecorderBase::WriteMetric(char *json);
    ParfaitRecorderBase& ParfaitRecorderBase::WriteExtra(char *json);
    // 确认写入,开启上传功能后Parfait会自动上传
    void ParfaitRecorderBase::DoRecord();
  1. 没有写入需求/进程退出时,调用DestroyRecorder销毁Recorder,防止内存泄漏。
  • // 销毁CreateRecorder方法生成的自定义事件Recorder,不然会内存泄漏
    void ParfaitWrapperBase::DestroyRecorder(ParfaitRecorderBase* recorder);
  • 示例代码:
  • // 1.初始化Parfait SDK,得到parfait_wrapper指针
    // 2.创建名为"your_service"事件recorder
    parfait::ParfaitRecorderBase* recorder = parfait_wrapper_ptr->CreateRecorder(parfait::INTERVAL_10, "your_service");
    // 3.写入json数据
    char* category = "{\n"
    " \t\t\"category_key\" : \"1\",\n"
    " \t}";
    char* mertic = "{\n"
    " \t\t\"metric_key\" : 1,\n"
    " \t}";
    char* extra = "{\n"
    " \t\t\"extra_key\" : \"1\",\n"
    " \t}";
    recorder->WriteCategory(category)
    .WriteMetric(mertic)
    .WriteExtra(extra)
    .DoRecord();
    // 4.继续写入数据,这次只写metric数据
    char* mertic2 = "{\n"
    " \t\t\"metric_key\" : 2,\n"
    " \t}";
    // 显式调用WriteCategory("") & WriteExtra("") 覆盖数据
    recorder->.WriteCategory("")
    .WriteMetric(mertic)
    .WriteExtra("")
    .DoRecord();
    // 5.应用退出,销毁recorder
    parfait_wrapper_ptr->DestroyRecorder(recorder);
自定义日志
  1. 创建自定义事件log recorder。您可以长期持有此log recorder。
  • enum LOG_RECORD_LEVEL {
    LOG_VERBOSE,
    LOG_DEBUG,
    LOG_INFO,
    LOG_WARN,
    LOG_ERROR
    };
    /**
    * 新接口,生成‘日志查询’的log recorder,业务方可用返回的log recorder写指标数据
    * @param interval 指标flush间隔,flush越短越快被上报
    * @param log_level 日志类型
    * @return ‘日志查询’的log recorder指针
    */
    ParfaitLogRecorderBase* ParfaitWrapperBase::CreateLogRecorder(enum RECORD_INTERVAL interval, enum LOG_RECORD_LEVEL log_level);
  • interval:数据flush的间隔,可理解为优先级,间隔越短,优先级越高,越能更快被上报。和自定义事件的interval一样。
  • log_level:日志等级。
  1. 记录Category、Log数据。
  • 数据
    说明
    示例
    Category
    (optional)可枚举数据类型。
    • key:value中的value必须是字符串类型。
    • 不支持嵌套json数据。
    {
    "is_scanning": "false"
    }
    Log
    日志内容,传入任意字符串即可。
    “This is a test log.”
  • 传入的数据必须为已序列化的json数据。最后调用DoRecord确认写入数据。可重复这步写入新数据。
  • 该步骤只是写入,并不代表数据上传。DoRecord()后不会清空Category、Log数据。如果下次写事件时,不需要写入Category数据,需要显示调用WriteCategory()清除Category。
  • 示例代码:
  • // WriteCategory()函数必须传入序列化好的json数据,切记!!!
    ParfaitLogRecorderBase& ParfaitRecorderBase::WriteCategory(char *json);
    ParfaitLogRecorderBase& ParfaitRecorderBase::WriteLog(char *log);
    // 确认写入,开启上传功能后Parfait会自动上传
    void ParfaitLogRecorderBase::DoRecord();
  1. 没有写入需求/进程退出时,调用DestroyLogRecorder销毁LogRecorder,防止内存泄漏。
  • /**
    * 新接口,回收‘日志查询’的log recorder
    * @param recorder CreateLogRecorder返回的指针
    */
    void ParfaitWrapperBase::DestroyLogRecorder(ParfaitLogRecorderBase* recorder);
  • 示例代码:
  • // 1.初始化Parfait SDK,得到parfait_wrapper指针
    // 2.创建info级别的log recorder
    parfait::ParfaitLogRecorderBase* log_recorder = parfait_wrapper_ptr->CreateLogRecorder(parfait::INTERVAL_10, parfait::LOG_INFO);
    // 3.写入第一条日志
    char* category = "{\n"
    " \t\t\"category\" : \"1\",\n"
    " \t}";
    log_recorder->WriteCategory(buff1)
    .WriteLog("log hahahaha")
    .DoRecord();
    // 4.写入第二条日志,只用写log
    // 显式调用WriteCategory("")覆盖数据
    log_recorder->WriteCategory("")
    .WriteLog("log hahahaha test2")
    .DoRecord();
    // 5.应用退出/不再写入log,销毁log_recorder
    parfait_wrapper_ptr->DestroyLogRecorder(log_recorder);
上报数据
业务写入自定义事件/自定义日志后,数据尚未上传。有两种上传方式:
  • (推荐)Parfait自动间隔循环上传数据,业务方不需要关心数据上报时机。间隔上报时间可由业务方设置,在初始化调用Global Env的SetReportInterval方法设置。Parfait退出时间隔上报才可停止。这种方式适合数据量大,频繁打点的业务。
注意
多parfait实例,多进程的情况下,同一aid只要有一个parfait实例调用Upload即可。
  • /**
    * 触发自定义事件/自定义日志/性能监控数据/网络监控数据的自动间隔循环上传
    **/
    void ParfaitWrapperBase::Upload();
    示例代码:
    parfait_wrapper_ptr->Upload();
  • 业务调用UploadWithFlushImmediately()接口主动触发一次上报。此方法适用于少量数据写入,避免间隔循环上报带来的性能消耗。
注意
此接口实际上并非同步接口,所以在进程退出时调用可能不生效。
  • /**
    * 即刻触发一次flush+upload指标&日志数据
    **/
    void ParfaitWrapperBase::UploadWithFlushImmediately();
    示例代码:
    parfait_wrapper_ptr->UploadWithFlushImmediately();
查询/消费
查询数据
数据上报后2min~4min后,可以在平台上查询和消费数据。
  1. 在APMPlus PC平台找到自己aid对应的项目(没有项目请新建一个项目)。
  1. 进入项目详情页后,单击右侧的日志查询
  1. 输入对应的did或uid,选择目标时间段,选中自定义事件/自定义日志,即可搜查数据。
特殊场景支持
同一进程内多aid打点
假设A业务的aid是6666,B业务aid为7777。那么:
A业务创建一个AID为6666的parfait全局环境变量和parfait示例环境变量,并持有aid为6666的parfait_wrapper6666指针写入数据。
B业务创建一个AID为7777的parfait全局环境变量和parfait示例环境变量,并持有aid为7777的parfait_wrapper7777指针写入数据。
由于二者数据存放路径不一致,因此,AID6666和AID7777都需要调用Upload()方法开启自己的数据间隔循环上报。
多进程打点
如果业务为多进程应用,子进程也需要进行打点。有两种方式:
  • 基于IPC通信,子进程传数据给主进程进行打点。
  • 子进程也接入Parfait,初始化流程和主进程一致。如果和主进程为同一AID + Rootpath,那么打点进程只需要管理进程SDK初始化+打点,不用管任何的上报逻辑。
最近更新时间:2025.03.07 15:02:00
这个页面对您有帮助吗?
有用
有用
无用
无用