Kami sedang membangunkan antara muka yang paling mudah di dunia* untuk melihat log

Kami sedang membangunkan antara muka yang paling mudah di dunia* untuk melihat log Jika anda pernah menggunakan antara muka web untuk melihat log, maka anda mungkin perasan bagaimana, sebagai peraturan, antara muka ini menyusahkan dan (selalunya) tidak begitu mudah dan responsif. Sesetengah anda boleh membiasakan diri, ada yang benar-benar mengerikan, tetapi nampaknya saya alasan untuk semua masalah ialah kami mendekati tugas melihat log secara tidak betul: kami cuba mencipta antara muka web di mana CLI (antara muka baris arahan) berfungsi lebih baik. Saya secara peribadi sangat selesa bekerja dengan tail, grep, awk dan lain-lain, dan oleh itu bagi saya antara muka yang ideal untuk bekerja dengan log adalah sesuatu yang serupa dengan tail dan grep, tetapi yang juga boleh digunakan untuk membaca log yang datang dari banyak pelayan . Iaitu, sudah tentu, membacanya dari ClickHouse!

*mengikut pendapat peribadi pengguna habra kamu hebat

Bertemu logscli

Saya tidak menghasilkan nama untuk antara muka saya, dan, sejujurnya, ia wujud dalam bentuk prototaip, tetapi jika anda ingin segera melihat kod sumber, maka anda dialu-alukan: https://github.com/YuriyNasretdinov/logscli (350 baris kod Go yang dipilih).

peluang

Matlamat saya adalah untuk membuat antara muka yang kelihatan biasa kepada mereka yang terbiasa dengan ekor/grep, iaitu, untuk menyokong perkara berikut:

  1. Lihat semua log, tanpa penapisan.
  2. Biarkan baris yang mengandungi subrentetan tetap (bendera -F у grep).
  3. Tinggalkan baris yang sepadan dengan ungkapan biasa (bendera -E у grep).
  4. Secara lalai, tontonan adalah dalam susunan kronologi terbalik, kerana log terbaharu biasanya diutamakan yang diutamakan.
  5. Tunjukkan konteks di sebelah setiap baris (pilihan -A, -B и -C у grep, mencetak N baris sebelum, selepas, dan di sekeliling setiap baris yang sepadan, masing-masing).
  6. Lihat log masuk dalam masa nyata, dengan atau tanpa penapisan (pada asasnya tail -f | grep).
  7. Antara muka mesti serasi dengan less, head, tail dan lain-lain - secara lalai, keputusan harus dikembalikan tanpa sekatan pada nombor mereka; baris dicetak sebagai aliran selagi pengguna berminat untuk menerimanya; isyarat SIGPIPE sepatutnya mengganggu penstriman log secara senyap, sama seperti yang mereka lakukan tail, grep dan utiliti UNIX lain.

Реализация

Saya akan menganggap bahawa anda sudah tahu bagaimana untuk menghantar log ke ClickHouse. Jika tidak, saya cadangkan mencubanya lsd и rumah kucingDan artikel ini tentang penghantaran log.

Mula-mula anda perlu membuat keputusan mengenai skema asas. Memandangkan anda biasanya ingin menerima log yang diisih mengikut masa, nampaknya logik untuk menyimpannya dengan cara itu. Jika terdapat banyak kategori log dan kesemuanya daripada jenis yang sama, maka anda boleh menjadikan kategori log sebagai lajur pertama kunci utama - ini akan membolehkan anda mempunyai satu jadual dan bukannya beberapa, yang akan menjadi nilai tambah yang besar apabila memasukkan ke dalam ClickHouse (pada pelayan dengan pemacu keras, adalah disyorkan untuk memasukkan data tidak lebih daripada ~1 kali sesaat untuk keseluruhan pelayan).

Iaitu, kita memerlukan kira-kira skema jadual berikut:

CREATE TABLE logs(
    category LowCardinality(String), -- категория логов (опционально)
    time DateTime, -- время события
    millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
    ..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
    message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)

Malangnya, saya tidak dapat segera mencari sebarang sumber terbuka dengan log realistik yang boleh saya ambil dan muat turun, jadi saya mengambil ini sebagai contoh ulasan produk dari Amazon sebelum 2015. Sudah tentu, struktur mereka tidak betul-betul sama dengan log teks, tetapi untuk tujuan ilustrasi ini tidak penting.

arahan untuk memuat naik ulasan Amazon ke ClickHouse

Mari buat jadual:

CREATE TABLE amazon(
   review_date Date,
   time DateTime DEFAULT toDateTime(toUInt32(review_date) * 86400 + rand() % 86400),
   millis UInt16 DEFAULT rand() % 1000,
   marketplace LowCardinality(String),
   customer_id Int64,
   review_id String,
   product_id LowCardinality(String),
   product_parent Int64,
   product_title String,
   product_category LowCardinality(String),
   star_rating UInt8,
   helpful_votes UInt32,
   total_votes UInt32,
   vine FixedString(1),
   verified_purchase FixedString(1),
   review_headline String,
   review_body String
)
ENGINE=MergeTree()
ORDER BY (time, millis)
SETTINGS index_granularity=8192

Dalam set data Amazon hanya terdapat tarikh untuk semakan, tetapi tidak ada masa yang tepat, jadi mari kita isi data ini dengan randon.

Anda tidak perlu memuat turun semua fail tsv dan menghadkan diri anda kepada ~10-20 yang pertama untuk mendapatkan set data yang agak besar yang tidak sesuai dengan 16 GB RAM. Untuk memuat naik fail TSV saya menggunakan arahan berikut:

for i in *.tsv; do
    echo $i;
    tail -n +2 $i | pv |
    clickhouse-client --input_format_allow_errors_ratio 0.5 --query='INSERT INTO amazon(marketplace,customer_id,review_id,product_id,product_parent,product_title,product_category,star_rating,helpful_votes,total_votes,vine,verified_purchase,review_headline,review_body,review_date) FORMAT TabSeparated'
done

Pada Cakera Gigih standard (iaitu HDD) dalam Google Cloud dengan saiz 1000 GB (saya mengambil saiz ini terutamanya supaya kelajuannya lebih tinggi sedikit, walaupun mungkin SSD dengan saiz yang diperlukan mungkin lebih murah) muat naik kelajuan adalah lebih kurang ~ 75 MB/saat pada 4 teras.

  • Saya mesti membuat tempahan bahawa saya bekerja di Google, tetapi saya menggunakan akaun peribadi dan artikel ini tiada kaitan dengan kerja saya di syarikat itu

Saya akan menghasilkan semua ilustrasi dengan set data khusus ini, kerana ini sahaja yang saya ada.

Tunjukkan kemajuan pengimbasan data

Memandangkan dalam ClickHouse kami akan menggunakan imbasan penuh pada meja dengan log, dan operasi ini boleh mengambil masa yang banyak dan mungkin tidak menghasilkan apa-apa keputusan untuk masa yang lama jika beberapa perlawanan ditemui, adalah dinasihatkan untuk dapat menunjukkan kemajuan pertanyaan sehingga baris pertama dengan hasilnya diterima. Untuk melakukan ini, terdapat parameter dalam antara muka HTTP yang membolehkan anda menghantar kemajuan dalam pengepala HTTP: send_progress_in_http_headers=1. Malangnya, pustaka Go standard tidak boleh membaca pengepala semasa ia diterima, tetapi antara muka HTTP 1.0 (jangan dikelirukan dengan 1.1!) disokong oleh ClickHouse, jadi anda boleh membuka sambungan TCP mentah ke ClickHouse dan menghantarnya ke sana GET /?query=... HTTP/1.0nn dan menerima pengepala dan badan tindak balas tanpa sebarang melarikan diri atau penyulitan, jadi dalam kes ini kita tidak perlu menggunakan perpustakaan standard.

Menstrim log daripada ClickHouse

ClickHouse telah mempunyai pengoptimuman untuk pertanyaan dengan ORDER BY untuk masa yang agak lama (sejak 2019?), jadi pertanyaan seperti

SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESC

Ia akan mula mengembalikan baris dengan serta-merta yang mempunyai subrentetan "sesuatu" dalam mesejnya, tanpa menunggu imbasan selesai.

Juga, adalah sangat mudah jika ClickHouse sendiri membatalkan permintaan apabila sambungan kepadanya ditutup, tetapi ini bukan tingkah laku lalai. Pembatalan permintaan automatik boleh didayakan menggunakan pilihan cancel_http_readonly_queries_on_client_close=1.

Pengendalian SIGPIPE yang betul dalam Go

Apabila anda melaksanakan, katakan, perintah itu some_cmd | head -n 10, betul-betul bagaimana arahan itu some_cmd menghentikan pelaksanaan apabila head tolak 10 baris? Jawapannya mudah: bila head berakhir, paip ditutup, dan stdout perintah some_cmd mula menunjuk, secara bersyarat, "ke mana-mana". Bila some_cmd cuba menulis pada paip tertutup, ia menerima isyarat SIGPIPE, yang secara senyap menamatkan program secara lalai.

Dalam Go ini juga berlaku secara lalai, tetapi pengendali isyarat SIGPIPE juga mencetak "isyarat: SIGPIPE" atau mesej serupa pada penghujungnya, dan untuk mengosongkan mesej ini, kami hanya perlu mengendalikan SIGPIPE sendiri seperti yang kami mahu, iaitu, secara senyap. keluar:

ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
    <-ch
    os.Exit(0)
}()

Tunjukkan konteks mesej

Selalunya anda ingin melihat konteks di mana beberapa ralat berlaku (contohnya, permintaan yang menyebabkan panik, atau masalah berkaitan yang kelihatan sebelum ranap), dan dalam grep Ini dilakukan menggunakan pilihan -A, -B, dan -C, yang masing-masing menunjukkan bilangan baris yang ditentukan selepas, sebelum dan di sekeliling mesej.

Malangnya, saya tidak menemui cara mudah untuk melakukan perkara yang sama dalam ClickHouse, jadi untuk memaparkan konteks, permintaan tambahan seperti ini dihantar ke setiap baris hasil (butiran bergantung pada pengisihan dan sama ada konteks ditunjukkan sebelum ini. atau selepas):

SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1

Memandangkan permintaan dihantar hampir serta-merta selepas ClickHouse mengembalikan baris yang sepadan, ia berakhir dalam cache dan secara amnya permintaan itu dilaksanakan dengan cepat dan menggunakan sedikit CPU (biasanya permintaan mengambil masa kira-kira ~6 ms pada mesin maya saya).

Tunjukkan mesej baharu dalam masa nyata

Untuk menunjukkan mesej masuk dalam (hampir) masa nyata, kami hanya melaksanakan permintaan sekali setiap beberapa saat, mengingati cap masa terakhir yang kami temui sebelum ini.

Contoh perintah

Apakah rupa arahan logscli biasa dalam amalan?

Jika anda memuat turun set data Amazon yang saya nyatakan pada permulaan artikel, anda boleh menjalankan arahan berikut:

# Показать строки, где встречается слово walmart
$ logscli -F 'walmart' | less

# Показать самые свежие 10 строк, где встречается "terrible"
$ logscli -F terrible -limit 10

# То же самое без -limit:
$ logscli -F terrible | head -n 10

# Показать все строки, подходящие под /times [0-9]/, написанные для vine и у которых высокий рейтинг
$ logscli -E 'times [0-9]' -where="vine='Y' AND star_rating>4" | less

# Показать все строки со словом "panic" и 3 строки контекста вокруг
$ logscli -F 'panic' -C 3 | less

# Непрерывно показывать новые строки со словом "5-star"
$ logscli -F '5-star' -tailf

rujukan

Kod utiliti (tanpa dokumentasi) tersedia di github di https://github.com/YuriyNasretdinov/logscli. Saya berbesar hati mendengar pendapat anda tentang idea saya untuk antara muka konsol untuk melihat log berdasarkan ClickHouse.

Sumber: www.habr.com

Tambah komen