Sviluppemu l'interfaccia più còmuda in u mondu * per vede logs

Sviluppemu l'interfaccia più còmuda in u mondu * per vede logs Se avete mai utilizatu interfacce web per vede logs, allora avete prubabilmente nutatu cumu, in regula, sti interfacce sò ingombranti è (spessu) micca assai convenienti è responsive. Qualchidunu pudete avè abituatu, alcuni sò assulutamente terribili, ma mi pare chì u mutivu di tutti i prublemi hè chì avvicinemu à u compitu di vede logs in modu incorrectu: pruvemu di creà una interfaccia web induve a CLI (interfaccia di linea di cumanda) funziona megliu. Personalmente sò assai còmode di travaglià cù tail, grep, awk è altri, è dunque per mè l'interfaccia ideale per travaglià cù logs seria qualcosa simili à tail è grep, ma chì puderia ancu esse usatu per leghje logs chì venenu da parechji servitori. Questu hè, sicuru, leghjiteli da ClickHouse!

*secondu l'opinione persunale di l'utilizatori di habra u vostru ROCK

Scuntrà logscli

Ùn aghju micca un nome per a mo interfaccia, è, per esse onestu, esisti piuttostu in forma di prototipu, ma se vulete vede immediatamente u codice fonte, allora site benvenutu: https://github.com/YuriyNasretdinov/logscli (350 linee di codice Go sceltu).

Caratteristiche

U mo scopu era di fà una interfaccia chì parerebbe familiar à quelli chì sò abituati à tail / grep, vale à dì per sustene e cose seguenti:

  1. Vede tutti i logs, senza filtru.
  2. Lasciate e linee chì cuntenenu una substringa fissa (bandiera -F у grep).
  3. Lasciate e linee chì currispondenu à l'espressione regulare (bandiera -E у grep).
  4. Per automaticamente, a visualizazione hè in ordine cronologicu inversu, postu chì i logs più recenti sò generalmente d'interessu prima.
  5. Mostra u cuntestu accantu à ogni linea (opzioni -A, -B и -C у grep, stampendu N linee prima, dopu è intornu à ogni linea currispundente, rispettivamente).
  6. Vede i logs entranti in tempu reale, cù o senza filtru (essenzialmente tail -f | grep).
  7. L'interfaccia deve esse cumpatibile cù less, head, tail è altri - per automaticamente, i risultati devenu esse restituiti senza restrizioni à u so numeru; e linee sò stampate cum'è un flussu sempre chì l'utilizatore hè interessatu à riceve; signale SIGPIPE duveranu interrompe in silenziu u streaming di log, cum'è elli tail, grep è altre utilità UNIX.

Реализация

Assumeraghju chì sapete digià in qualchì manera cumu furnisce i logs à ClickHouse. Se no, vi cunsigliu di pruvà LSD и gattini, cum'è ancu stu articulu nantu à a consegna di log.

Prima avete bisognu di decide nantu à u schema di basa. Siccomu di solitu vulete riceve logs ordinati per u tempu, pare logicu per almacenà cusì. Se ci sò parechje categurie di logu è sò tutti di u stessu tipu, pudete fà una categuria di log cum'è a prima colonna di a chjave primaria - questu vi permetterà di avè una tavola invece di parechji, chì serà un grande plus quandu inserisce in ClickHouse (in i servitori cù discu duru, hè cunsigliatu di inserisce dati micca più di ~ 1 volte per secondu per tuttu u servitore).

Vale à dì, avemu bisognu di circa u schema di tavula seguente:

CREATE TABLE logs(
    category LowCardinality(String), -- категория логов (опционально)
    time DateTime, -- время события
    millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
    ..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
    message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)

Sfurtunatamente, ùn aghju micca pussutu truvà immediatamente alcuna fonti aperte cù logs realistichi chì puderia piglià è scaricà, cusì aghju pigliatu questu invece cum'è un esempiu. recensioni di i prudutti di Amazon prima di 2015. Di sicuru, a so struttura ùn hè micca esattamente listessa cum'è quella di i logs di testu, ma per scopi di illustrazione ùn hè micca impurtante.

istruzioni per caricare recensioni di Amazon su ClickHouse

Creemu una tavola:

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

In u dataset di Amazon ci hè solu una data per una rivisione, ma ùn ci hè micca u tempu esatta, per quessa, cumpiendu sti dati cun un randon.

Ùn avete bisognu di scaricà tutti i fugliali tsv è limità à u primu ~ 10-20 per avè un inseme abbastanza grande di dati chì ùn si mette micca in 16 GB di RAM. Per carica i schedari TSV aghju utilizatu u cumandimu seguente:

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

In un Discu Persistente standard (chì hè un HDD) in Google Cloud cù una dimensione di 1000 GB (aghju pigliatu questa dimensione principalmente per chì a velocità era un pocu più altu, ancu se forse un SSD di a dimensione necessaria seria più prezzu) a carica. a velocità era di circa ~ 75 MB/sec su 4 core.

  • Deve fà una riservazione chì travaglia in Google, ma aghju utilizatu un contu persunale è questu articulu ùn hà nunda di fà cù u mo travagliu in a cumpagnia.

Pruduceraghju tutte l'illustrazioni cù questu dataset particulari, postu chì questu hè tuttu ciò chì aghju avutu in manu.

Mostra u prugressu di scansione di dati

Siccomu in ClickHouse useremu una scansione completa nantu à una tavula cù logs, è sta operazione pò piglià una quantità significativa di tempu è ùn pò micca pruduce risultati per un bellu pezzu si trovanu pochi partiti, hè cunsigliu per esse capaci di mustrà u prugressu di a dumanda finu à chì i primi fila cù u risultatu sò ricevuti. Per fà questu, ci hè un paràmetru in l'interfaccia HTTP chì permette di mandà u prugressu in l'intestazione HTTP: send_progress_in_http_headers=1. Sfortunatamente, a libreria Go standard ùn pò micca leghje l'intestazione cum'è sò ricevuti, ma l'interfaccia HTTP 1.0 (per ùn esse cunfundita cù 1.1!) Hè supportata da ClickHouse, cusì pudete apre una cunnessione TCP cruda à ClickHouse è mandà quì. GET /?query=... HTTP/1.0nn è riceve l'intestazione di a risposta è u corpu senza scappà o criptu, cusì in questu casu ùn avemu mancu bisognu di utilizà a biblioteca standard.

Streaming logs da ClickHouse

ClickHouse hà avutu ottimisazione per e dumande cù ORDER BY per un tempu relativamente longu (dapoi u 2019?), Dunque una dumanda cum'è

SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESC

Cuminciarà immediatamente à rinvià e linee chì anu a substringa "qualcosa" in u so messagiu, senza aspittà chì a scansione finisci.

Inoltre, saria assai còmuda se ClickHouse stessu annullava a dumanda quandu a cunnessione à questu hè stata chjusa, ma questu ùn hè micca u cumpurtamentu predeterminatu. L'annullamentu automaticu di a dumanda pò esse attivatu cù l'opzione cancel_http_readonly_queries_on_client_close=1.

Gestione curretta di SIGPIPE in Go

Quandu eseguite, dì, u cumandamentu some_cmd | head -n 10, esattamente cumu u cumandamentu some_cmd ferma l'esecuzione quandu head sottrattu 10 linii? A risposta hè simplice: quandu head finisce, a pipa si chjude, è u stdout di u cumandimu some_cmd cumencia à puntà, cundizionalmente, "à nulla". Quandu some_cmd prova à scrive à una pipa chjusa, riceve un signalu SIGPIPE, chì silenziu termina u prugramma per difettu.

In Go, questu succede ancu in modu predeterminatu, ma u gestore di signali SIGPIPE stampa ancu "signale: SIGPIPE" o un missaghju simile à a fine, è per sguassà stu missaghju, avemu solu bisognu di trattà SIGPIPE noi stessi cum'è vulemu, vale à dì, solu in silenziu. esce:

ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
    <-ch
    os.Exit(0)
}()

Mostra u cuntestu di u messagiu

Spessu vulete vede u cuntestu in u quale qualchì errore hè accadutu (per esempiu, quale dumanda hà causatu un panicu, o quali prublemi cunnessi eranu visibili prima di u crash), è in grep Questu hè fattu cù l'opzioni -A, -B è -C, chì mostranu u numeru specificatu di linii dopu, prima è intornu à u messagiu, rispettivamente.

Sfurtunatamente, ùn aghju micca truvatu un modu faciule per fà u listessu in ClickHouse, cusì per vede u cuntestu, una dumanda supplementaria cum'è questu hè mandata à ogni linea di u risultatu (i dettagli dependenu di l'ordinamentu è se u cuntestu hè mostratu prima). o dopu):

SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1

Siccomu a dumanda hè mandata quasi immediatamenti dopu chì ClickHouse torna a linea currispundente, finisce in u cache è in generale a dumanda hè eseguita abbastanza rapidamente è cunsuma un pocu CPU (di solitu a dumanda dura circa ~ 6 ms in a mo macchina virtuale).

Mostra novi messagi in tempu reale

Per fà vede i missaghji entranti in (quasi) tempu reale, simpricimenti eseguite a dumanda una volta ogni pochi seconde, ricurdendu l'ultimu timestamp chì avemu scontru prima.

Esempi di cumandamenti

Chì sò i cumandamenti tipici di logscli in a pratica?

Se avete scaricatu u dataset Amazon chì aghju citatu à u principiu di l'articulu, pudete eseguisce i seguenti cumandamenti:

# Показать строки, где встречается слово 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

referenze

U codice di utilità (senza documentazione) hè dispunibule nantu à github at https://github.com/YuriyNasretdinov/logscli. Saria cuntentu di sente i vostri pinsamenti nantu à a mo idea per una interfaccia di cunsola per vede i log basati nantu à ClickHouse.

Source: www.habr.com

Add a comment