Kui olete kunagi kasutanud veebiliideseid logide vaatamiseks, olete tõenäoliselt märganud, kui kohmakad ja (tihti) mitte eriti mugavad ja reageerivad need liidesed tavaliselt on. Mõnega harjub ära, mõni on täiesti kohutav, kuid minu arvates seisneb kõigi probleemide põhjus selles, et läheneme logide vaatamise ülesandele valesti: me püüame luua veebiliidese seal, kus CLI (komandirežiimi liides) töötab paremini. Mulle isiklikult meeldib töötada tail, grep, awk ja muu taolisega, seega oleks minu jaoks ideaalne liides logide töötlemiseks midagi sarnast tail ja grep'ile, kuid millega saaks lugeda logisid, mis on saadud paljusidest serveritest. Teisisõnu, loomulikult lugeda neid ClickHouse'ist!
*isiklik arvamus Habr kasutajalt
Tutvustame logscli
Ma ei leidnud oma liidesele nime ja, ausalt öeldes, eksisteerib see pigem prototüübi kujul, kuid kui soovite kohe lähtekoodi vaadata, siis tere tulemast: (350 rida valitud koodi Go-s).
Võimalused
Seadsin endale eesmärgiks luua liides, mis tunduks tuttav neile, kes on harjunud tail/grep'iga, s.t. toetama järgmisi asju:
- Logide vaatamine, ilma filtreerimata.
- Jätta read, mis sisaldavad fikseeritud alamstringi (lipuke
-Fongrep). - Jätta read, mis vastavad regulaaravaldisele (lipuke
-Eongrep). - Vaikimisi vaatamine vastupidises kronoloogilises järjekorras, kuna tavaliselt on kõige värskemad logid esimesed, mis huvi pakuvad.
- Konteksti kuvamine igas reas (parameetrid
-A,-Bja: ühenduse tihendamine. Kui teil on aeglane kanal või vaatate palju teksti, võib see ühendust kiirendada.ongrep, mis prindib N rida enne, pärast ja igast vastavast reast.) - Logide vaatamine reaalajas, filtreerimisega ja ilma (sisuliselt
tail -f | grep). - Liides peab olema ühilduv
less,head,tailja teistega — vaikimisi peaksid tulemused olema piiranguteta; read prinditakse voogesituse kaudu seni, kuni kasutaja on huvitatud nende saamisest; signaalSIGPIPEpeaks mõõtmatult katkestama logide voogesituse, nagu seda teevadtail,grepja teised UNIX-i utiliidid.
Rakendamine
Ma eeldan, et oskate juba kuidagi logisid ClickHouse'i toimetada. Kui ei, siis soovitan proovida ja , samuti .
Esmaltamiseks tuleks esmalt määrata andmebaasi skeem. Kuna logisid soovitakse tavaliselt ajaliselt sortida, tundub loogiline neid selliselt ka talletada. Kui logikategooriaid on palju ja need on sarnased, siis võib esimeseks primaarkohaks kasutada logikategooriat - see võimaldab omada ühte tabelit mitme asemel, mis andmete sisestamisel ClickHouse'i suur pluss (rangete kraanadega serverites on soovitatav andmeid sisestada mitte tihedamalt kui ~1 kord sekundis. kogu serveri jaoks).
Seega vajame umbes järgmist tabeliskemaatikat:
CREATE TABLE logs(
category LowCardinality(String), -- logikategooria (valikuline)
time DateTime, -- sündmuse aeg
millis UInt16, -- millisekundid (võivad olla ka mikrosked, jne.): soovitatav talletada, kui sündmusi on palju, et oleks lihtsam sündmusi omavahel eristada
..., -- teie enda väljad, näiteks serveri nimi, logimise tase jne.
message String -- sõnumi tekst
) ENGINE=MergeTree()
ORDER BY (category, time, millis)Kahjuks ei leidnud ma kohe mingit avatud allikat realistlike logide jaoks, mida saaks alla laadida, seega kasutasin selle asemel näitena . Ilmselt ei ole nende struktuur sama, mis tekstilistel logidel, kuid illustreerimiseks pole see põhimõtteliselt oluline.
Amazonist arvustuste laadimise juhend ClickHouse'i
Loome tabeli:
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=8192Amazoni andmestikus on olemas ainult arvustuse kuupäev, kuid pole täpset aega, seepärast täidame need andmed juhuslike numbritega.
Ei ole vaja alla laadida kõiki tsv-failide faile ja piirduda esialgu 10-20 esimese failiga, et saada piisavalt suur andmestik, mis ei mahtunud 16 GB RAM-i. TSV-failide laadimiseks kasutasin järgmist käsku:
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'
doneGoogle Cloudis 1000 GB suurusega tavapärasel Persistent Diskil (HDD), mille valisin peamiselt selleks, et kiirus oleks veidi kõrgem, kuigi võib-olla oleks vajalik SSD odavamalt saadud. Üleslaadimise kiirus oli umbes ~75 MB/s 4 tuumal.
- Pean täpsustama, et töötan Googles, kuid kasutasin isiklikku kontot ning see artikkel ei seostu minu tööga ettevõttes.
Kõik illustratsioonid teen selle andmestikuga, kuna see on kõik, mis mul käepärast oli.
Andmete skannimise edenemise kuvamine
Kuna ClickHouse'is kasutame me täiskannatust logide tabelis ja see operation võib võtta märkimisväärselt aega ning ei anna pikka aega mingeid tulemusi, kui vasteid on vähe, on soovitatav osata näidata päringu täitmise edenemist enne esmaste ridade hankimist. Selleks on HTTP-liideses parameeter, mis võimaldab edenemist edastada HTTP-päistes: send_progress_in_http_headers=1. Kahjuks ei oska Go standardbibliograafia lugeda päiseid nende saamise ajal, kuid HTTP 1.0 (ära sega seda 1.1-ga!) on ClickHouse'is toetatud, seega saab avada toore TCP-ühenduse ClickHouse'iga, saata sinna GET \/?query=... HTTP\/1.0nn ja saada vastuseks päised ja keha ilma igasuguse põgenemise ja krüpteerimiseta, nii et sel juhul pole meil isegi vaja standardbibliograafiat kasutada.
Logide voog ClickHouse'ist
ClickHouse'is on juba suhteliselt kaua (alates 2019. aastast?) olemas optimeerimine ORDER BY päringute jaoks, nii et selline päring
SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESCAlustab kohe nende ridade tagastamist, kus message'is on allstring "something", ootamata skannimise lõpetamist.
Samuti oleks väga mugav, kui ClickHouse tühistaks päringu iseenesest, kui ühendus temaga suletakse, kuid see ei ole vaikimisi käitumine. Automaatset päringu tühistamist saab aktiveerida valikuga cancel_http_readonly_queries_on_client_close=1.
SIGPIPE korrektne käsitlemine Go-s
Kui sooritate näiteks käsu some_cmd | head -n 10, kuidas täpselt käsk some_cmd lõpetab oma täitmise, kui head on loetud 10 rida? Vastus on lihtne: kui head lõppeb, suletakse pipe ja some_cmd'i stdout hakkab viitama, tinglikult, «mitte kuhugi». Kui some_cmd proovitakse salvestada suletud pipe'i, .
Go-s on tavaliselt nii, kuid SIGPIPE signaali käitleja lõpus prindib ka "signal: SIGPIPE" või sarnase sõnumi, ja selle sõnumi eemaldamiseks tuleb lihtsalt käsitleda SIGPIPE nii, nagu me soovime, st lihtsalt vaikselt lahkuda.
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
<-ch
os.Exit(0)
}()Sõnumi konteksti kuvamine
Sageli tahaks näha konteksti, kus mingi viga juhtus (näiteks, milline päring käivitas paanikat või milliseid kaasnevaid probleeme oli enne kukkumist nähtud), ja selle jaoks grep olevad valikud -A, -B ja -C, mis näitavad vastavalt указаное arvu ridu pärast, enne ja sõnumi ümber.
Kahjuks ei leidnud ma lihtsat viisi sama asja tegemiseks ClickHouse'is, seetõttu saadetakse iga tulemuse rida jaoks lisapäring umbes järgmist tüüpi (detailid sõltuvad sorteerimisest ja sellest, kas konteksti kuvatakse enne või pärast):
SELECT time,millis,review_body FROM amazon
WHERE (time = 'SÜNDMUSE_AEG' AND millis < MILLISEKUNDIDE_SÜNDMUSE) OR (time < 'SÜNDMUSE_AEG')
ORDER BY time DESC, millis DESC
LIMIT KONTEKSTI_RIDU
SETTINGS max_threads=1Kuna päring saadetakse peaaegu kohe pärast seda, kui ClickHouse vastas vastava reale, satub see vahemälu ja päring täidetakse üldiselt üsna kiiresti ning kulutab natuke CPU-d (tavaliselt kestab päring minu virtuaalmasinas umbes ~6 ms).
Uute sõnumite kuvamine reaalajas
Selleks, et näidata saabuvad sõnumid (peaaegu) reaalajas, täidame lihtsalt päringu iga paarisekundi tagant, mäletades viimast timestampi, mida oleme enne näinud.
Käskude näited
Millised näevad välja tüüpilised logscli käsklused praktikas?
Kui olete laadinud alla Amazon'i andmestiku, millest ma artikli alguses rääkisin, saate sooritada järgmisi käsklusi:
# Показать строки, где встречается слово 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' -tailfViidatud lingid
Tööriista kood (ilma dokumentatsioonita) on saadaval githubis aadressil . Ootaksin teie mõtteid minu idee kohta logide vaatamiseks mõeldud käsurealiidese osas ClickHouse'i põhjal.
Allikas: habr.com
