Kui olete kunagi kasutanud veebiliideseid logide vaatamiseks, olete kindlasti märganud, kui sageli need liidesed on kohmakad ja (tihti) mitte just kõige mugavamad ja reageerimisvõimelised. Mõned neist võivad harjumiseks sobida, teised on lihtsalt kohutavad, kuid minu arvates on kõigi probleemide põhjus see, et me läheneme logide vaatamise ülesandele valesti: proovime luua veebiliidese, kus CLI (käskude rida) töötab paremini. Isiklikult tunnen end taili, grepi, awki ja teistega töötades väga mugavalt, seega oleks logide vaatamiseks ideaalne liides, mis sarnaneb tailile ja grepile, kuid võimaldaks lugeda logisid, mis tulid paljusilt serveritelt. See tähendab, et muidugi, lugeda neid ClickHouse'ist!
*erakordne arvamus hublahuviliselt
Tutvuge logscli'ga
Ma ei ole oma liidesele nime välja mõelnud ja ausalt öeldes eksisteerib see pigem prototüübi vormis, kuid kui soovite kohe lähtekoodiga tutvuda, siis olete teretulnud: (350 rida hoolikalt valitud koodi Go's).
Võimalused
Seadsin endale eesmärgi luua liides, mis näib tuttav neile, kes on harjunud tail / grep'iga, st toetada järgmisi asju:
- Logide vaatamine ilma filtreerimata.
- Jätta read, mis sisaldavad kindlat alamstringi (lipp
-Fongrep). - Jätta read, mis vastavad regulaaravaldiste nõuetele (lipp
-Eongrep). - Vaikimisi kuvamine tagurpidi kronoloogilises järjekorras, kuna tavaliselt huvitavad kõige rohkem värsked logid.
- Konteksti näitamine iga rea ümber (parameetrid
-A,-Bja-Congrep, prindib N rida enne, pärast ja iga vastava vastuse poole. - Reaalajas logide vaatamine, filteriga ja ilma (põhimõtteliselt
tail -f | grep). - Liides peab olema ühilduv
less,head,tailja muu — vaikimisi tuleks tulemused tagasi tuua piiranguteta; read prinditakse voogude kaudu seni, kuni kasutaja on huvitatud nende vastuvõtmisest; signaalSIGPIPEpeab vaikides katkestama logide voogude saatmise, just nagu seda teevadtail,grepja teised UNIX-i utiliidid.
Rakendus
Eeldan, et oskate juba mingil moel edastada logid ClickHouse'i. Kui ei, siis soovitan proovida ja , samuti .
Esiteks tuleb otsustada andmebaasi skeemi üle. Kuna logisid soovitakse tavaliselt ajaliselt sorteerituna saada, näib loogiline neid ka nii salvestada. Kui logide kategooriaid on palju ja need on ühte tüüpi, võib esimese veeru esmases võtmes teha logide kategooria — see võimaldab omada ühte tabelit mitme asemel, mis andmete sisestamisel ClickHouse'i suur eelis (karmide kõvakettaga serverites soovitatakse andmeid sisestada mitte tihedamini kui ~1 kord sekundis kogu serveri jaoks).
Seega on meil vaja ligikaudu järgmist tabelite skeemi:
CREATE TABLE logs(
category LowCardinality(String), -- logide kategooria (valikuline)
time DateTime, -- sündmuse aeg
millis UInt16, -- millisekundid (võivad olla ka mikrosekundid jne): soovitatakse salvestada, kui sündmusi on palju, et oleks kergem sündmusi üksteisest 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 mingeid avatud allikaid realistlike logidega, mida saaks alla laadida, seega kasutasin näiteks . Loomulikult pole nende struktuur täpselt sama nagu tekstilistes logides, kuid illustreerimise jaoks ei ole see põhimõtteline.
Amazonis arvustuste üleslaadimise 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 ainult kuupäev arvustuse kohta, kuid täpset aega pole, seega täidame need andmed juhuslikult.
Ei ole vaja alla laadida kõiki tsv-faile, piisab esimestest ~10-20, et saada juba piisavalt suur andmestik, mis ei mahuks 16 GB RAM-i. TSV-failide üleslaadimiseks 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 Cloudi standardne Persistent Disk (HDD) suurusega 1000 GB (valisin selle suuruse peamiselt, et kiirus oleks veidi parem, kuigi võib-olla oleks SSD sobiva mahtuvusega odavam) laadimiskiirus oli umbes ~75 MB/s 4 tuumal.
- pean mainima, et töötan Google'is, kuid kasutasin isiklikku kontot ja see artikkel ei ole seotud minu tööga ettevõttes.
Kõik illustratsioonid teen just selle andmestiku põhjal, kuna see on kõik, mis mul käepärast oli.
Andmete skannimise edenemise näitamine
Kuna ClickHouse'is kasutame logide tabelis täielikku skannimist ja see operatsioon võib võtta märkimisväärselt aega, andes pikka aega vähe või ei midagi tagasi, on soovitatav osata näidata päringu edenemist enne, kui esimeseid tulemuse reameid saadakse. Selleks on HTTP-liideses parameeter, mis võimaldab edastada edenemist HTTP pealkirjades: send_progress_in_http_headers=1. Kahjuks ei oska Go standardraamatukogu lugeda pealkirju nende vastuvõtmise ajal, kuid HTTP 1.0 liidest (ära sega 1.1-ga!) toetab ClickHouse, seega on võimalik avada toore TCP-ühendus ClickHouse'iga, saata sinna GET /?query=... HTTP/1.0nn ja saada vastuseks pealkirjad ja keha ilma igasuguse kodeerimise ja krüpteerimiseta, seega ei ole meil selle puhul isegi standardraamatukogu vaja.
Logide voogedastus ClickHouse's
ClickHouse'il on juba suhteliselt kaua (2019. aastast?) olemas optimeerimine ORDER BY päringute jaoks, seega päring nagu
SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESChakkab kohe tagastama read, mille message'is on alamstring "something", ootamata skaneerimise lõpetamist.
Samuti oleks väga mugav, kui ClickHouse tühistaks päringu automaatselt, kui ühendus suletakse, kuid see ei ole vaikimisi käitumine. Automaatne päringu tühistamine on võimalik lubada valikuga cancel_http_readonly_queries_on_client_close=1.
SIGPIPE korrektne töötlemine Go's
Kui täidate näiteks käsku some_cmd | head -n 10, kuidas täpselt käsk some_cmd oma täitmise lõpetab, kui head kas sa lugesid 10 rida? Vastus on lihtne: kui head see lõppeb, pipe suletakse ja some_cmd käsu stdout hakkab osutama, tinglikult, "ei kuhugi". Kui some_cmd üritatakse kirjutada suletud pipe'i, .
Go-s juhtub see samuti vaikimisi, kuid SIGPIPE signaali töötleja prindib lõpuks ka "signal: SIGPIPE" või sarnase sõnumi, ja et see sõnum eemaldada, tuleb lihtsalt ise SIGPIPE töödelda nii, nagu me soovime, st lihtsalt vaikselt väljuda:
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
<-ch
os.Exit(0)
}()Sõnumi konteksti näitamine
Tihti on soov näha konteksti, kus mõni viga juhtus (näiteks, milline päring põhjustas paanika või millised kaasnevad probleemid olid nähtavad enne kukkumist), ja grep selleks on olemas valikud -A, -B ja -C, mis näitavad määratud arvu ridu pärast, enne ja ümber sõnumi vastavalt.
Kahjuks ei leidnud ma ClickHouse'is lihtsat võimalust sama teha, seega, konteksti kuvamiseks saadetakse tulemuse igale reale täiendav päring umbes järgmise kujuga (detailid sõltuvad sortimisest ja sellest, kas konteksti kuvatakse enne või pärast):
SELECT time,millis,review_body FROM amazon
WHERE (time = 'AEG_SÜNDMUS' AND millis < MILLISEKUNDID_SÜNDMUS) OR (time < 'AEG_SÜNDMUS')
ORDER BY time DESC, millis DESC
LIMIT KONTEKSTI_REAE_ARV
SETTINGS max_threads=1Kuna päring saadetakse peaaegu kohe pärast seda, kui ClickHouse on vastava rea tagastanud, siis see siseneb vahemäändisse ja kogu päring täidetakse piisavalt kiiresti, kulutades veidi CPU-d (tavaliselt kestab päring umbes ~6 ms minu virtuaalmasinas).
Uute sõnumite näitamine reaalajas
Kuidas näidata saabuvate sõnumite reaalajas (peaaegu) reaalajas, lihtsalt täidame päringut mitu korda sekundis, mäletades viimasest timestamp, millega oleme varem kokku puutunud.
Käskude näidised
Kuidas näevad tüüpilised logscli käsklused praktikas välja?
Kui olete üles laadinud Amazon'i andmestiku, millest ma artikli alguses rääkisin, siis saate täita järgmisi käske:
# Показать строки, где встречается слово 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' -tailfLingid
Utility kood (ilma dokumentatsioonita) on saadaval githubis aadressil . Ootan huvi ja tagasisidet oma ideedest ClickHouse'iga logide vaatamiseks mõeldud konsooli liidese kohta.
Allikas: habr.com
