Erregistroak ikusteko munduko interfazerik erosoena garatzen ari gara*

Erregistroak ikusteko munduko interfazerik erosoena garatzen ari gara* 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 zureHARRIA

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: https://github.com/YuriyNasretdinov/logscli (Hautatutako Go kodearen 350 lerro).

Capabilities

Nire helburua tail/grep egiteko erabiltzen direnei ezaguna irudituko zitzaien interfaze bat egitea zen, hau da, honako gauza hauek onartzea:

  1. Ikusi erregistro guztiak, iragazi gabe.
  2. Utzi azpikate finko bat duten lerroak (bandera -F у grep).
  3. Utzi adierazpen erregulararekin bat datozen lerroak (bandera -E у grep).
  4. Lehenespenez, alderantzizko ordena kronologikoan ikusten da, izan ere, azken erregistroak interesgarri izaten dira lehenik.
  5. Erakutsi testuingurua lerro bakoitzaren ondoan (aukerak -A, -B и -C у grep, bat datozen lerro bakoitzaren aurretik, ondoren eta inguruan N lerro inprimatuz, hurrenez hurren).
  6. Ikusi sarrerako erregistroak denbora errealean, iragazkiarekin edo gabe (funtsean tail -f | grep).
  7. 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; seinalea SIGPIPE isilean eten beharko luke erregistroen streaming, haiek egiten duten bezala tail, grep eta beste UNIX utilitate batzuk.

Inplementazioa

Suposatuko dut dagoeneko badakizula nolabait ClickHouse-ra erregistroak nola entregatu. Hala ez bada, probatzea gomendatzen dut LSD и kittenhouseEta erregistroen entregari buruzko artikulu hau.

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. Amazoneko produktuen iritziak 2015era arte. Jakina, haien egitura ez da testu-erregistroen berdina, baina ilustrazioetarako hori ez da garrantzitsua.

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, SIGPIPE seinalea jasotzen du, eta horrek isilik amaitzen du programa lehenespenez.

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 https://github.com/YuriyNasretdinov/logscli. Pozik egongo nintzateke ClickHousen oinarritutako erregistroak ikusteko kontsola-interfaze baten ideiari buruz zure iritzia entzutea.

Iturria: www.habr.com

Gehitu iruzkin berria