4 poin oleh GN⁺ 2023-11-03 | 1 komentar | Bagikan ke WhatsApp
  • Bear Blog mengimplementasikan sistem analitik internal yang bekerja tanpa JavaScript klien karena ada batasan kecepatan, efisiensi, dan stabilitas
  • Skrip analitik umum bisa diblokir oleh pemblokir iklan, dan hanya mengandalkan log server dapat mencampurkan crawler, scraper, hingga parser berbasis GPT sehingga statistik kunjungan terdistorsi
  • Dari CSS tiap halaman, saat body:hover terjadi, border-image memanggil endpoint /hit/{{ post.id }}/, sehingga hover atau scroll di seluler dipakai sebagai sinyal membaca
  • Server memeriksa apakah itu bot, browser, dan platform lewat user-agent, lalu alamat IP hanya dipakai untuk menentukan negara dan setelah itu duplikasi pembacaan dihapus dengan hash IP+tanggal
  • Jika dibaca di hari yang sama dari beberapa perangkat pada IP yang sama, itu tetap dihitung sekali, tetapi tanpa menyimpan informasi identitas, sistem tetap bisa menghitung jumlah pembaca unik per halaman secara sederhana

Membuat event baca dengan CSS hover

  • Sistem analitik Bear Blog mengikuti batasan untuk tidak menggunakan JavaScript di sisi klien
  • Alat analitik umum bisa memakai JavaScript klien untuk sebagian menilai keaslian trafik atau apakah itu bot, tetapi banyak pemblokir iklan memblokir bukan hanya Google Analytics melainkan juga skrip analitik seperti Fathom dan Plausible
  • Jika hanya mem-parsing log server, crawler mesin pencari, scraper, dan parser berbasis GPT dapat tercampur seperti trafik biasa sehingga menghasilkan sudut pandang yang terdistorsi
  • Bear menyisipkan CSS berikut ke setiap halaman agar saat pengguna mengarahkan kursor ke halaman atau melakukan scroll di perangkat seluler, body:hover terpicu
body:hover {
  border-image: url("/hit/{{ post.id }}/?ref={{ request.META.HTTP_REFERER }}");
}
  • Saat body:hover terpicu, URL hit untuk tulisan tersebut dipanggil
  • Informasi yang secara eksplisit ditambahkan kembali ke permintaan ini adalah referrer, dan ejaan HTTP_REFERER adalah salah eja yang bertahan seperti standar
  • Dengan memanfaatkan fakta bahwa bot tidak melakukan hover, pemanggilan berbasis body:hover dipakai sebagai sinyal pembaca manusia
  • Setelah itu server memeriksa lewat user-agent apakah itu bot, lalu mengekstrak browser dan platform dari string user-agent

Menghapus pembacaan duplikat tanpa informasi identitas

  • Batasan kedua adalah tidak menyimpan informasi yang dapat mengidentifikasi pembaca, baik di cookie browser maupun di server
  • Alamat IP hanya digunakan untuk menentukan negara, dan sebelum disimpan akan di-hash bersama tanggal
  • Permintaan berikutnya untuk halaman yang sama dibandingkan dengan hash alamat IP + tanggal, dan jika duplikat akan dibuang
  • Dengan cara ini, selama satu hari satu alamat IP dihitung sebagai satu read untuk satu halaman
  • Alamat IP asli tidak disimpan, dan hash yang mencakup tanggal memberi efek kedaluwarsa harian
user_agent = httpagentparser.detect(self.request.META.get('HTTP_USER_AGENT', None))
if user_agent.get('bot', False):
    print('Bot traffic')
    return

ip_hash = hashlib.md5(f"{client_ip(self.request)}-{timezone.now().date()}".encode('utf-8')).hexdigest()
country = get_user_location(client_ip(self.request)).get('country_name', '')
device = user_agent.get('platform', {}).get('name', '')
browser = user_agent.get('browser', {}).get('name', '')
referrer = self.request.GET.get('ref', '')

if referrer:
    referrer = urlparse(referrer)
    referrer = '{uri.scheme}://{uri.netloc}/'.format(uri=referrer)

Hit.objects.get_or_create(
    post_id=self.pk,
    ip_address=ip_hash,
    referrer=referrer,
    country=country,
    device=device,
    browser=browser)
  • Hash IP hanya dipakai untuk mencegah hit duplikat dalam satu hari, dan setiap tampilan halaman pada dasarnya diperlakukan sebagai unik
  • Pada akhir setiap hari, pekerjaan latar belakang menghapus hash dari log hit agar tidak berbenturan dengan penafsiran GDPR yang terlalu ketat
  • Kekurangan pendekatan ini adalah jika dibaca di hari yang sama dari beberapa perangkat dengan alamat IP yang sama, itu tetap hanya dihitung sebagai satu read
  • Bear menilai kasus seperti ini hanyalah sebagian kecil dari trafik, dan menganggap pendekatan berbasis CSS memberi jumlah pembacaan yang lebih akurat sambil tetap lebih ringkas dan sederhana dibanding berbagai cara pengumpulan analitik lainnya

1 komentar

 
GN⁺ 2023-11-03
Komentar Hacker News
  • Saya penulisnya. Hash alamat IP dalam konteks ini hanya dipakai untuk mencegah tampilan duplikat dalam satu hari
    Tujuannya membuat setiap page view pada dasarnya unik, dan di akhir setiap hari sebuah tugas worker mengosongkan hash sambil tetap menyisakan informasi view. Saya juga menambahkan perubahan pada tulisan agar ini lebih jelas

    • Penasaran apakah pernah mempertimbangkan cara benar-benar menyajikan gambar transparan kecil dengan header cache privat yang kedaluwarsa pada tengah malam, dan sama sekali tidak menyimpan IP
    • Kalau 10 pengguna dari VPN bersama di seluruh dunia memakai IP yang sama dan masuk ke situs, apakah dihitung hanya sebagai 1 orang? Ada juga kasus seperti jaringan perusahaan; IP adalah metrik yang buruk
  • Saat pertama kali melihat ide memakai request yang dipicu oleh CSS untuk analitik, saya merasa itu benar-benar keren
    Seseorang di Twitter pernah menaruh grid kotak tak terlihat di atas halaman, lalu membuat tiap sel memuat gambar latar unik saat hover untuk pelacakan mouse. Tiap gambar latar mengirim request tertentu ke server, lalu server menafsirkannya
    Untuk iseng pada suatu musim panas, saya mengembangkan ide ini menjadi “chat web asinkron khusus CSS” tanpa JavaScript: https://github.com/kkuchta/css-only-chat

  • Mengklaim alamat IP dianonimkan hanya dengan meng-hash tanggal dan IP itu sekadar teater keamanan
    Hash kriptografis dirancang agar cepat dihitung. Dengan hashcat, MacBook M1 Pro bisa menghitung 6 miliar hash MD5 per detik, sementara alamat IPv4 hanya ada 4 miliar. Seluruh rentang bisa di-brute force untuk menemukan alamat IP, jadi pada praktiknya sama saja seperti membalikkan hash
    Bahkan jika memakai hash aman seperti SHA-256 alih-alih MD5 yang sudah rusak, hasilnya tetap sama

    • Terlepas dari fakta bahwa mendapatkan kembali IP dari hash itu secara teknis sepele, otoritas perlindungan data UE sudah sangat jelas bahwa meng-hash data pribadi bukan berarti menganonimkannya
      Sekalipun nama lengkap seseorang di-hash, nanti masih bisa dijawab pertanyaan “apakah hash ini cocok dengan nama lengkap tertentu ini?” Fakta bahwa pertanyaan ini bisa dijawab berarti proses anonimisasi tersebut dapat dibalik
    • Saya penulisnya. Saya juga menulis di bawah, tetapi ini tampaknya lebih relevan dengan thread ini
      Hash alamat IP dalam konteks ini hanya dipakai untuk mencegah tampilan duplikat dalam satu hari. Tujuannya membuat setiap page view pada dasarnya unik, dan di akhir setiap hari tugas worker menghapus hash IP yang kini sudah tidak diperlukan
    • Sebagai referensi, masalah yang sama juga muncul dalam diskusi ketika Storybook melakukan hal serupa pada telemetri[0], dan tanpa optimasi apa pun, di laptop rumah saya butuh sekitar dua jam untuk menghitung hash bersalt untuk semua IPv4
      [0] https://news.ycombinator.com/item?id=37596757
    • Hash harus diberi salt. Kalau memakai salt, tidak apa-apa; kalau tidak, tidak aman
      Apakah salt disimpan permanen atau diganti secara berkala hanyalah detail implementasi, dan poin utama saat memberi salt pada hash untuk analitik adalah salt tersebut sama sekali tidak pernah keluar dari klien
      Dari penjelasan artikel, sepertinya tidak ada salt. Atau mungkin tanggal saat ini dipakai seperti salt, tetapi itu bukan salt acak, sehingga siapa pun yang ingin tahu “apakah IP x.y.z.w berkunjung pada tanggal yy-mm-dd?” bisa menebaknya dengan mudah
      Dari sudut pandang penyerang, menilai masalah seperti ini mudah. Dengan data yang diberikan, bagaimana cara mengetahui sesuatu tentang orang tertentu? Jika tidak bisa, kemungkinan besar data itu pada umumnya aman untuk disimpan
    • Bukankah bisa memakai salt rahasia atau salt yang dirotasi? Karena tidak ada di kode contoh, rasanya kritik itu benar. Namun dengan menambahkan satu hal saja, ini bisa dibuat cukup masuk akal dan aman
      Namun saya khawatir teater keamanan seperti ini saja sudah cukup untuk lolos dari berbagai hukum dan regulasi terkait privasi
  • Ini memang terlihat cerdik, tetapi body:hover kemungkinan besar hampir sepenuhnya melewatkan pengguna khusus keyboard dan user agent yang tidak memakai perangkat penunjuk, yaitu pengguna teknologi bantu
    Kelompok seperti ini mungkin marginal, tetapi melihat mereka dikecualikan dengan cara apa pun selalu merupakan sinyal yang sangat buruk
    Saya tidak tahu, dan juga ragu, apakah dengan CSS dasar saja ada cara yang 100% andal di semua user agent untuk mendeteksi bahwa “pengguna nyata sedang membaca tulisan ini” dan mengirim request HTTP. Sebagian mungkin sama sekali tidak mendukung CSS atau menonaktifkan pemuatan gambar dekoratif CSS
    Selector modern yang mungkin membantu adalah :root:focus-within, tetapi pengguna harus benar-benar memberi fokus pada elemen interaktif, dan tidak semua user agent menjamin hal itu. @scroll-timeline, animasi mutakhir yang tersinkron dengan scroll, juga mungkin, tetapi pembaca braille kemungkinan tetap terlewat

    • Marginal? Bukankah ini memengaruhi ponsel dan tablet yang tidak mendukung :hover, yaitu lebih dari 50% user agent? Tentu saja jika tidak ada mouse yang terpasang
    • Dengan cara penulisan saat ini, pada perangkat yang memiliki pointer, ini bergantung pada posisi pointer. Jika pointer berada di dalam area 760px di tengah, ia aktif, tetapi jika di luar, tidak
      Area ini adalah lebar yang mencakup kolom konten dan padding 20px di kedua sisi. Jadi sebagian pengguna keyboard akan tercatat, sementara sebagian pengguna mouse, terutama yang memakai viewport besar, tidak akan tercatat
  • Pernyataan bahwa “bukan hanya hal buruk seperti Google Analytics, tetapi Fathom dan Plausible juga kesulitan mencatat aktivitas di browser pemblokir iklan” menurut saya karena mereka pada dasarnya mencoba bertahan hidup di padang tandus beracun
    Pengguna seperti kami sudah muak dengan seluruh konsep itu, jadi kalau analitik CSS menjadi populer, saya rasa akan muncul juga upaya untuk mengakalinya

    • Kenapa begitu?
      Saya secara manual membuka blokir Piwik/Matomo, Plausible, dan Fathom di uBlock. Saya tidak melihat ada bahaya dari apa dan bagaimana mereka melacak. Dan mereka memberi operator situs informasi yang berguna untuk “meningkatkan layanan”
      Misalnya, Plausible mengumpulkan lebih sedikit informasi tentang saya dibanding log nginx atau Apache biasa. Dari sudut pandang blogger, penting untuk melihat apakah sebuah tulisan naik ke HN, apakah ditautkan dari suatu tempat, serta konten mana yang dianggap bernilai dan mana yang diabaikan. Dengan begitu, mereka bisa menulis hal yang memang ingin dibaca orang dan menyebarkannya lewat kanal yang benar-benar bisa mereka ketahui
    • Memasukkan access.log server web ke layanan analitik tidak mencegah apa pun
      Justru, karena pada dasarnya mustahil menyaring semua traffic bot hanya dari user agent, angkanya bisa membengkak
    • Yang terasa seperti padang tandus beracun di web bagi saya adalah segala macam iklan. Pelacakan adalah persoalan yang jauh lebih subtil, dan dalam jangka panjang bahayanya adalah bisa terbentuk kembaran digital yang dapat dipakai bereksperimen untuk menemukan cara paling optimal memanipulasi saya
      Saya tidak tahu seberapa banyak orang yang benar-benar takut akan hal ini. Reaksinya mungkin terbelah dari “ya, itu menyeramkan” sampai “tidak masuk akal, itu cuma fiksi ilmiah”
    • Saya jadi teringat uMatrix, yang bahkan bisa memblokir pemuatan CSS
    • Cara ini tidak lebih sulit diblokir daripada cara berbasis JavaScript. Pada akhirnya ini hanya soal memblokir request ke pola URL tertentu
  • Ini sudah dikenal sejak puluhan tahun lalu sebagai pixel tracker

    • Juga dipakai di email. Memuat gambar transparan 1x1 lebih pasti daripada memicu event hover, tetapi pemblokir iklan sering memblokir gambar semacam itu
    • Benar. Namun kalau dilakukan dengan CSS, ada beberapa sisi menarik. Dengan memakai :hover, kita bisa menyaring bot yang tidak memakai WebDriver penuh, yaitu sebagian besar bot
      Dalam beberapa hal, mungkin lebih baik memuat file .css yang nyaris kosong melalui @import bersama supports. Pemblokir iklan sangat pandai menemukan pixel pelacak transparan 1px, tetapi kemungkinan lebih enggan memblokir file .css agar tidak merusak layout. Namun dalam kasus ini, keunggulan cerdas dari :hover hilang
  • Ini pertanyaan yang benar-benar membuat saya penasaran, tapi saya khawatir akan terbaca seperti pendapat yang meremehkan. Apa tujuan mengumpulkan data analitik di blog pribadi nonkomersial yang tampak seperti Bearblog?

    • Saya bisa menjawab dari sudut pandang penulis yang sudah konsisten ngeblog sejak sekitar tahun 2000 dan sepanjang waktu sangat tertarik pada “statistik”
      Alasan utama tertarik pada analitik adalah untuk melihat apakah tulisan dibaca. Di permukaan, dan dalam beberapa hal, ini karena kesombongan, tetapi sebenarnya ini tentang koneksi antara penulis dan pembaca. Saya benar-benar penasaran terhadap apa yang direspons pembaca, dan ingin memberi mereka lebih banyak hal seperti itu. “Hal seperti itu” bisa berupa topik, nada tulisan, atau panjang tulisan. Ini membantu saya memoles bahan agar cocok dengan pembaca saya. Pada akhirnya, saya bisa menulis dua belas topik dengan dua puluh empat cara. Tentu saya menulis hal yang saya sukai, tetapi saya memolesnya agar lebih mengena bagi pembaca
      Dalam arti ini, analitik juga merupakan cara mengenal pembaca. Di blog dengan tingkat keterlibatan tinggi, analitik memberi semacam potret samar tentang pembaca. Saya bisa melihat bukan hanya apa yang mereka sukai, tetapi juga kapan mereka menyukainya. Saya bisa tahu apakah mereka membaca pertama kali di pagi hari, saat makan siang, atau larut malam, dan itu membantu saya memutuskan kapan harus menerbitkan sesuatu atau merasa lebih yakin dengan keputusan itu. Tentu semuanya informasi yang kabur, tetapi benar-benar membantu saya terhubung lebih aktif dengan pembaca
    • Karena feedback loop. Berbeda dari anggapan banyak orang, analitik bukan hanya untuk iklan atau penjualan data, melainkan untuk menganalisis performa situs dan konten
      Tentu bisa dipakai untuk iklan dan bisa disalahgunakan, tetapi jika saya ingin umpan balik atas apa yang saya lakukan, itu penting
      Entah situs dibaca 12 orang atau 12.000 orang, mungkin tidak ada nilai finansialnya. Namun dari sudut pandang pribadi, baik untuk mengetahui apa yang ingin orang baca dari saya, merasa bahwa waktu yang dihabiskan untuk menulis dipakai dengan baik, dan jika mau, menyesuaikannya ke arah yang lebih populer
    • Mungkin karena rasa ingin tahu? Saya ingin tahu apakah ada orang yang membaca apa yang saya tulis. Mengetahui apa yang diminati orang juga berguna
      Bahkan blogger pribadi pun mungkin ingin menyesuaikan konten dengan pembaca. Bagus untuk mengetahui bahwa tulisan tentang satu topik dibaca 500 orang, sementara tulisan tentang topik lain hanya dibaca 3 orang
  • Awal tahun ini saya sempat mencoba membuat hal seperti ini, tetapi kehilangan motivasi saat membuat UI web. Cara saya bukan CSS, melainkan sekadar memuat gambar palsu dengan tag
    https://github.com/nolytics

  • Kenapa tidak mengambil informasi ini langsung dari server HTTP?

    • Di tulisan blog dijelaskan seperti ini
      “Selalu ada opsi untuk mem-parsing log server, dan itu bisa memberi gambaran kasar tentang jenis traffic yang mengakses server. Namun secara umum semua traffic server terlihat sama. Secara teknis bot seharusnya memiliki user agent yang mengidentifikasi dirinya sebagai bot, tetapi karena mereka mencoba mengeruk informasi seperti ‘manusia’ yang memakai browser, mereka hampir tidak pernah mengidentifikasi diri seperti itu. Pada dasarnya, kalau hanya memakai log server untuk analitik, traffic akan terlihat terdistorsi karena banyak crawler mesin pencari, scraper, dan kini parser berbasis GPT”
    • Semua bot ikut tercampur
    • Sulit kalau dijalankan secara serverless
  • Bagaimana data analitik disimpan?
    Bayangkan ada situs e-commerce dan ada produk yang ingin dijual. Selain analitik, diputuskan untuk mencatat langsung sebagian tindakan, seperti kunjungan ke halaman detail produk saat pengguna sedang login. Jadi ingin menyimpan hal-hal seperti ID pengguna, ID produk, dan timestamp
    Sebenarnya harus disimpan bagaimana? Secara naif, saya mengira cukup dimasukkan ke tabel. DBA bertanya berapa lama data itu diperlukan, dan saya menjawab minimal satu bulan. Lalu ia bilang baik, dan sepertinya ia menjadwalkan pekerjaan untuk memindahkan data yang lebih lama ke tabel lain
    Dalam praktiknya, bagaimana log seperti ini disimpan, dan berapa lama biasanya disimpan?

    • Jika skalanya tidak sangat besar, memasukkannya ke tabel Postgres sepenuhnya tidak masalah. Bahkan untuk skala besar, tabel bisa dipartisi berdasarkan tanggal atau atribut lain yang sesuai agar tidak perlu menangani indeks raksasa
      Saya pernah melakukannya seperti ini, dan sampai sekitar 1 miliar baris pun belum perlu memikirkan partisi. Meski begitu, sebaiknya lakukan partisi lebih awal dari itu. Pengalaman tersebut tidak menyenangkan
    • Database untuk analitik lebih baik. Contohnya ClickHouse atau BigQuery
      Agregasi bisa dilakukan jauh lebih cepat, dan database seperti ini juga menangani banyak kolom yang jarang terisi dengan baik. Misalnya event paid memiliki atribut amount, sedangkan event page_view memiliki atribut url
    • Saya menyimpan data 13 tahun di MySQL. Skalanya 5 juta pengunjung per tahun. Melakukan query di sana sangat menyakitkan, jadi saya juga mempertahankan salinannya di ClickHouse. ClickHouse benar-benar nyaman untuk query
    • Saya memakai Postgres dan TimescaleDB. Selama situs e-commerce-nya bukan sebesar amazon.com, ini berjalan dengan baik
      Hal bagus dari TimescaleDB adalah ia menangani sendiri pembuatan materialized view untuk agregasi yang diminati, seperti jumlah tampilan produk per jam. Jika ada banyak event dan Anda ingin menghindari database menjadi terlalu besar, Anda juga bisa memilih untuk “membuang” event itu sendiri dan hanya menyisakan agregasinya
    • ClickHouse