engineering6 minit bacaan

Perkara yang ditemui Sentry: kebolehcerapan, kestabilan dan perubahan kos memantau kod sendiri

Ralat produksi mendedahkan ketidakpadanan skema, pemulihan transaksi yang gagal dan log yang tidak membantu. Cara pasukan kecil menggunakan Sentry untuk membaiki kegagalan backend, menyediakan pemantauan pelayar dan mengawal hingar amaran.

K
Ken Jo

Dahulu, pasukan kejuruteraan sama ada melabur terlalu banyak dalam kebolehcerapan—misalnya seluruh organisasi SRE memasang papan pemuka yang tiada siapa baca—atau langsung mengabaikannya sehingga mengetahui perkhidmatan terhenti melalui e-mel pelanggan. Pada 2026, kedua-dua keterlaluan ini tidak boleh diterima. Anda perlu tahu perkara yang rosak, tetapi juga perlu mengetahuinya tanpa membayar harga perusahaan untuk produk indie.

Panduan ini menunjukkan cara integrasi Sentry mendedahkan ralat produksi, perubahan yang kami lakukan sebagai tindak balas, dan cara kami mengkonfigurasi pemantauan untuk mengawal hingar serta penggunaan. Kami turut melihat perkembangan alat kebolehcerapan untuk pasukan kejuruteraan kecil.

Mengapa amaran tidak mengesan kegagalan pelayar

Backend kami telah disambungkan ke Sentry sejak Mac. DSN berada dalam Google Secret Manager, rahsia dipasang pada Cloud Run dan sentry_sdk.init berjalan setiap kali aplikasi dimulakan. Amaran e-mel diterima. Dari luar, semuanya kelihatan baik.

Namun, keadaan sebenarnya berbeza. Frontend langsung belum disambungkan ke Sentry. Exception pelayar, ralat hydration dan kegagalan pemuatan chunk tidak kelihatan. Backend pula menghantar ralat Python ke projek bernama javascript-nextjs, satu-satunya projek dalam organisasi. Stack trace terkumpul di tempat yang salah, pengelompokan tidak berguna dan papan pemuka dipenuhi event daripada bahasa berlainan.

Menutup jurang ini bermaksud mengasingkan kegagalan pelayar daripada ralat backend sebelum menangani pepijat satu demi satu.

Perkara yang ditunjukkan oleh data

Kami mengambil event ralat sepanjang 90 hari terakhir. Beberapa corak ketara.

Insiden lama yang sudah dibaiki

Ralat paling kerap dalam tempoh itu ialah Postgres StringDataRightTruncation daripada endpoint pendaftaran sosial: 16 event dalam 22 saat. Puncanya ialah schema drift yang lazim: definisi model membenarkan bio sepanjang 800 aksara, tetapi lajur pangkalan data produksi masih VARCHAR(500) daripada migrasi terdahulu. Pengguna menghantar bio sedikit melebihi 500 aksara, lapisan Pydantic menerimanya, kemudian INSERT gagal.

Migrasi untuk meluaskan lajur kepada 800 sudah ditulis dan digunakan pada pagi berikutnya. Namun masalah asas—model dan skema DB boleh menyimpang tanpa disedari sehingga pelanggan mengalaminya—masih belum ditangani.

Kami melakukan dua perkara. Pertama, kami mengetatkan skema permintaan pendaftaran sosial dengan max_length yang dinyatakan secara jelas untuk e-mel, nama paparan dan token, supaya input luar biasa memulangkan 422 dengan kemas dan tidak sampai ke pangkalan data. Kedua, kami meluaskan skrip integriti DB supaya membandingkan information_schema.columns.character_maximum_length dengan panjang yang dijangka oleh aplikasi. Jika migrasi akan datang memendekkan lajur hingga kurang daripada nilai yang boleh dihasilkan model, pemeriksaan integriti pada deployment berikutnya akan gagal.

Sesi yang tidak dapat di-rollback

Lebih jauh dalam senarai, terdapat satu rangkaian: satu OperationalError: server closed the connection unexpectedly pada POST /v1/upload, diikuti banyak PendingRollbackError daripada laluan kod yang sama. Postgres memutuskan sambungan semasa kueri, sesi SQLAlchemy berada dalam keadaan tidak sah, kemudian perkhidmatan muat naik cuba menyimpan hasil separa menggunakan sesi tersebut. Setiap operasi berikutnya dalam sesi itu turut gagal.

Pembaikannya kecil tetapi mudah tersalah susunan. Apabila pipeline muat naik menangkap exception, perkara pertama yang kini dilakukan ialah db.rollback()—dibungkus dengan try/except tersendiri supaya rollback yang gagal tidak menutup ralat asal. Selepas itu, logik penyimpanan separa berjalan menggunakan sesi yang bersih.

Log yang memadamkan maklumatnya sendiri

Pengendali tamat WebSocket mencatat exception yang ditangkap menggunakan err=%s. Bagi kebanyakan exception, hasilnya berguna. Tetapi beberapa jenis exception mempunyai __str__ yang memulangkan rentetan kosong, lalu log hanya menunjukkan err= tanpa butiran. Event Sentry memberitahu kami bahawa penyimpanan gagal tetapi tidak menjelaskan sebabnya.

Menukar kepada logger.exception(...) dan err=%r tidak memerlukan kos, dan menjadikan setiap event akan datang lebih bermaklumat.

Hingar yang tidak mahu kami bayar

Item lain dalam baris gilir bukan pepijat. uvloop kadangkala mengeluarkan RuntimeError: unable to perform operation on <TCPTransport closed=True> apabila klien terputus di tengah-tengah SSL. Itu tingkah laku yang betul, bukannya sesuatu yang perlu dibaiki. Dengan kuota percuma 5,000 ralat sebulan, event tersebut membazirkan had. Kami menambah penapis before_send untuk menggugurkan corak exception/nilai khusus itu. Di frontend, pendekatan sama digunakan untuk hingar pelayar seperti ResizeObserver loop limit exceeded.

Melaraskan penggunaan untuk pelan percuma

Setakat 13 Oktober 2026, pelan percuma Sentry Developer merangkumi 5,000 ralat, 5 juta span penjejakan dan 50 replay sebulan. Penjejakan diukur dalam span, bukannya unit prestasi lama. Semak had pelan semasa sebelum memilih kadar pensampelan: kuota ralat bukan bajet untuk semua isyarat yang boleh dihantar oleh SDK.

Tetapan kami:

  • tracesSampleRate: 0 pada backend dan frontend. Distributed tracing memang berguna, tetapi dengan 10K unit prestasi sebulan, satu petang yang buruk boleh menghabiskan bajet. Kami boleh menghidupkannya dengan kadar pensampelan rendah apabila menyiasat masalah khusus.
  • profilesSampleRate: 0 pada backend, atas sebab yang sama.
  • Session Replay dimatikan pada frontend. Kod integrasi dikekalkan tetapi kedua-dua kadar pensampelan ditetapkan kepada sifar. Jika pepijat kritikal memerlukan konteks replay untuk dinyahpepijat, kami boleh menetapkan replaysOnErrorSampleRate kepada 0.05 selama sehari dan mematikannya semula.
  • Penapis before_send pada kedua-dua runtime menggugurkan event yang diketahui tidak memerlukan tindakan.

Perubahan backend mengurangkan hingar ralat yang boleh ditindaklanjuti, manakala konfigurasi SDK pelayar disediakan untuk pengaktifan. Itu dua pencapaian yang berbeza: kod dan tetapan pensampelan sahaja tidak membuktikan event pelayar sampai ke projek yang dimaksudkan.

Perubahan dalam pasaran kebolehcerapan

Kami melaras penggunaan untuk pelan percuma kerana pelan percuma Sentry agak luas bagi produk terhos. Namun, perkembangan lebih besar juga wajar difahami kerana ekonomi bidang ini sedang berubah.

Beberapa perkara berubah dalam tempoh 12 hingga 18 bulan lalu:

  • Piawaian terbuka mengurangkan kerja migrasi, bukan menghapuskan semua kerja. Instrumentasi yang serasi dengan OTLP boleh mengurangkan kebergantungan pada backend pemantauan. Kueri khusus vendor, papan pemuka, peraturan amaran dan ciri SDK masih perlu dirancang serta diuji apabila berpindah.
  • Pengehosan sendiri mengubah pengiraan kos. Pilihan seperti GlitchTip dan stack asli OTLP menawarkan laluan pemantauan lain. Bandingkan storan, sandaran, naik taraf dan masa kejuruteraan dengan pelan terhos, bukan sekadar bil mesin maya dengan harga langganan.
  • Penyahpepijatan berbantu AI meluaskan aliran kerja. Seer daripada Sentry mencadangkan punca akar dan patch, sementara integrasi MCP yang dibenarkan boleh membawa konteks ralat ke pembantu pengekodan. Cadangan pembaikan tetap perlu dihasilkan semula dan diuji regresinya sebelum keluaran.
  • Had pelan perlu diberi perhatian sama seperti ciri. Jumlah ralat, tempoh pengekalan, pensampelan dan akses pasukan boleh mempengaruhi bil. Mulakan dengan isyarat yang diperlukan dan bajet event yang diukur, kemudian bandingkan pelan berdasarkan beban kerja itu.

Pada snapshot keluaran ini, Sentry memenuhi keperluan pemantauan ralat segera kami. Penggunaan antara muka terbuka apabila tersedia memberi pasukan lebih banyak pilihan kemudian, tetapi pertukaran vendor masih memerlukan semakan routing projek, amaran, data tersimpan dan ciri khusus penyedia.

Pemeriksaan deployment melengkapkan persediaan pemantauan

Pada snapshot artikel bertarikh 17 Mei 2026, dua tugas deployment masih belum selesai:

  1. Cipta projek Sentry Python khusus supaya ralat backend tidak lagi direkodkan di bawah javascript-nextjs. DSN ditukar dalam entri Secret Manager yang sama seperti yang sudah dibaca oleh backend.
  2. Masukkan DSN frontend dalam tetapan projek Vercel supaya ralat sisi klien mula dihantar. Kodnya sudah tersedia dan dimulakan secara bersyarat; yang masih tiada hanyalah pemboleh ubah persekitaran.

Untuk setiap pelaksanaan pemantauan, hantar event ujian terkawal daripada setiap runtime dan sahkan projek, persekitaran, pengelompokan serta konteksnya sebelum menyatakan integrasi selesai. Pengasingan projek dan pemboleh ubah persekitaran ialah langkah persediaan, bukannya bukti event telah diterima.

Mengapa ini penting

Apabila anda tidak dapat melihat perkara yang rosak, anda mungkin melabur terlalu banyak dalam kod defensif atau terlalu sedikit lalu menghantar pepijat. Kedua-duanya mahal. Kebolehcerapan yang murah dan boleh dipercayai membolehkan pasukan kecil beroperasi seperti pasukan lebih besar: mengesan regresi sebelum pelanggan menyedarinya, membaikinya tanpa meneka, dan menggunakan masa kejuruteraan untuk membina perkara baharu.

Pengajaran utamanya ialah mengesahkan kedua-dua bahagian: pembaikan aplikasi dan laluan pemantauan yang sepatutnya mendedahkan regresi seterusnya.


← Kembali ke blog