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
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:
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ı:
- Tüm günlükleri filtrelemeden görüntüleyin.
- Sabit bir alt dize içeren satırları bırakın (bayrak
-F
уgrep
). - Normal ifadeyle eşleşen satırları bırakın (bayrak
-E
уgrep
). - 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.
- 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). - Filtrelemeli veya filtrelemesiz olarak gelen günlükleri gerçek zamanlı olarak görüntüleyin (esasen
tail -f | grep
). - 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; sinyalSIGPIPE
tıpkı yaptıkları gibi günlük akışını sessizce kesmelitail
,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
Ö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.
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,
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:
Kaynak: habr.com