Хэрэв та логуудыг үзэхийн тулд вэб интерфэйсийг ашиглаж байсан бол эдгээр интерфэйсүүд нь дүрмээр бол төвөгтэй бөгөөд (ихэвчлэн) тийм ч тохиромжтой, хариу үйлдэл үзүүлэхгүй байгааг анзаарсан байх. Зарим нь та дасаж болно, зарим нь үнэхээр аймшигтай, гэхдээ миний бодлоор бүх асуудлын шалтгаан нь бид бүртгэлийг үзэх ажилд буруу ханддагтай холбоотой юм шиг санагдаж байна: бид CLI (командын мөрийн интерфейс) бүхий вэб интерфэйсийг бий болгохыг хичээдэг. илүү сайн ажилладаг. Би хувьдаа tail, grep, awk болон бусадтай ажиллахад маш тухтай байдаг тул миний хувьд логуудтай ажиллах хамгийн тохиромжтой интерфейс нь tail болон grep-тэй төстэй зүйл байх боловч үүнийг олон серверээс ирсэн логуудыг уншихад ашиглаж болно. Мэдээжийн хэрэг, тэдгээрийг ClickHouse-аас уншаарай!
*хабра хэрэглэгчийн хувийн бодлоор
logscli-тай танилц
Би интерфэйсийнхээ нэрийг олоогүй бөгөөд үнэнийг хэлэхэд энэ нь прототип хэлбэрээр байдаг, гэхдээ та эх кодыг нэн даруй харахыг хүсвэл урьж байна.
Онцлог
Миний зорилго бол tail/grep-д дассан хүмүүст танил мэт харагдах интерфейсийг бий болгох, өөрөөр хэлбэл дараах зүйлсийг дэмжих явдал байв.
- Бүх бүртгэлийг шүүлтүүргүйгээр үзэх.
- Тогтмол дэд мөр агуулсан мөрүүдийг үлдээгээрэй (туг
-F
уgrep
). - Тогтмол илэрхийлэлтэй тохирох мөрүүдийг үлдээгээрэй (туг
-E
уgrep
). - Анхдагч байдлаар, үзэх нь урвуу дарааллаар явагддаг, учир нь хамгийн сүүлийн үеийн бүртгэлүүд ихэвчлэн хамгийн түрүүнд сонирхолтой байдаг.
- Мөр бүрийн хажууд контекстийг харуулах (сонголт
-A
,-B
и-C
уgrep
, тохирох мөр бүрийн өмнө, дараа болон эргэн тойронд N мөрийг хэвлэх). - Ирж буй логуудыг шүүлтүүртэй эсвэл шүүлтүүргүйгээр бодит цаг хугацаанд харах (үндсэндээ
tail -f | grep
). - Интерфэйс нь нийцтэй байх ёстой
less
,head
,tail
болон бусад - анхдагчаар үр дүнг тоонд хязгаарлалтгүйгээр буцааж өгөх ёстой; хэрэглэгч хүлээн авах сонирхолтой л бол мөрүүдийг урсгал хэлбэрээр хэвлэдэг; дохиоSIGPIPE
лог урсгалыг тэдэн шиг чимээгүй тасалдуулах ёстойtail
,grep
болон бусад UNIX хэрэгслүүд.
Реализация
Та ямар нэгэн байдлаар логуудыг ClickHouse руу хэрхэн хүргэхээ мэддэг болсон гэж би бодож байна. Хэрэв үгүй бол би үүнийг туршиж үзэхийг зөвлөж байна
Эхлээд та үндсэн схемийг шийдэх хэрэгтэй. Та ихэвчлэн цаг хугацаагаар эрэмбэлсэн логуудыг хүлээн авахыг хүсдэг тул тэдгээрийг ингэж хадгалах нь логик юм шиг санагддаг. Хэрэв олон бүртгэлийн категориуд байгаа бөгөөд тэдгээр нь бүгд ижил төрлийн байвал та бүртгэлийн ангиллыг үндсэн түлхүүрийн эхний багана болгож болно - энэ нь танд хэд хэдэн хүснэгтийн оронд нэг хүснэгттэй байх боломжийг олгоно. ClickHouse-д оруулах (хатуу дисктэй серверүүд дээр секундэд ~1-ээс илүүгүй удаа өгөгдөл оруулахыг зөвлөж байна) бүх серверийн хувьд).
Өөрөөр хэлбэл, бидэнд ойролцоогоор дараах хүснэгтийн схем хэрэгтэй болно.
CREATE TABLE logs(
category LowCardinality(String), -- категория логов (опционально)
time DateTime, -- время события
millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)
Харамсалтай нь би барьж аваад татаж авч болох бодит бүртгэлтэй нээлттэй эх сурвалжийг тэр даруй олж чадаагүй тул би үүнийг жишээ болгон авсан.
Amazon тоймыг ClickHouse-д байршуулах заавар
Хүснэгт үүсгэцгээе:
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
Амазоны мэдээллийн санд зөвхөн хянан үзэх огноо байгаа боловч яг тодорхой цаг байхгүй тул энэ өгөгдлийг рандоноор бөглөцгөөе.
10 ГБ RAM-д багтахгүй нэлээд том багц өгөгдлийг авахын тулд та бүх tsv файлыг татаж аваад эхний ~20-16 хүртэл хязгаарлах шаардлагагүй. TSV файлуудыг байршуулахын тулд би дараах тушаалыг ашигласан:
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
Google Cloud-ийн 1000 ГБ хэмжээтэй стандарт Persistent Disk (HDD) дээр (би энэ хэмжээг голчлон авсан бөгөөд ингэснээр хурд нь арай өндөр байсан ч шаардлагатай хэмжээтэй SSD хямд байх байсан) хурд нь 75 цөм дээр ойролцоогоор ~ 4 МБ/сек байсан.
- Би Google-д ажилладаг гэдгээ захиалах ёстой, гэхдээ би хувийн данс ашигласан бөгөөд энэ нийтлэл нь миний компани дахь ажилтай ямар ч холбоогүй юм.
Энэ бол миний гарт байсан бүх зүйл учраас би энэ өгөгдлийн багц бүхий бүх зургийг гаргах болно.
Өгөгдөл скан хийх явцыг харуулах
ClickHouse-д бид лог бүхий хүснэгтийг бүрэн сканнердах бөгөөд энэ үйлдэл нь маш их цаг хугацаа шаардагдах бөгөөд цөөн тооны таарч олдвол удаан хугацаанд үр дүн өгөхгүй байж болзошгүй тул үүнийг харуулах боломжтой байхыг зөвлөж байна. үр дүн бүхий эхний мөрүүдийг хүлээн авах хүртэл асуулгын явц. Үүнийг хийхийн тулд HTTP интерфейс дээр HTTP толгой хэсэгт ахиц дэвшлийг илгээх боломжийг олгодог параметр байдаг: send_progress_in_http_headers=1
. Харамсалтай нь, стандарт Go номын сан нь гарчгийг хүлээн авч унших боломжгүй ч HTTP 1.0 интерфэйсийг (1.1-тэй андуурч болохгүй!) ClickHouse дэмждэг тул та ClickHouse руу түүхий TCP холболт нээж, тэнд илгээх боломжтой. GET /?query=... HTTP/1.0nn
мөн хариултын толгой болон үндсэн хэсгийг ямар ч зугтах, шифрлэлтгүйгээр хүлээн авах тул энэ тохиолдолд бид стандарт номын санг ашиглах шаардлагагүй болно.
ClickHouse-аас логуудыг цацаж байна
ClickHouse-д ORDER BY-ийн тусламжтай асуулгад зориулсан оновчлол харьцангуй удаан хугацаанд (2019 оноос хойш?) хийгдсэн тул асуулга дараах байдалтай байна.
SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESC
Энэ нь скан дуусахыг хүлээлгүйгээр зурвастаа "ямар нэгэн зүйл" гэсэн дэд мөр бүхий мөрүүдийг шууд буцааж эхэлнэ.
Түүнчлэн, ClickHouse нь холболт хаагдсан үед хүсэлтийг цуцалсан бол энэ нь маш тохиромжтой байх болно, гэхдээ энэ нь анхдагч үйлдэл биш юм. Сонголтыг ашиглан хүсэлтийг автоматаар цуцлах боломжтой cancel_http_readonly_queries_on_client_close=1
.
Go дахь SIGPIPE-ийн зөв харьцах
Та тушаалыг гүйцэтгэхдээ хэлээрэй some_cmd | head -n 10
, яг яаж тушаал some_cmd
үед гүйцэтгэлийг зогсооно head
10 мөр хассан уу? Хариулт нь энгийн: хэзээ head
дуусч, хоолой хаагдах ба some_cmd командын stdout нь нөхцөлт байдлаар "хаашаа ч үгүй" гэж зааж эхэлнэ. Хэзээ some_cmd
хаалттай хоолой руу бичихийг оролдох,
Go-д энэ нь мөн өгөгдмөл байдлаар тохиолддог, гэхдээ SIGPIPE дохионы зохицуулагч нь мөн төгсгөлд нь "дохио: SIGPIPE" эсвэл ижил төстэй мессежийг хэвлэдэг бөгөөд энэ мессежийг арилгахын тулд бид SIGPIPE-г хүссэнээрээ, өөрөөр хэлбэл чимээгүйхэн зохицуулах хэрэгтэй. гарах:
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
<-ch
os.Exit(0)
}()
Зурвасын контекстийг харуулах
Ихэнхдээ та ямар нэг алдаа гарсан контекстийг харахыг хүсдэг (жишээлбэл, ямар хүсэлт сандралд хүргэсэн эсвэл ослын өмнө ямар холбоотой асуудлууд харагдаж байсан) болон grep
Энэ нь мессежийн ард, өмнө, эргэн тойронд заасан тооны мөрийг харуулдаг -A, -B, -C сонголтуудыг ашиглан хийгддэг.
Харамсалтай нь би ClickHouse дээр үүнийг хийх хялбар арга олоогүй тул контекстийг харуулахын тулд үүнтэй төстэй нэмэлт хүсэлтийг үр дүнгийн мөр бүрт илгээдэг (дэлгэрэнгүй мэдээлэл нь эрэмбэлэлт болон контекстийг өмнө нь харуулсан эсэхээс хамаарна) эсвэл дараа нь):
SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1
ClickHouse харгалзах мөрийг буцаасны дараа хүсэлт бараг шууд илгээгддэг тул энэ нь кэшэд дуусдаг бөгөөд ерөнхийдөө хүсэлт нь маш хурдан хэрэгжиж, бага зэрэг CPU зарцуулдаг (ихэвчлэн хүсэлт миний виртуал машин дээр ~6 мс орчим болдог).
Шинэ мессежүүдийг бодит цаг хугацаанд харуулах
Ирж буй мессежийг (бараг) бодит цаг хугацаанд харуулахын тулд бид өмнө нь тааралдсан хамгийн сүүлийн цагийн тэмдгийг санаж, хэдхэн секунд тутамд хүсэлтийг гүйцэтгэхэд хангалттай.
Тушаалын жишээнүүд
Ердийн logscli командууд практикт ямар харагддаг вэ?
Хэрэв та нийтлэлийн эхэнд дурдсан Амазон мэдээллийн багцыг татаж авсан бол дараах тушаалуудыг ажиллуулж болно.
# Показать строки, где встречается слово 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
лавлагаа
Хэрэглээний кодыг (баримт бичиггүй) github дээрээс авах боломжтой
Эх сурвалж: www.habr.com