# ほとんどの場合、痕跡のない埋設点を通じてすべての情報データを収集し、視覚的な埋設点と連携して特定の点を特定し、それに応じてほとんどの埋設点情報を分析できます。
特殊な状況では、ビジネス コードを追加して、特殊なシナリオに対処するポイントを手動で埋め込むことができます (ほとんどの場合、強力なビジネスは、通常のクリックや更新イベント、および必要な情報とは何の関係もありません)報告済み)
埋没点 SDK 開発
埋没点データの収集と分析
- 基本的なイベント データ
- イベント発生時間
- 発生時のページ情報のスナップショット
- ページ
- ページPV、UV
- ユーザーページ滞在時間
- ページジャンプイベント
- ページがバックグラウンドに入る
- ユーザーがページを離れる
- ユーザー情報
- ユーザーuid
- ユーザーデバイスのフィンガープリント
- デバイス情報
- ip
- ポジショニング
- ユーザー操作の動作
##ページ AJAX リクエスト-
リクエスト成功- リクエスト失敗
- リクエスト タイムアウト
-
# ページ エラー
- リソース読み込みエラー新しいリソース読み込みパフォーマンス
- 画像
- スクリプト
- ページ読み込みパフォーマンス
- 上記のデータは、
3 次元を通じて非表示のイベントを定義します ·LEVEL - : 埋め込まれたデータのログ レベルを記述します。
INFO- : 一部のユーザー操作、リクエストの成功、リソースの読み込みなど、通常のデータ レコード
ERROR - : JS エラー、インターフェイス エラーなどのデータ レコード。
DEBUG- : 開発者が手動でバグを排除するためにデータ レコードを返すために予約されています。呼び出し
WARN- : 開発者が手動呼び出しを通じて異常なユーザー動作のデータ レコードを返すために予約されています
CATEGORY- : 説明埋め込みポイント データの分類
TRACK- : 埋め込みポイント SDK オブジェクトのライフ サイクルによって、埋め込みポイント データ全体が管理されます。
WILL_MOUNT- : SDK オブジェクトが初期化およびロードされようとしており、デフォルト ID が生成され、関連するすべてのイベントが追跡されます
DID_MOUNTED- :SDKオブジェクトが初期化され、本体のデバイスフィンガープリント等の非同期操作が完了
#AJAX- :AJAX関連データ
ERROR- : ページ内の例外に関するデータ
PERFORMANCE- : パフォーマンス関連のデータ
OPERATION- : ユーザー操作関連data
EVENT_NAME- : 特定のイベント名
上記の次元に従って、次のアーキテクチャを簡単に設計できます
プロキシ リクエスト ブラウザには現在 2 つの主なタイプがあります。リクエスト メソッドは 3 つあり、1 つは XMLHttpRequest、もう 1 つは Fetch です。 Agent XMLHttpRequest function NewXHR() { var realXHR: any = new OldXHR(); // 代理模式里面有提到过
realXHR.id = guid() const oldSend = realXHR.send;
realXHR.send = function (body) {
oldSend.call(this, body) //记录埋点
}
realXHR.addEventListener('load', function () { //记录埋点
}, false);
realXHR.addEventListener('abort', function () { //记录埋点
}, false);
realXHR.addEventListener('error', function () { //记录埋点
}, false);
realXHR.addEventListener('timeout', function () { //记录埋点
}, false); return realXHR;
}复制代码 Agent Fetch const oldFetch = window.fetch; function newFetch(url, init) { const fetchObj = { url: url, method: method, body: body,
}
ajaxEventTrigger.call(fetchObj, AJAX_START); return oldFetch.apply(this, arguments).then(function (response) { if (response.ok) { //记录埋点
} else { //上报错误
} return response
}).catch(function (error) {
fetchObj.error = error //记录埋点
throw error
})
}复制代码 ページの PV をリッスンします、UV
ページに入る前に、アルゴリズムを使用して一意の セッション ID を生成します。これは、この埋め込み動作のグローバル ID として機能し、ユーザー ID、デバイスの指紋、およびデバイス情報を報告します。ユーザーがログインしていない場合、UV はデバイスのフィンガープリントを通じて計算され、 PV は セッション ID を通じて計算されます。 例外キャプチャ 例外は、プログラムの通常のフローを妨げる異常な事故です。実行時エラー
JS で渡すことができます。 window.onerror および window.addEventListener('error', callback) は、ランタイム例外をキャプチャします。通常、 window.onerror が使用されます。互換性。 window.onerror = function(message, url, lineno, columnNo, error) { const lowCashMessage = message.toLowerCase() if(lowCashMessage.indexOf('script error') > -1) { return
} const detail = { url: url
filename: filename, columnNo: columnNo, lineno: lineno, stack: error.stack, message: message
} //记录埋点}复制代码 スクリプト エラー ここでは、スクリプト エラーをフィルター処理します。これは主に、ページに読み込まれたサードパーティのクロスドメイン スクリプトによって報告されるエラーによって発生します。サードパーティ CDN の js スクリプトでホストされます。このタイプの問題は、トラブルシューティングがより困難です。解決策は次のとおりです。
CORS (クロスオリジン リソース共有、クロスドメイン リソース共有) を開き、次の手順に従います。-
aabe02b7c09859a7420c688c19aeb5c62cacc6d41bbb37262a98f745aa00fbf0
-
Modify Access-Control-Allow-Origin: * | ドメイン名を指定
使用 try catch <script scr="crgt.js"></script> //加载crgt脚本,window.crgt = {getUser: () => string}
try{ window.crgt.getUser();
}catch(error) { throw error // 输出正确的错误堆栈
}复制代码
プロミス拒否
js パスできません非同期例外 onerror メソッド キャプチャの場合、Promise オブジェクトが拒否され、同時に処理されなかった場合
unhandledrejection エラーがスローされ、上記のメソッドでは捕捉されないため、別の処理イベントを追加する必要があります。 window.addEventListener("unhandledrejection", event => { throw event.reason
});复制代码
资源加载异常
在浏览器中,可以通过 window.addEventListener('error', callback) 的方式监听资源加载异常,比如 js 或者 css 脚本文件丢失。 window.addEventListener('error', (event) => { if (event.target instanceof HTMLElement) { const target = parseDom(event.target, ['src']); const detail = { target: target, path: parseXPath(target),
} // 记录埋点
}
}, true)复制代码 监听用户行为
通过 addEventListener click 监听 click 事件 window.addEventListener('click', (event) => { //记录埋点}, true)复制代码 在这里通过组件的 displaName 来定位元素的位置,displaName 表示组件的文件目录,比如 src/components/Form.js 文件导出的组件 FormItem 通过 babel plugin 自动添加属性 @components/Form.FormItem ,或者使用者主动给组件添加 static 属性 displayName 。
页面路由变化
- hashRouter
监听页面hash变化,对hash进行解析
window.addEventListener('hashchange', event => { const { oldURL, newURL } = event; const oldURLObj = url.parseUrl(oldURL); const newURLObj = url.parseUrl(newURL); const from = oldURLObj.hash && url.parseHash(oldURLObj.hash); const to = newURLObj.hash && url.parseHash(newURLObj.hash); if(!from && !to ) return; // 记录埋点})复制代码 监听页面离开
通过 addEventListener beforeunload 监听离开页面事件 window.addEventListener('beforeunload', (event) => { //记录埋点})复制代码 SDK 架构class Observable { constructor(observer) {
observer(this.emit)
}
emit = (data) => { this.listeners.forEach(listener => {
listener(data)
})
}
listeners = [];
subscribe = (listener) => { this.listeners.push(listeners); return () => { const index = this.listeners.indexOf(listener); if(index === -1) { return false
}
this.listeners.splice(index, 1); return true;
}
}
}复制代码 const clickObservable = new Observable((emit) => { window.addEventListener('click', emit)
})复制代码 然而在处理 ajax ,需要将多种数据组合在一起,需要进行 merg 操作,则显得没有那么优雅,也很难适应后续复杂的数据流的操作。 const ajaxErrorObservable = new Observable((emit) => { window.addEventListener(AJAX_ERROR, emit)
})const ajaxSuccessObservable = new Observable((emit) => { window.addEventListener(AJAX_SUCCESS, emit)
})const ajaxTimeoutObservable = new Observable((emit) => { window.addEventListener(AJAX_TIMEOUT, emit)
})复制代码 可以选择 RxJS 来优化代码 export const ajaxError$ = fromEvent(window, 'AJAX_ERROR', true)export const ajaxSuccess$ = fromEvent(window, 'AJAX_SUCCESS', true)export const ajaxTimeout$ = fromEvent(window, 'AJAX_TIMEOUT', true)复制代码 ajaxError$.pipe(
merge(ajaxSuccess$, ajaxTimeout$),
map(data=> (data) => ({category: 'ajax', data; data}))
subscribe(data => console.log(data))复制代码 通过 merge , map 两个操作符完成对数据的合并和处理。
数据流
项目结构
-
core
-
event$ 数据流合并
-
snapshot 获取当前设备快照,例如url ,userID ,router
-
track 埋点类,组合数据流和日志。
-
logger
-
observable
ajax
beforeUpload
opeartion
routerChange
logger
track
参考
- www.alibabacloud.com/help/zh/doc…
结尾
自建埋点系统是一个需要前后端一起合作的事情,如果人力不足的情况下,建议使用第三方分析插件,例如 Sentry 就能足够满足大部分日常使用
但还是建议多了解,在第三方插件出现不能满足业务需求的时候,可以顶上。
想了解更多编程学习,敬请关注php培训栏目!
|