Бид логийг үзэх дэлхийн хамгийн тохиромжтой интерфэйсийг* хөгжүүлж байна

Бид логийг үзэх дэлхийн хамгийн тохиромжтой интерфэйсийг* хөгжүүлж байна Хэрэв та логуудыг үзэхийн тулд вэб интерфэйсийг ашиглаж байсан бол эдгээр интерфэйсүүд нь дүрмээр бол төвөгтэй бөгөөд (ихэвчлэн) тийм ч тохиромжтой, хариу үйлдэл үзүүлэхгүй байгааг анзаарсан байх. Зарим нь та дасаж болно, зарим нь үнэхээр аймшигтай, гэхдээ миний бодлоор бүх асуудлын шалтгаан нь бид бүртгэлийг үзэх ажилд буруу ханддагтай холбоотой юм шиг санагдаж байна: бид CLI (командын мөрийн интерфейс) бүхий вэб интерфэйсийг бий болгохыг хичээдэг. илүү сайн ажилладаг. Би хувьдаа tail, grep, awk болон бусадтай ажиллахад маш тухтай байдаг тул миний хувьд логуудтай ажиллах хамгийн тохиромжтой интерфейс нь tail болон grep-тэй төстэй зүйл байх боловч үүнийг олон серверээс ирсэн логуудыг уншихад ашиглаж болно. Мэдээжийн хэрэг, тэдгээрийг ClickHouse-аас уншаарай!

*хабра хэрэглэгчийн хувийн бодлоор youROCK

logscli-тай танилц

Би интерфэйсийнхээ нэрийг олоогүй бөгөөд үнэнийг хэлэхэд энэ нь прототип хэлбэрээр байдаг, гэхдээ та эх кодыг нэн даруй харахыг хүсвэл урьж байна. https://github.com/YuriyNasretdinov/logscli (сонгосон Go кодын 350 мөр).

Онцлог

Миний зорилго бол tail/grep-д дассан хүмүүст танил мэт харагдах интерфейсийг бий болгох, өөрөөр хэлбэл дараах зүйлсийг дэмжих явдал байв.

  1. Бүх бүртгэлийг шүүлтүүргүйгээр үзэх.
  2. Тогтмол дэд мөр агуулсан мөрүүдийг үлдээгээрэй (туг -F у grep).
  3. Тогтмол илэрхийлэлтэй тохирох мөрүүдийг үлдээгээрэй (туг -E у grep).
  4. Анхдагч байдлаар, үзэх нь урвуу дарааллаар явагддаг, учир нь хамгийн сүүлийн үеийн бүртгэлүүд ихэвчлэн хамгийн түрүүнд сонирхолтой байдаг.
  5. Мөр бүрийн хажууд контекстийг харуулах (сонголт -A, -B и -C у grep, тохирох мөр бүрийн өмнө, дараа болон эргэн тойронд N мөрийг хэвлэх).
  6. Ирж буй логуудыг шүүлтүүртэй эсвэл шүүлтүүргүйгээр бодит цаг хугацаанд харах (үндсэндээ tail -f | grep).
  7. Интерфэйс нь нийцтэй байх ёстой less, head, tail болон бусад - анхдагчаар үр дүнг тоонд хязгаарлалтгүйгээр буцааж өгөх ёстой; хэрэглэгч хүлээн авах сонирхолтой л бол мөрүүдийг урсгал хэлбэрээр хэвлэдэг; дохио SIGPIPE лог урсгалыг тэдэн шиг чимээгүй тасалдуулах ёстой tail, grep болон бусад UNIX хэрэгслүүд.

Реализация

Та ямар нэгэн байдлаар логуудыг ClickHouse руу хэрхэн хүргэхээ мэддэг болсон гэж би бодож байна. Хэрэв үгүй ​​​​бол би үүнийг туршиж үзэхийг зөвлөж байна lsd и зулзагаТэгээд гуалин хүргэлтийн тухай энэ нийтлэл.

Эхлээд та үндсэн схемийг шийдэх хэрэгтэй. Та ихэвчлэн цаг хугацаагаар эрэмбэлсэн логуудыг хүлээн авахыг хүсдэг тул тэдгээрийг ингэж хадгалах нь логик юм шиг санагддаг. Хэрэв олон бүртгэлийн категориуд байгаа бөгөөд тэдгээр нь бүгд ижил төрлийн байвал та бүртгэлийн ангиллыг үндсэн түлхүүрийн эхний багана болгож болно - энэ нь танд хэд хэдэн хүснэгтийн оронд нэг хүснэгттэй байх боломжийг олгоно. ClickHouse-д оруулах (хатуу дисктэй серверүүд дээр секундэд ~1-ээс илүүгүй удаа өгөгдөл оруулахыг зөвлөж байна) бүх серверийн хувьд).

Өөрөөр хэлбэл, бидэнд ойролцоогоор дараах хүснэгтийн схем хэрэгтэй болно.

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

Харамсалтай нь би барьж аваад татаж авч болох бодит бүртгэлтэй нээлттэй эх сурвалжийг тэр даруй олж чадаагүй тул би үүнийг жишээ болгон авсан. 2015 оноос өмнөх Amazon-ийн бүтээгдэхүүний тойм. Мэдээжийн хэрэг, тэдгээрийн бүтэц нь текстийн бүртгэлтэй яг адилхан биш боловч тайлбарлах үүднээс энэ нь чухал биш юм.

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 хаалттай хоолой руу бичихийг оролдох, энэ нь SIGPIPE дохиог хүлээн авдаг бөгөөд энэ нь анхдагчаар програмыг чимээгүйхэн зогсоодог.

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 дээрээс авах боломжтой https://github.com/YuriyNasretdinov/logscli. ClickHouse дээр суурилсан бүртгэлийг үзэх консолын интерфейсийн талаарх миний санаа бодлыг сонсоход таатай байх болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх