Günlükleri görüntülemek için dünyanın en kullanışlı arayüzünü geliştiriyoruz*

Günlükleri görüntülemek için dünyanın en kullanışlı arayüzünü geliştiriyoruz* Günlükleri görüntülemek için web arayüzlerini kullandıysanız, muhtemelen bu arayüzlerin kural olarak ne kadar hantal olduğunu ve (çoğunlukla) pek kullanışlı ve duyarlı olmadığını fark etmişsinizdir. Bazıları alışabilirsiniz, bazıları kesinlikle berbat, ama bana öyle geliyor ki tüm sorunların nedeni, günlükleri görüntüleme görevine yanlış yaklaşmamız: CLI'nin (komut satırı arayüzü) bulunduğu bir web arayüzü oluşturmaya çalışıyoruz. daha iyi çalışır. Ben kişisel olarak tail, grep, awk ve diğerleriyle çalışırken çok rahatım ve bu nedenle benim için günlüklerle çalışmak için ideal arayüz, tail ve grep'e benzer bir şey olurdu, ancak bu aynı zamanda birçok sunucudan gelen günlükleri okumak için de kullanılabilir. Yani elbette bunları ClickHouse'dan okuyun!

*habra kullanıcısının kişisel görüşüne göre harikasın

logscli ile tanışın

Arayüzüm için bir isim bulamadım ve dürüst olmak gerekirse, daha çok bir prototip biçiminde var, ancak kaynak kodunu hemen görmek istiyorsanız, hoş geldiniz: https://github.com/YuriyNasretdinov/logscli (Seçili Go kodunun 350 satırı).

fırsatlar

Amacım, tail/grep'e alışkın olanlara tanıdık gelecek, yani aşağıdaki şeyleri destekleyecek bir arayüz oluşturmaktı:

  1. Tüm günlükleri filtrelemeden görüntüleyin.
  2. Sabit bir alt dize içeren satırları bırakın (bayrak -F у grep).
  3. Normal ifadeyle eşleşen satırları bırakın (bayrak -E у grep).
  4. En yeni günlükler genellikle ilk önce ilgi çekici olduğundan, görüntüleme varsayılan olarak ters kronolojik sırada yapılır.
  5. Her satırın yanında bağlamı göster (seçenekler -A, -B и -C у grep, eşleşen her satırın öncesinde, sonrasında ve çevresinde sırasıyla N satır yazdırılır).
  6. Filtrelemeli veya filtrelemesiz olarak gelen günlükleri gerçek zamanlı olarak görüntüleyin (esasen tail -f | grep).
  7. Arayüz uyumlu olmalıdır less, head, tail ve diğerleri - varsayılan olarak sonuçlar, sayılarında herhangi bir kısıtlama olmaksızın döndürülmelidir; satırlar, kullanıcı bunları almakla ilgilendiği sürece bir akış olarak yazdırılır; sinyal SIGPIPE tıpkı yaptıkları gibi günlük akışını sessizce kesmeli tail, grep ve diğer UNIX yardımcı programları.

uygulama

Günlüklerin ClickHouse'a nasıl teslim edileceğini zaten bir şekilde bildiğinizi varsayacağım. Değilse denemenizi tavsiye ederim lsd и yavru kedi eviVe günlük teslimiyle ilgili bu makale.

Öncelikle temel şemaya karar vermelisiniz. Günlükleri genellikle zamana göre sıralanmış olarak almak istediğinizden, bunları bu şekilde saklamak mantıklı görünmektedir. Çok sayıda günlük kategorisi varsa ve hepsi aynı türdeyse, birincil anahtarın ilk sütunu olarak bir günlük kategorisi oluşturabilirsiniz; bu, birkaç tablo yerine bir tabloya sahip olmanızı sağlar; bu, büyük bir artı olacaktır. ClickHouse'a ekleme (sabit diskli sunucularda, saniyede ~1 defadan fazla veri girilmemesi önerilir) tüm sunucu için).

Yani, yaklaşık olarak aşağıdaki tablo şemasına ihtiyacımız var:

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

Ne yazık ki yakalayıp indirebileceğim gerçekçi günlüklere sahip herhangi bir açık kaynağı hemen bulamadım, bu yüzden bunu örnek olarak aldım. 2015'e kadar Amazon'daki ürünlerin incelemeleri. Elbette bunların yapısı metin günlüklerininkiyle tam olarak aynı değildir ancak örnekleme amacıyla bu önemli değildir.

Amazon incelemelerini ClickHouse'a yükleme talimatları

Bir tablo oluşturalım:

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

Amazon veri kümesinde inceleme için yalnızca bir tarih vardır ancak kesin bir zaman yoktur, bu nedenle bu verileri rastgele bir şekilde dolduralım.

10 GB RAM'e sığmayacak kadar büyük bir veri kümesi elde etmek için tüm tsv dosyalarını indirmenize ve kendinizi ilk ~20-16 ile sınırlamanıza gerek yok. TSV dosyalarını yüklemek için aşağıdaki komutu kullandım:

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

Google Cloud'da 1000 GB boyutunda standart bir Kalıcı Diske (bir HDD olan) (bu boyutu esas olarak hızın biraz daha yüksek olması için aldım, ancak gerekli boyuttaki bir SSD belki daha ucuz olabilirdi) yükleme 75 çekirdekte hız yaklaşık ~ 4 MB/sn idi.

  • Google'da çalıştığım için rezervasyon yaptırmam gerekiyor ancak kişisel hesap kullandım ve bu makalenin şirketteki işim ile hiçbir ilgisi yok

Elimde olan tek şey bu olduğu için tüm illüstrasyonları bu özel veri kümesiyle üreteceğim.

Veri tarama ilerlemesini göster

ClickHouse'da günlüklerin bulunduğu bir tabloda tam tarama kullanacağımız ve bu işlemin önemli miktarda zaman alabileceği ve az sayıda eşleşme bulunursa uzun süre sonuç vermeyebileceği için, günlükleri gösterebilmeniz tavsiye edilir. sonucu içeren ilk satırlar alınana kadar sorgunun ilerleyişi. Bunu yapmak için, HTTP arayüzünde, ilerleme durumunu HTTP başlıklarında göndermenize izin veren bir parametre vardır: send_progress_in_http_headers=1. Ne yazık ki, standart Go kütüphanesi başlıkları alındığı gibi okuyamaz, ancak HTTP 1.0 arayüzü (1.1 ile karıştırılmamalıdır!) ClickHouse tarafından desteklenir, böylece ClickHouse'a ham bir TCP bağlantısı açabilir ve oraya gönderebilirsiniz. GET /?query=... HTTP/1.0nn ve yanıt başlıklarını ve gövdesini herhangi bir kaçış veya şifreleme olmadan alırız; dolayısıyla bu durumda standart kitaplığı kullanmamıza bile gerek kalmaz.

ClickHouse'dan günlük akışı

ClickHouse, nispeten uzun bir süredir (2019'dan beri?) ORDER BY ile sorgular için optimizasyona sahiptir, dolayısıyla şöyle bir sorgu

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

Taramanın bitmesini beklemeden, mesajlarında "bir şey" alt dizesini içeren satırları hemen döndürmeye başlayacaktır.

Ayrıca, ClickHouse'un bağlantı kapatıldığında isteği kendisinin iptal etmesi çok uygun olacaktır, ancak bu varsayılan davranış değildir. Otomatik istek iptali seçeneği kullanılarak etkinleştirilebilir cancel_http_readonly_queries_on_client_close=1.

Go'da SIGPIPE'ın doğru kullanımı

Diyelim ki komutu çalıştırdığınızda some_cmd | head -n 10, komut tam olarak nasıl some_cmd yürütmeyi durdurur head 10 satır mı çıkarıldı? Cevap basit: ne zaman head sona erer, kanal kapanır ve some_cmd komutunun stdout'u koşullu olarak "hiçbir yere" işaret etmeye başlar. Ne zaman some_cmd kapalı bir boruya yazmaya çalışır, varsayılan olarak programı sessizce sonlandıran bir SIGPIPE sinyali alır.

Go'da da bu varsayılan olarak gerçekleşir, ancak SIGPIPE sinyal işleyicisi aynı zamanda "sinyal: SIGPIPE" veya benzer bir mesajı da sonuna yazdırır ve bu mesajı temizlemek için SIGPIPE'yi kendimiz istediğimiz şekilde, yani sessizce ele almamız gerekir. çıkış:

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

Mesaj içeriğini göster

Çoğunlukla bazı hataların oluştuğu bağlamı (örneğin, hangi isteğin paniğe neden olduğu veya çökmeden önce hangi ilgili sorunların görünür olduğu) görmek istersiniz. grep Bu, sırasıyla mesajın ardından, öncesinde ve çevresinde belirtilen sayıda satırı gösteren -A, -B ve -C seçenekleri kullanılarak yapılır.

Maalesef aynısını ClickHouse'da yapmanın kolay bir yolunu bulamadım, dolayısıyla bağlamı görüntülemek için sonucun her satırına bunun gibi ek bir istek gönderilir (ayrıntılar sıralamaya ve bağlamın daha önce gösterilip gösterilmediğine bağlıdır). yada sonra):

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

İstek, ClickHouse ilgili satırı döndürdükten hemen sonra gönderildiğinden, önbellekte biter ve genel olarak istek oldukça hızlı bir şekilde yürütülür ve biraz CPU tüketir (genellikle istek sanal makinemde yaklaşık ~6 ms sürer).

Yeni mesajları gerçek zamanlı olarak göster

Gelen mesajları (neredeyse) gerçek zamanlı olarak göstermek için, daha önce karşılaştığımız son zaman damgasını hatırlayarak isteği birkaç saniyede bir yürütmemiz yeterlidir.

Komut örnekleri

Tipik logscli komutları pratikte neye benziyor?

Yazının başında bahsettiğim Amazon veri setini indirdiyseniz aşağıdaki komutları çalıştırabilirsiniz:

# Показать строки, где встречается слово 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

referanslar

Yardımcı program kodu (belgeler olmadan) github'da mevcuttur: https://github.com/YuriyNasretdinov/logscli. ClickHouse'a dayalı olarak günlükleri görüntülemek için bir konsol arayüzü fikrim hakkındaki düşüncelerinizi duymaktan memnuniyet duyarım.

Kaynak: habr.com

Yorum ekle