Risiko Bisnis: Tracking Loss dan Anomali Data Atribusi
Kesalahan format atau hilangnya event telemetri iklan (seperti ad_impression, ad_click, dan conversion) berdampak langsung pada kalkulasi revenue dan forecasting monetisasi. Masalah ini kerap bersifat silent failure: aplikasi tetap berjalan normal, response HTTP mengembalikan status 200, namun backend analitik membuang event karena ketidaksesuaian tipe data atau atribut wajib yang hilang. Akibatnya, terjadi selisih (discrepancy) atribusi antara Ad Network dan data internal yang sulit dideteksi pasca rilis.
Solusi yang terbukti andal adalah memindahkan pengujian ke fase build dengan automasi CI: memvalidasi skema payload secara statis, mengeksekusi integrasi end-to-end terisolasi menggunakan mock server lokal, dan menghentikan pipeline deployment jika terdapat pelanggaran kontrak event.
Spesifikasi Kontrak Telemetri dengan JSON Schema
Gunakan JSON Schema untuk mendefinisikan struktur payload analitik. Format ini memungkinkan penegakan tipe data ketat, validasi regex, serta aturan ketergantungan antar-properti.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["event_name", "timestamp", "user_id", "ad_unit_id", "revenue"],
"properties": {
"event_name": {
"type": "string",
"enum": ["ad_impression", "ad_click", "ad_reward"]
},
"timestamp": {
"type": "integer",
"minimum": 1000000000
},
"user_id": {
"type": "string",
"pattern": "^[a-fA-F0-9-]{36}$"
},
"ad_unit_id": {
"type": "string",
"minLength": 1
},
"revenue": {
"type": "number",
"minimum": 0
}
},
"additionalProperties": false
}Mock Collector HTTP dan Assertion Test
Pengujian berbasis pipeline memerlukan HTTP mock collector lokal untuk menampung rekaman event yang dipicu oleh client SDK atau worker background. Node.js native standard library menyediakan kapabilitas yang cukup tanpa dependensi mock server eksternal yang kompleks.
Berikut adalah skrip verifikasi verify-telemetry.js yang menjalankan mock server, memicu eksekusi kode klien, dan memvalidasi payload yang masuk menggunakan library validator skema (ajv).
const http = require('http');
const Ajv = require('ajv');
const schema = require('./schemas/ad_event.schema.json');
const ajv = new Ajv({ allErrors: true });
const validate = ajv.compile(schema);
const receivedEvents = [];
const server = http.createServer((req, res) => {
if (req.method === 'POST' && req.url === '/v1/telemetry') {
let body = '';
req.on('data', chunk => { body += chunk; });
req.on('end', () => {
try {
const payload = JSON.parse(body);
receivedEvents.push(payload);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'queued' }));
} catch (err) {
res.writeHead(400).end();
}
});
} else {
res.writeHead(404).end();
}
});
server.listen(4040, async () => {
try {
// Jalankan pipeline simulasi tracker klien ke http://localhost:4040/v1/telemetry
const clientModule = require('./tracker-client');
await clientModule.triggerSampleImpression('http://localhost:4040/v1/telemetry');
// 1. Verifikasi deteksi missing event (Tracking Loss)
if (receivedEvents.length === 0) {
throw new Error('Assertion Failed: Silent drop terdeteksi, tidak ada event yang terekam.');
}
// 2. Verifikasi kesesuaian skema (Linting Payload)
for (const event of receivedEvents) {
const valid = validate(event);
if (!valid) {
console.error('Schema errors:', validate.errors);
throw new Error(`Assertion Failed: Payload tidak valid untuk event ${event.event_name}`);
}
}
console.log(`Success: ${receivedEvents.length} event(s) tervalidasi tanpa error.`);
process.exit(0);
} catch (error) {
console.error(error.message);
process.exit(1);
} finally {
server.close();
}
});Konfigurasi Runner CI (GitHub Actions)
Konfigurasikan workflow CI untuk menjalankan pemeriksaan kontrak ini pada setiap pull request dan sebelum trigger deployment production.
name: Telemetry Contract Verification
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
validate-telemetry:
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Setup Node.js runtime
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Telemetry Lint and Contract Tests
run: node scripts/verify-telemetry.js
env:
CI: trueMenangani Edge Case: Silent Drops dan Batching
Sebagian besar SDK telemetri menggunakan antrean internal dalam memori dan mengirimkan batch event secara periodik atau saat ukuran buffer tercapai. Pola ini memicu kegagalan umum dalam CI:
- Proses runner berhenti sebelum buffer dikosongkan (flush): Pastikan mock harness memanggil metode klien eksplisit seperti
client.flush()sebelum mengeksekusi assertion. - Ketidaksesuaian encoding: Selalu lakukan asersi terhadap header
Content-Type: application/jsondan format kompresi (misalgzip) jika klien mengaktifkan payload optimization. - Payload logging berlebih: Pastikan pipeline merahasiakan PII (Personally Identifiable Information) agar tidak tercetak pada runner logs saat validasi gagal.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!