You need to enable JavaScript to run this app.
最新活动
产品
解决方案
定价
合作与生态
支持与服务
开发者
了解我们
导航

自定义事件/自定义日志

更新时间:2022.09.28 15:59:08

自定义事件/自定义日志是APMPlus PC提供的埋点功能,支持多进程多实例调用。自定义事件记录数值型数据,如cpu使用率指标,启动耗时指标等等。自定义日志记录字符串型数据,一般用于记录用户行为,产品行为,用于单点追查用户反馈的问题等等。自定义事件/自定义日志都可以在APMPlus PC的日志通用功能-日志查询中查到。

接入要求:
  1. 提供有权限的文件夹绝对路径,作为Parfait初始化时的Rootpath,parfait在此路径下存储自定义事件/自定义日志。
  2. 初始化Parfait SDK。持有初始化成功的parfait_wrapper_ptr指针。
  3. 注意:单条自定义事件/自定义日志长度是有限制的。自定义事件下Category+Metric+Extra的总大小不要超过900kb。自定义日志下Category+Log总大小不要超过900KB,超出限制可能导致写入失败。
写入数据:

自定义事件

  1. 创建自定义事件recorder。您可在可长期持有此recorder。
    1. interval:数据flush的间隔,可理解为优先级,间隔越短,优先级越高,越能更快被上报。
    2. service_name:事件名称,可在日志查询中查看。
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);
  1. 调用WriteXXX()方法记录Category,Metric,Extra数据,参数必须为已序列化的json数据。最后调用DoRecord()确认写入数据。可重复这步写入新数据。
    注意:此时只是写入,并不代表数据上传。DoRecord()后不会清空Category、Metric、Extra数据。如果下次写事件时,不需要写入Extra数据,需要显示调用WriteExtra()清除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."
    }

WriteXXX()函数均必须传入序列化好的json数据,切记!!!

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。

    1. interval:数据flush的间隔,可理解为优先级,间隔越短,优先级越高,越能更快被上报。和自定义事件的interval一样。
    2. log_level:日志等级
    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);
  2. 记录Category,Log数据,Category必须为已序列化的json数据。最后调用DoRecord确认写入数据。可重复这步写入新数据。
    注意:此时只是写入,并不代表数据上传。DoRecord()后不会清空Category、Log数据。如果下次写事件时,不需要写入Category数据,需要显示调用WriteCategory()清除Category。

含义:示例:

Category

(optional)可枚举数据类型。key:value中的value必须是字符串类型。 指标查询无法消费自定义日志数据,category仅为业务标识用。不支持嵌套json数据。

{
"is_scanning": "false"
}

Log日志内容,传入任意字符串即可。“This is a test log.”
// 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);
上报数据:

业务写入自定义事件/自定义日志后,数据尚未上传。有两种上传方式:

  1. (推荐)Parfait自动间隔循环上传数据,业务方不需要关心数据上报时机。间隔上报时间可由业务方设置,在初始化调用Global Env的SetReportInterval方法设置即可。Parfait退出时间隔上报才可停止。这种方式适合数据量大,频繁打点的业务。
    注意:多parfait实例,多进程的情况下,同一aid只要有一个parfait实例调用Upload即可。
/**
 * 触发自定义事件/自定义日志/性能监控数据/网络监控数据的自动间隔循环上传
 **/
void ParfaitWrapperBase::Upload();

示例代码:
parfait_wrapper_ptr->Upload();
  1. 业务调用UploadWithFlushImmediately()接口主动触发一次上报。此方法适用于少量数据写入,避免间隔循环上报带来的性能消耗。
    注意:此接口实际上并非同步接口,所以在进程退出时调用可能不生效。
/**
 * 即刻触发一次flush+upload指标&日志数据
 **/
void ParfaitWrapperBase::UploadWithFlushImmediately();

示例代码:
parfait_wrapper_ptr->UploadWithFlushImmediately();
查询/消费:

查询数据:

数据上报后2~4min后,可以在平台上查询和消费数据,首先在APMPlus PC 平台找到自己aid对应的项目(没有请新建),进入项目详情页后,点击右侧的日志查询,输入对应的did或uid,选择目标时间段,勾选自定义事件/自定义日志,即可搜查数据。

最佳实践:
  1. 在APMPlus PC平台上创建项目。
  2. 初始化SDK。
  3. 开启间隔循环上报。
  4. 写入自定义事件/自定义日志。
  5. 过一阵子后,数据上传。具体什么时候上传是依据业务方设置的Report Interval & Recorder Flush Interval而定的。
  6. 在APMPlus PC平台的日志查询上搜查自定义事件/自定义日志。
  7. 如果没有搜到,一般有三个原因:
    1. 数据未写入:查看RootPathName路径下是否有lock/prepare/ready文件夹生成,一般是因为sdk未初始化,或者RootPathName设置不当,没有写入数据的权限。
    2. 数据未上报:未调用Upload()或者UploadWithFlushImmediately()方法上传数据。
    3. 平台数据堆积:数据已上报但是未展示,请联系RD反馈
特殊场景支持:

同一进程内多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()方法开启自己的数据间隔循环上报。

多进程打点:

如果业务为多进程应用,子进程也需要进行打点。有两种方式:

  1. 基于IPC通信,子进程传数据给主进程进行打点。
  2. 子进程也接入Parfait,初始化流程和主进程一致。如果和主进程为同一AID + Rootpath,那么打点进程只需要管理进程SDK初始化+打点即可,不用管任何的上报逻辑。