Ha valaha is használt webes felületeket a naplók megtekintéséhez, akkor valószínűleg észrevette, hogy ezek a felületek általában nehézkesek és (gyakran) nem túl kényelmesek és érzékenyek. Néhányat meg lehet szokni, van, amelyik teljesen szörnyű, de számomra úgy tűnik, hogy minden probléma oka az, hogy helytelenül közelítjük meg a naplók megtekintésének feladatát: megpróbálunk létrehozni egy webes felületet, ahol a CLI (parancssori felület) jobban működik. Én személy szerint nagyon kényelmesen tudok dolgozni a tail-el, grep-pel, awk-kal és másokkal, ezért számomra az ideális interfész a naplókkal való munkához valami hasonló lenne a tail-hoz és a grep-hez, de ez is használható számos szerverről származó naplók olvasására. Ez persze olvassa el őket a ClickHouse-ból!
*a habra használó személyes véleménye szerint
Ismerje meg a logscli-t
Nem én találtam ki nevet a felületemnek, és hogy őszinte legyek, inkább prototípus formájában létezik, de ha azonnal látni szeretnéd a forráskódot, akkor szívesen látod:
Képességek
Célom az volt, hogy egy olyan felületet készítsek, ami ismerősnek tűnik a tail/grep-hez szokottak számára, vagyis az alábbi dolgokat támogatja:
- Az összes napló megtekintése szűrés nélkül.
- Hagyja meg a rögzített részkarakterláncot tartalmazó sorokat (jelző
-F
уgrep
). - Hagyjon meg olyan sorokat, amelyek megfelelnek a reguláris kifejezésnek (jelző
-E
уgrep
). - Alapértelmezés szerint a megtekintés fordított időrendben történik, mivel általában a legfrissebb naplók érdekesek először.
- Kontextus megjelenítése az egyes sorok mellett (opciók
-A
,-B
и-C
уgrep
, N sort nyomtat az egyes egyező sorok elé, utána és köré). - Megtekintheti a bejövő naplókat valós időben, szűréssel vagy anélkül (lényegében
tail -f | grep
). - Az interfésznek kompatibilisnek kell lennie
less
,head
,tail
és mások - alapértelmezés szerint az eredményeket a számuk korlátozása nélkül kell visszaküldeni; a sorokat adatfolyamként nyomtatják ki, amíg a felhasználót érdekli a fogadás; jelSIGPIPE
csendben meg kell szakítaniuk a naplózást, ahogy ők tesziktail
,grep
és egyéb UNIX segédprogramok.
Реализация
Feltételezem, hogy valamilyen módon már tudja, hogyan kell naplókat eljuttatni a ClickHouse-hoz. Ha nem, akkor azt javaslom, próbálja ki
Először el kell döntenie az alaprendszert. Mivel általában idő szerint rendezett naplókat szeretne kapni, logikusnak tűnik, hogy így tárolja őket. Ha sok naplókategória van, és mindegyik azonos típusú, akkor létrehozhat egy naplókategóriát az elsődleges kulcs első oszlopaként - ez lehetővé teszi, hogy több helyett egy tábla legyen, ami nagy előnyt jelent, ha beszúrás a ClickHouse-ba (merevlemezes szervereken legfeljebb ~1 alkalommal ajánlott beszúrni az adatokat másodpercenként az egész szerverre).
Vagyis hozzávetőlegesen a következő táblázatsémára van szükségünk:
CREATE TABLE logs(
category LowCardinality(String), -- категория логов (опционально)
time DateTime, -- время события
millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)
Sajnos nem találtam azonnal nyílt forráskódot valósághű naplókkal, amelyeket meg tudtam fogni és letölteni, ezért inkább ezt vettem példaként
utasítások az Amazon-vélemények ClickHouse-ba való feltöltéséhez
Hozzunk létre egy táblázatot:
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
Az Amazon adathalmazában csak egy áttekintés dátuma van, de pontos idő nincs, ezért töltsük ki ezeket az adatokat véletlenszerűen.
Nem kell letöltenie az összes tsv fájlt, és az első ~ 10-20-ra korlátozni magát ahhoz, hogy meglehetősen nagy adathalmazt kapjon, amely nem fér bele a 16 GB RAM-ba. A TSV-fájlok feltöltéséhez a következő parancsot használtam:
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
Egy szabványos Persistent Disk-en (ami egy HDD) a Google Cloudban 1000 GB-os méretben (ezt a méretet főleg azért vettem, hogy kicsit nagyobb legyen a sebesség, bár talán olcsóbb lett volna egy megfelelő méretű SSD) a feltöltés a sebesség körülbelül ~ 75 MB/sec volt 4 magon.
- Le kell foglalnom, hogy a Google-nál dolgozom, de személyes fiókot használtam, és ennek a cikknek semmi köze a cégnél végzett munkámhoz
Az összes illusztrációt ezzel a konkrét adatkészlettel készítem, mivel csak ez volt a kezemben.
Az adatok szkennelésének folyamatának megjelenítése
Mivel a ClickHouse-ban teljes vizsgálatot fogunk végezni egy naplókkal ellátott táblázaton, és ez a művelet jelentős időt vehet igénybe, és hosszú ideig nem hoz eredményt, ha kevés egyezést találunk, célszerű megmutatni a a lekérdezés előrehaladását, amíg meg nem érkezik az eredményt tartalmazó első sor. Ehhez a HTTP-felületen van egy paraméter, amely lehetővé teszi a HTTP-fejlécekben történő előrehaladást: send_progress_in_http_headers=1
. Sajnos a szabványos Go könyvtár nem tudja beolvasni a fejléceket a beérkezésükkor, de a HTTP 1.0 felületet (nem tévesztendő össze az 1.1-gyel!) támogatja a ClickHouse, így nyers TCP-kapcsolatot nyithat a ClickHouse-hoz és elküldheti oda. GET /?query=... HTTP/1.0nn
és megkapjuk a válaszfejléceket és a törzset mindenféle menekülés vagy titkosítás nélkül, így ebben az esetben nem is kell a szabványos könyvtárat használnunk.
Naplók streamelése a ClickHouse-ból
A ClickHouse viszonylag hosszú ideje (2019 óta?) optimalizálja a lekérdezéseket az ORDER BY-val, így egy olyan lekérdezés, mint pl.
SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESC
Azonnal elkezdi visszaadni azokat a sorokat, amelyek üzenetében a "valami" részkarakterlánc szerepel, anélkül, hogy megvárná a vizsgálat befejezését.
Ezenkívül nagyon kényelmes lenne, ha a ClickHouse maga törölné a kérést, amikor a kapcsolat megszakadt, de ez nem az alapértelmezett viselkedés. A kérés automatikus törlése az opcióval engedélyezhető cancel_http_readonly_queries_on_client_close=1
.
A SIGPIPE helyes kezelése Go-ban
Amikor végrehajtja, mondjuk, a parancsot some_cmd | head -n 10
, pontosan hogyan a parancs some_cmd
leállítja a végrehajtást, amikor head
kivont 10 sort? A válasz egyszerű: mikor head
véget ér, a cső bezárul, és a some_cmd parancs stdoutja feltételesen a „semmibe” kezd mutatni. Amikor some_cmd
zárt csőre próbál írni,
A Go-ban ez is megtörténik alapból, de a SIGPIPE jelkezelő a "signal: SIGPIPE" vagy hasonló üzenetet is kiírja a végére, és ennek az üzenetnek a törléséhez csak magunknak kell kezelnünk a SIGPIPE-ot úgy, ahogy akarjuk, vagyis csak csendben. kijárat:
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
<-ch
os.Exit(0)
}()
Üzenetkörnyezet megjelenítése
Gyakran szeretné látni azt a kontextust, amelyben valamilyen hiba történt (például melyik kérés okozott pánikot, vagy milyen kapcsolódó problémák voltak láthatók az összeomlás előtt), és grep
Ez az -A, -B és -C opciókkal történik, amelyek az üzenet után, előtt és körül megadott sorok számát mutatják.
Sajnos nem találtam egyszerű módot erre a ClickHouse-ban, ezért a kontextus megjelenítéséhez az eredmény minden sorába egy ehhez hasonló kérést küldenek (a részletek a rendezéstől és a kontextus megjelenítésétől függenek vagy utána):
SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1
Mivel a kérés szinte azonnal elküldésre kerül, miután a ClickHouse visszaadja a megfelelő sort, így a gyorsítótárba kerül, és általában a kérés elég gyorsan végrehajtódik, és kevés CPU-t fogyaszt (általában a kérés kb. 6 ms-t vesz igénybe a virtuális gépemen).
Jelenítse meg az új üzeneteket valós időben
Annak érdekében, hogy a bejövő üzeneteket (majdnem) valós időben jelenítsük meg, egyszerűen néhány másodpercenként végrehajtjuk a kérést, emlékezve a legutóbbi időbélyegzőre, amellyel korábban találkoztunk.
Parancspéldák
Hogyan néznek ki a tipikus logscli parancsok a gyakorlatban?
Ha letöltötte a cikk elején említett Amazon adatkészletet, akkor a következő parancsokat futtathatja:
# Показать строки, где встречается слово 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
referenciák
A segédprogram kódja (dokumentáció nélkül) elérhető a githubon a címen
Forrás: will.com