Skip to content

Data Tracking: record user làm gì trong app ​

Vấn đề chương này giải

Làm sao biết user trong app làm gì?

Tưởng bạn mở quán trà sữa offline. Đứng quầy quan sát từng khách: xem menu bao lâu? Order gì? Có do dự xong bỏ đi không?

Nhưng "shop" là app/website, không thấy user thao tác. Cần tech "đặt" record point ở vị trí key của app, tự động record từng step user. Đây là Data Tracking (Event Tracking).

"Tracking" nghe professional, nhưng core đơn giản: đặt "recorder" ở chỗ user có thể thao tác, ghi lại làm gì.

4 step:

  1. Chọn collection method — đặt recorder ở đâu, thế nào
  2. Design data format — mỗi record chứa info gì
  3. Transmit + cache — gửi record từ phone user an toàn lên server
  4. Clean + load — sort data, bỏ duplicate + error, lưu DB

Step 1: Chọn collection method — đặt recorder ở đâu? ​

Goal: chọn cách record user op.

Vd: PM muốn biết "bao nhiêu user click buy button". Dev add logic record trong code button — mỗi click → ghi 1 record.

Lựa chọn: chỉ đặt recorder chỗ quan trọng (chỉ "buy", "register"), hay mọi chỗ (mọi click, swipe, dwell)?

场景:用户在电商 App 点击了「加入购物车」按钮
捕获到的信息代码埋点可视化埋点全埋点
点击了哪个按钮✔✔✔
点击发生的时间✔✔✔
用户停留了多久✘✘✔
商品名称 / 价格✔✘✘
用了哪张优惠券✔✘✘
账户余额✔✘✘
页面滑动轨迹✘✘✔

3 method mainstream

Method 1: Code Tracking — manual precise

Dev manually specify trong code: khi user op X → record.

Ẩn dụ: tại counter trà sữa có 1 người chuyên record "ai mua gì, bao nhiêu". Info detail + chính xác.

  • Lợi: detail business info (coupon dùng, balance)
  • Cost: thêm record point = code + test + release version mới, lâu

Method 2: Visual Tracking — click circle record

Không cần code. System cung cấp visual tool, marketer "circle" button/area trong app UI, system auto record.

Ẩn dụ: trên CCTV trà sữa, mouse circle "counter area", system auto đếm flow.

  • Lợi: không cần dev, marketer tự config
  • Cost: chỉ record "user click gì" UI, không record "order amount" business

Method 3: Auto Tracking — auto record mọi thứ

App nhúng SDK auto record mọi op: mỗi click, swipe, dwell.

Ẩn dụ: lắp camera mọi góc trà sữa, record mọi cử động.

  • Lợi: không sót op nào
  • Cost: data cực lớn, đa số vô dụng (vd user swipe vô thức), cần lọc-clean nhiều

Tóm: chọn method xong, app có capability "record user op".

Vấn đề mới: mỗi recorder format khác (có "userID", có "user_id", có không record) → không phân tích thống nhất được. Step sau: define format thống nhất.


Step 2: Design data format — mỗi record chứa gì? ​

Goal: define "record template" thống nhất.

Sao cần? Tưởng 3 nhân viên trà sữa record sale: 1 ghi "An mua trà sữa trân châu 15k", 1 ghi "15k, sữa, trân châu", 1 ghi "trà sữa trân châu 1 ly". Cuối tháng tổng hợp = đau khổ.

What"event": "add_to_cart"
Who"user_id": "u_98765"
When"time": "2025-08-12T10:33:09Z"
Where"device": "iPhone 15", "network": "5G"
What"product": "新款手机", "price": 2999
点击上方按钮,观察一条埋点记录是如何被组装出来的

4W1H template

Mỗi record trả lời 5 câu hỏi (4W1H):

Who — ai làm?

  • User logged in: account ID (user_id: "hoang123")
  • Not logged in: device unique ID (phone device ID), để phân biệt "cùng phone"

When — khi nào? Time chính xác đến ms. Detail: app có user oversea, 3 giờ Hà Nội ≠ 3 giờ NY (13h cách). Thống nhất convert sang UTC.

Where & How — env nào?Common attribute — device + network env. Auto kèm với mọi record:

  • Device model: iPhone 15 / Xiaomi 14
  • Network: WiFi / 5G / 4G
  • App version: v1.2.3
  • OS: iOS 18 / Android 15

Value: bug chỉ trên 1 model → common attr giúp định vị nhanh.

What — làm gì cụ thể?Custom attribute — business detail. Op khác → info khác:

  • Click "Add to cart": product name, price, quantity
  • Complete payment: order amount, payment method, coupon code

Tóm: qua 4W1H, mỗi op user → record format thống nhất (JSON).

Vấn đề mới: format thống nhất rồi, nhưng app traffic lớn (vd campaign, vài chục nghìn record/giây), phone không gửi từng cái (tốn pin + bandwidth + server crash). Step sau: design transmission khôn hơn.


Step 3: Transmit + cache — gửi data an toàn lên server? ​

Pre-condition: mỗi op user đã thành JSON format thống nhất.

Goal: gửi data từ phone (browser) đáng tin tới server, dù network kém.

Sao không gửi thẳng? Mỗi record gửi network request = mỗi viết 1 thư chạy đến bưu điện. Tốt hơn: gom 1 batch gửi.

📱
手机
📦
打包
🌐
发送
🚦
排队
🗄️
入库
产生数据攒一批网络传输消息队列数据仓库

3 layer protection

Layer 1: gom batch (batching) SDK không gửi từng record, mà cache memory phone. Đủ batch (vd 30 record) hoặc đủ time (vd 5 giây) → pack batch, gửi 1 lần.

Như gửi nhiều món qua bưu điện chung. Phone giảm request → tiết kiệm pin + bandwidth.

Layer 2: offline tolerance (local storage) User trong elevator, subway tunnel, no signal. Data chỉ memory → close app = mất.

SDK save data chưa gửi vào local storage (như cho thư vào ngăn kéo). Network có lại → auto resend. Short disconnect = không mất.

Layer 3: server không sập (message queue) Data đến server không direct write DB. Sao? Peak campaign vài chục nghìn record/giây cùng lúc, DB process direct = crash.

Solution: thêm "buffer" trước DB — Message Queue (Kafka). Như taking ticket queue nhà hàng: peak khách (data) xếp hàng, bếp (DB) xử theo nhịp riêng, không bị spike crush.

Tóm: qua "batch → offline storage → MQ buffer", data đến server an toàn.

Vấn đề mới: offline reconnect auto resend → có thể duplicate. Không xử trực tiếp DB = duplicate (vd 100k order ghi 2 lần, sale ảo). Step sau: clean data.


Step 4: Clean + load — bỏ "dirty data" ​

Pre-condition: data đến server qua pipeline.

Goal: trước khi vào DB chính, "health check" — bỏ duplicate, fix format sai.

Tech: ETL — 3 chữ viết tắt:

  • Extract: lấy từ MQ
  • Transform: check + fix format
  • Load: ghi clean data vào DB
原始数据(服务器收到的)
id-001 userId: "zhang" add_to_cart ¥2999
id-001 userId: "zhang" add_to_cart ¥2999重复
id-002 user_id: "li" click_buy ¥0
id-003 userId: "wang" pay 1970-01-01时间异常
id-004 user_id: "zhao" click_buy ¥599
ETL 清洗
→
清洗后(写入数据仓库的)
id-001 user_id: "zhang" add_to_cart ¥2999
id-002 user_id: "li" click_buy ¥0
id-004 user_id: "zhao" click_buy ¥599

2 action key

Action 1: Dedup — bỏ record duplicate

Reconnect auto resend → duplicate. Xử thế nào?

Đơn giản: client pack data → cấp ID unique global cho mỗi record (dedup_id, như tracking number). Server lưu data → check ID đã có chưa — có = drop.

Action 2: Validation + normalize — fix record không chuẩn

App update version, code tracking khác bản:

  • Old version userId, new user_id
  • Timestamp bất thường (vd 1970)
  • Value không nhận diện

Step này: viết rule transform unified — field name align, timestamp lỗi drop, unknown mark unknown.

Tóm: sau dedup + validation, data clean ghi Data Warehouse (DB chuyên store + analyze, vd ClickHouse, Hive). Data analyst dùng SQL query → result đáng tin.


Full flow recap ​

StepLàm gìĐược gìCòn vấn đề
1. MethodChọn cách recordApp có khả năng recordFormat không thống nhất
2. Format4W1H templateMỗi record JSON chuẩnTraffic lớn không gửi từng cái được
3. TransmitBatch + offline + MQData an toàn đến serverRetry → duplicate
4. CleanDedup + validation Data clean vào DW—

Kết ​

Khi user click 1 button, bề mặt là 1 action tức thời. Đằng sau là chain hoàn chỉnh:

  1. Tracking code capture click, theo 4W1H gen record chuẩn
  2. Record cache local, đủ batch gửi server
  3. Server qua MQ nhận êm, dedup + validate
  4. Cuối, data clean + chính xác ghi DW

Tracking system = biến hành vi scattered, invisible thành structured data queryable + analyzable. PM hiểu user thích feature nào, mất ở đâu; marketer eval campaign; dev định vị bug version nào.

"Collect → model → transmit → clean" = infrastructure cho data-driven decision.

2026 cho VN dev

  • Tool:
    • PostHog (open-source, all-in-one): tracking + analytics + feature flag + A/B
    • Amplitude: enterprise, mạnh nhất
    • Mixpanel: alternative Amplitude
    • Segment: data router, tracking 1 lần gửi nhiều destination
    • Snowplow (open-source): self-host data pipeline
  • VN context: Tiki, Shopee, Grab dùng Amplitude/Mixpanel; startup thường PostHog
  • Privacy first 2026: GDPR, VN Data Protection Decree → cần consent banner, anonymization, opt-out
  • AI tracking: track user query LLM, prompt pattern, accept/reject AI suggestion (Cursor, Copilot làm này)