埋点和superset使用教程

埋点+superset作图相关的项目实践目前较少,经验尚不成熟,我们会持续更新

1 流程简介

-log行为

每一个项目初次生成开始,会在zion_analytics_prod数据库中增加一个名为client_log_projectId的数据模型,用于记录该小程序的所有用户的行为,其最关键的字段为jsonb格式的data字段,其中记录了触发时间、事件、用户id、用户ip、用户手机信息等信息,例: { "time": "2021-09-13T08:32:11.388Z", "event": "APP_LAUNCH", "platform": "WECHAT_MINI_PROGRAM", "accountId": "1000000000000000", "_client_ip": "115.216.28.53", "project_id": 2000000000003114, "systemInfo": 略 "_user_agent": "hasura-graphql-engine/v1.3.0-beta.3", "event_category": "APP", "thirdPartyInfo": {}, "_request_account_id": 1000000000000000 } 而zion允许以log行为添加埋点,对新的触发事件做记录,log id会决定data中event字段的取值,parameters则决定了该事件的data字段中所新增的字段及其取值。
以上图为例,在首页横向列表轮播图的点击事件上绑定该log,重新生成后,每当用户点击轮播图时,在client_log_本项目id中会添加一条记录: { "time": ***, "bannerid":对应项id "event": "banner_click", "platform": ***, "accountId": *** }

-取数

承接1中轮播图的例子,进入数据监测superset,点击Sql Lab- Sql Editor,输入
SELECT data -> 'bannerid' as bannerid,created_at FROM client_log_2000000000003114 where data -> 'event' = '"banner_click"';
就可以得到所有轮播图被点击的记录,其他自定义的事件以此类推,通常就以event取值进行过滤即可。 必要的一些pgql知识补充:
  1. 单双引号区分
在pgql中,单引号用于表示string(包括json),双引号标志表名或字段名/key名
  1. json类型字段的运算符
->int,根据index取json数组的元素,'[1,2,3]'->1返回2 ->text,通过key取json对象中的key值,'{"id":1,"a":2,"b":'shit'}'->'b'返回'shit' 注意虽然b对于json是key,用""表示,但在外面就只是一个普通的string值,用'' ->>int,根据index取json数组的元素,一律返回text类型,'[1,2,3]'->1返回'2' ->>text,通过key取json对象中的key值,一律返回text类型 进行运算后会变为常规数据类型 一般这里只用到->text
  1. ::json
::json表示将表达式转化为json格式,::jsonb转化为jsonb格式

-explore

在sql成功运行并取到数据后,点击Explore进入Explore界面。 依次选择好要生成的图表类型、时间字段、指标、分组字段,在customize中自定义图表,然后生成到具体的dashboard即可 tips: -customize中,饼图、直方图等标签类型默认会选择category name,一般不实用,通常会考虑改为value或category and value-customize中,时序图的x轴默认格式为周几+日,很不实用,一般需修改。另外需点上x界限,否则头尾的刻度不会显示完全。Y轴的最小刻度很多情况下需要自定义为0

-dashboard

dashboard的编辑比较简单,自行探索即可。 tips:用tab和header可以对界面起到简易的美化效果 如果只是根据流程简介走一遍,在按自己想法实操时一定会各种碰壁,比如为什么过滤条件中字符串要在'""'单双引号的包裹下才能生效,请耐心的把后续内容看完再进行实践。

2 log行为

log行为的设置是为sql取数做铺垫,需要在设置log时就想到到时候对应分析场景要如何取数,尽可能通过合理的log设置让sql简单化。 所谓sql简单化,就是尽量不要直接在sql中写distinct,也不需要额外写group by、having等,原因是进入explore状态(作图时),superset自带一定程度的透视、过滤功能。有的时候客户会要求对于数据分析图做一些修改,写死了往往意味着需要重写一个sql甚至不得不对埋点进行修改。

-规范

1场景类似,存在有放在一起分析的潜在可能的log,取相同的log id 举例:用户需要记录三个常见页面A、B、C的pv与uv,那么建议log id设置为'pagepv',参数设置pagename,分别记A、B、C。 反例:log id直接分为记为了A_pv、B_pv、C_pv,反例的缺点在于,当用户需要比较几个页面的pv或uv时,过滤条件设置会更麻烦,不利于在explore界面进行灵活操作。 2在第一点的基础上,确保任何类似但不同的log可以通过参数加以区分 3汇总一份事件与参数含义表,否则埋点一多会容易漏掉。

-常见场景

比较简单的,没有坑点的场景略过。 要说明的是,superset中只能取到clientlog中的数据,无法取到项目数据库里的数据(也就是你进控制台能看到的那些),这大大增加了需要设置log的量
  1. 页面pv、uv
直接在页面加载行为处放log即可,但这意味着无法检测switch to跳转带来的曝光,需要和客户明确“曝光”的含义。如果客户坚持要获取switch to带来的曝光,那么需要把所有swtich to跳转行为改为relaunch。 pv就count(accountid),uv就是count(distinct accountid)
  1. 详情查看数
直接在详情页的远程数据的成功时处放log,之所以不用页面加载行为,是因为页面加载行为先于远程数据获取,会导致log中引用不到详情相关记录的数据。
  1. 增删改
删除通过状态字段做成修改,在增改行为的成功时加log,必要时引用结果数据即可。
  1. 批量增删改
同样删除变修改,在增改行为的成功时加list action列表行为,数据源选择这次批量insert行为的数据源,如果是update则自己加一条过滤条件一致、不限额的远程数据,里面套log。 对加红部分解释下,比如批量insert,我要对一个可多选的礼包提交事件添加log,页面与提交行为如图所示:
那么list action的数据源,就直接选未申请礼包-sv这个选择视图即可。(为什么不用结果数据?因为现在zion中结果数据限额1,批量情况下只会返回第一条) 又如我需要update record表中符合如下条件的数据,update默认是批量,这个时候我们选不到一个现有的数据源,我们就在远程数据中设置一个来源为record表,过滤条件完全一致的数据源,将其选为list action的数据源:

-细节

1埋点重新设计 埋点重新设计后,并不会影响之前clientlog中的记录,也就是说可能会留下脏数据,需要自行去数据库里删,或者在sql过滤条件中加以约束 2空值 如果设计埋点时就没有加入参数A,那么取数时想取到A为空的记录,用A is null过滤如果设计埋点时有A这个参数但是没赋值,或者做了数据绑定但是返回了空值,那么取数想取到A为空的记录,用A= '""'过滤

3取数

-自带""

由于json字段的特殊性,我们通过 data -> '字段'取出的字段值,如果在设计埋点时没有把该字段设置为数字类型,那么实际都是带一层""的,""就是其值的一部分。 然而在展示的时候,sql自动做了一层隐式类型转换,导致看起来好像不带"",但我们在写过滤条件时依然要带上"",比如:where data -> 'page' = '"首页"' 包括下图这些看起来是空字符串的,其值其实是"",过滤时要用where data -> 'gifttype' <> '""'
想深入了解为什么json/jsonb格式的字段在键值对设计上要这么做,可以查看:

-过滤:显示类型转换

常用过滤关系:is (not) null,=,<>,~(包含) 由于自带""的关系,包含关系判断需要写成如下格式,否则系统会提示你explicit type cast: Where cast(data ->'page' as varchar(16)) ~ '首页'

-查看、加工sql

superset的explore面板的灵活性比较低下,如下左图在explore设置过滤条件后会作图失败,因为superset生成的sql是右图这样的:
superset会在explore时自动外套一层母查询,里面只包含分组字段、指标字段(如果是时序图则还有时间字段),导致expolre的过滤条件中实际上只能用分组字段和指标字段, 又比如这种有双聚合指标的图,靠写简单sql加explore是无法完成的,需要自行在editor中写2个子查询join起来:
所以实际使用时,需要经常自行去sql中反复调试,灵活使用生成图右上角的view query和run in sql lab可以提高调试的效率:

4进阶内容与细节

1时序图处理 类似聚合到这样的结果,最终绘制出的时序图,会直接跳过1-28这个实际count=0的一天:
原因是superset在处理时间字段的时候只用了date_trunc函数,而没有更多处理。以上时序图的源代码为:
SELECT step AS step, DATE_TRUNC('day', time) AS __timestamp, count(viewerid) AS "COUNT(viewerid)" FROM (SELECT data -> 'accountId' as viewerid, data -> 'step' as step, created_at as time FROM client_log_2000000000003114 where data -> 'event' = '"giftapply"' and data-> 'step' ='"提交"') AS expr_qry GROUP BY step, DATE_TRUNC('day', time)
date_trunc函数可以把时间截取成选定的精度,比如date_trunc('hour', timestamp '2001-02-16 20:38:40')返回2001-02-16 20:00:00。 只有在每个时间周期内必定有该log事件发生的情况下,才能用superset自带的explore绘制时序图,否则都需要自己写sql。 2如何给dashboard添加统一的时间过滤器 自己写一条sql:
点explore,生成为图表类型为“筛选盒”的图标即可 如果dashboard有图表无法被过滤,可能是图表背后的query没有时间字段,自己修改一下query,比如“总用户数”原本是不可按时间过滤的,在原本的query中加上对created_at的select,然后再外套一个count(distinct)就可以了:
2022-05-25
0 0