Inoiz web interfazeak erabili badituzu erregistroak ikusteko, seguruenik ohartu zara nola, normalean, interfaze hauek astunak diren eta (askotan) ez dira oso erosoak eta erantzuten. Batzuk ohitu zaitezke, beste batzuk erabat ikaragarriak dira, baina iruditzen zait arazo guztien arrazoia erregistroak ikusteko zereginari gaizki heltzea dela: web interfaze bat sortzen saiatzen gara non CLI (komando-lerroko interfazea) hobeto funtzionatzen du. Ni pertsonalki oso gustura nago tail, grep, awk eta beste batzuekin lan egiten, eta, beraz, niretzat erregistroekin lan egiteko interfaze aproposa tail eta grep-en antzeko zerbait izango litzateke, baina zerbitzari askotako erregistroak irakurtzeko ere erabil daitekeena. Hau da, noski, irakur itzazu ClickHouse-tik!
*habra erabiltzailearen iritzi pertsonalaren arabera
Ezagutu logscli
Ez nuen nire interfazearen izenik asmatu, eta, egia esateko, prototipo baten moduan existitzen da, baina iturburu-kodea berehala ikusi nahi baduzu, ongi etorria zara:
Capabilities
Nire helburua tail/grep egiteko erabiltzen direnei ezaguna irudituko zitzaien interfaze bat egitea zen, hau da, honako gauza hauek onartzea:
- Ikusi erregistro guztiak, iragazi gabe.
- Utzi azpikate finko bat duten lerroak (bandera
-F
уgrep
). - Utzi adierazpen erregulararekin bat datozen lerroak (bandera
-E
уgrep
). - Lehenespenez, alderantzizko ordena kronologikoan ikusten da, izan ere, azken erregistroak interesgarri izaten dira lehenik.
- Erakutsi testuingurua lerro bakoitzaren ondoan (aukerak
-A
,-B
и-C
уgrep
, bat datozen lerro bakoitzaren aurretik, ondoren eta inguruan N lerro inprimatuz, hurrenez hurren). - Ikusi sarrerako erregistroak denbora errealean, iragazkiarekin edo gabe (funtsean
tail -f | grep
). - Interfazeak bateragarria izan behar du
less
,head
,tail
eta beste batzuk - lehenespenez, emaitzak beren kopuruaren mugarik gabe itzuli behar dira; lerroak korronte moduan inprimatzen dira, erabiltzaileak jasotzeko interesa duen bitartean; seinaleaSIGPIPE
isilean eten beharko luke erregistroen streaming, haiek egiten duten bezalatail
,grep
eta beste UNIX utilitate batzuk.
Inplementazioa
Suposatuko dut dagoeneko badakizula nolabait ClickHouse-ra erregistroak nola entregatu. Hala ez bada, probatzea gomendatzen dut
Lehenik eta behin, oinarrizko eskema erabaki behar duzu. Normalean erregistroak denboraren arabera ordenatuta jaso nahi dituzunez, logikoa dirudi horrela gordetzea. Erregistro-kategoria asko badaude eta denak mota berekoak badira, orduan erregistro-kategoria bat egin dezakezu gako nagusiaren lehen zutabe gisa; honek hainbat mahai bat edukitzea ahalbidetuko du, eta hori abantaila handia izango da. ClickHouse-n txertatzea (disko gogorrak dituzten zerbitzarietan, datuak ~1 aldiz segundoko gehienez ez txertatzea gomendatzen da zerbitzari osorako).
Hau da, taula eskema hau gutxi gorabehera behar dugu:
CREATE TABLE logs(
category LowCardinality(String), -- категория логов (опционально)
time DateTime, -- время события
millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)
Zoritxarrez, ezin izan dut berehala aurkitu eta deskargatu nezakeen erregistro errealistadun iturri irekirik aurkitu, beraz, hau hartu dut adibide gisa.
Amazonen iritziak ClickHousera kargatzeko argibideak
Sortu dezagun taula:
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 datu-multzoan berrikuspenerako data besterik ez dago, baina ez dago ordu zehatzik, beraz, bete ditzagun datu hauek aleatorioz.
Ez duzu tsv fitxategi guztiak deskargatu eta lehenengo ~ 10-20ra mugatu beharrik 16 GB RAM-en sartuko ez den datu multzo nahiko handi bat lortzeko. TSV fitxategiak kargatzeko komando hau erabili dut:
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
1000 GB-ko tamaina duen Google Cloud-eko Persistent Disk (HDD bat dena) estandar batean (tamaina hori hartu nuen batez ere abiadura apur bat handiagoa izan zedin, nahiz eta beharbada behar den tamainako SSD bat merkeagoa izango zen) kargatu. abiadura gutxi gorabehera ~ 75 MB/seg zen 4 nukleotan.
- Erreserba bat egin behar dut Googlen lan egiten dudala, baina kontu pertsonal bat erabili dut eta artikulu honek ez du zerikusirik enpresan egiten dudan lanarekin
Datu-multzo zehatz honekin ilustrazio guztiak aterako ditut, esku artean nuen guztia baita.
Erakutsi datuak eskaneatzen aurrerapena
ClickHouse-n erregistroak dituen mahai batean eskaneatu osoa erabiliko dugunez, eta eragiketa honek denbora asko behar izan dezake eta baliteke emaitzarik ez ematea denbora luzez bat-etortze gutxi aurkitzen badira, komenigarria da kontsultaren aurrerapena emaitza duten lehen errenkadak jaso arte. Horretarako, HTTP interfazean parametro bat dago HTTP goiburuetan aurrerapena bidaltzeko aukera ematen duena: send_progress_in_http_headers=1
. Zoritxarrez, Go liburutegi estandarrak ezin ditu goiburuak irakurri jasotzen diren heinean, baina HTTP 1.0 interfazea (ez nahastu 1.1-rekin!) ClickHouse-k onartzen du, beraz, TCP konexio gordina ireki dezakezu ClickHouse-ra eta hara bidali. GET /?query=... HTTP/1.0nn
eta jaso erantzunen goiburuak eta gorputza inolako ihes edo enkriptaziorik gabe, beraz, kasu honetan ez dugu liburutegi estandarra erabili beharrik ere.
ClickHouse-tik erregistroak erreproduzitzea
ClickHouse-k ORDER BY-rekin egindako kontsultetarako optimizazioa izan du denbora luzez (2019tik?), beraz, bezalako kontsulta bat
SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESC
Berehala hasiko da mezuan "zerbait" azpikatea duten lerroak itzultzen, eskaneatzea amaitu arte itxaron gabe.
Gainera, oso erosoa izango litzateke ClickHousek berak eskaera bertan behera utziko balu harekin konexioa itxi zenean, baina hau ez da portaera lehenetsia. Eskaera automatikoa bertan behera uzteko aukera gaitu daiteke cancel_http_readonly_queries_on_client_close=1
.
SIGPIPEren kudeaketa zuzena Go-n
Exekutatzen duzunean, esate baterako, komandoa some_cmd | head -n 10
, zehazki nola komandoa some_cmd
exekuzioa gelditzen denean head
10 lerro kendu? Erantzuna erraza da: noiz head
amaitzen da, hodia ixten da, eta some_cmd komandoaren stdout-a, baldintzapean, "nowhere" seinalatzen hasten da. Noiz some_cmd
tutu itxi batean idazten saiatzen da,
Go-n ere hori lehenespenez gertatzen da, baina SIGPIPE seinale-kudeatzaileak "signal: SIGPIPE" edo antzeko mezu bat ere inprimatzen du amaieran, eta mezu hau garbitzeko SIGPIPE nahi dugun moduan kudeatu behar dugu, hau da, isilik. irteera:
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
<-ch
os.Exit(0)
}()
Erakutsi mezuaren testuingurua
Askotan erroreren bat gertatu den testuingurua ikusi nahi duzu (adibidez, zein eskaerak eragin duen izua, edo zer arazo erlazionatutako istripua gertatu baino lehen ikusi nahi da), eta grep
Hau -A, -B eta -C aukerak erabiliz egiten da, mezuaren ondoren, aurretik eta inguruan zehaztutako lerro kopurua erakusten dutenak, hurrenez hurren.
Zoritxarrez, ez dut gauza bera egiteko modu errazik aurkitu ClickHouse-n, beraz, testuingurua bistaratzeko, honelako eskaera gehigarri bat bidaltzen da emaitzaren lerro bakoitzean (xehetasunak ordenatzearen araberakoak dira eta testuingurua aurretik erakusten den ala ez). edo ondoren):
SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1
Eskaera ia berehala bidaltzen denez ClickHousek dagokion lerroa itzuli ondoren, cachean amaitzen da eta orokorrean eskaera nahiko azkar exekutatzen da eta CPU pixka bat kontsumitzen du (normalean eskaerak ~6 ms inguru hartzen ditu nire makina birtualean).
Erakutsi mezu berriak denbora errealean
Sarrerako mezuak (ia) denbora errealean erakusteko, eskaera segundo gutxitan behin exekutatzen dugu, aurretik aurkitu genuen azken denbora-zigilua gogoratuz.
Agindu adibideak
Nolakoak dira logscli komando tipikoak praktikan?
Artikuluaren hasieran aipatu dudan Amazon datu multzoa deskargatu baduzu, komando hauek exekutatu ditzakezu:
# Показать строки, где встречается слово 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
Erreferentziak
Erabilgarritasun-kodea (dokumentaziorik gabe) github-en dago eskuragarri
Iturria: www.habr.com