جيڪڏهن توهان لاگز ڏسڻ لاءِ ڪڏهن ويب انٽرفيس استعمال ڪيا آهن، ته پوءِ توهان شايد محسوس ڪيو هوندو ته ڪيئن، ضابطي جي طور تي، اهي انٽرفيس منجهيل آهن ۽ (اڪثر) تمام آسان ۽ جوابدار نه آهن. ڪجھ توھان کي استعمال ڪري سگھو ٿا، ڪجھ بلڪل خوفناڪ آھن، پر مون کي لڳي ٿو ته سڀني مسئلن جو سبب اھو آھي ته اسان لاگز کي ڏسڻ جي ڪم کي غلط طور تي پھچون ٿا: اسان ھڪڙي ويب انٽرنيٽ ٺاهڻ جي ڪوشش ڪندا آھيو جتي CLI (ڪمانڊ لائن انٽرفيس) بهتر ڪم ڪري ٿو. مان ذاتي طور تي tail، grep، awk ۽ ٻين سان ڪم ڪرڻ ۾ ڏاڍو آرام سان آهيان، ۽ تنهن ڪري مون لاء لاگز سان ڪم ڪرڻ لاء مثالي انٽرفيس ڪجهه tail ۽ grep وانگر هوندو، پر اهو پڻ استعمال ڪري سگهجي ٿو لاگز پڙهڻ لاء جيڪي ڪيترن ئي سرورن مان آيا آهن. اھو آھي، يقينا، انھن کي ڪلڪ ڪريو ھاؤس مان پڙھو!
*هبرا استعمال ڪندڙ جي ذاتي راءِ موجب
logscli سان ملو
مان پنهنجي انٽرفيس لاءِ ڪو نالو نه آيو آهيان، ۽، سچ پڇو، اهو بلڪه هڪ پروٽوٽائپ جي صورت ۾ موجود آهي، پر جيڪڏهن توهان فوري طور تي سورس ڪوڊ ڏسڻ چاهيو ٿا، ته پوءِ ڀليڪار آهيو:
خاصيتون
منهنجو مقصد هڪ انٽرفيس ٺاهڻ هو جيڪو انهن ماڻهن کي واقف هجي جيڪي دم/گريپ لاءِ استعمال ڪيا ويندا آهن، يعني هيٺين شين کي سپورٽ ڪرڻ لاءِ:
- سڀ لاگ ڏسو، بغير فلٽرنگ.
- ليڪن ڇڏي ڏيو جنهن ۾ هڪ مقرر ٿيل سبسٽرنگ هجي (پرچم
-F
уgrep
). - سٽون ڇڏي ڏيو جيڪي باقاعده اظهار سان ملن ٿيون (پرچم
-E
уgrep
). - ڊفالٽ طور، ڏسڻ ريورس ڪرائونالوجي آرڊر ۾ آهي، ڇاڪاڻ ته سڀ کان تازا لاگ عام طور تي پهرين دلچسپي جا هوندا آهن.
- هر لڪير جي اڳيان ڏيکاريو حوالو (اختيارن
-A
,-B
и-C
уgrep
, پرنٽ ڪرڻ N سٽون اڳ، بعد ۾، ۽ هر ملندڙ لائن جي چوڌاري، ترتيب سان). - اصل وقت ۾ ايندڙ لاگ ڏسو، فلٽرنگ سان يا بغير (لازمي طور تي
tail -f | grep
). - انٽرفيس سان مطابقت هجڻ گهرجي
less
,head
,tail
۽ ٻيا - ڊفالٽ طور، نتيجن کي واپس ڪيو وڃي بغير انهن جي تعداد تي پابنديون؛ لائينون هڪ وهڪرو طور ڇپيل آهن جيستائين صارف انهن کي حاصل ڪرڻ ۾ دلچسپي رکي ٿو؛ سگنلSIGPIPE
خاموشيءَ سان لاگ اسٽريمنگ ۾ مداخلت ڪرڻ گهرجي، جيئن اهي ڪندا آهنtail
,grep
۽ ٻيون يونڪس يوٽيلٽيز.
عمل
مان سمجهان ٿو ته توهان اڳ ۾ ئي ڪنهن نه ڪنهن طرح ڄاڻو ٿا ته ڪلڪ هائوس ڏانهن لاگ ڪيئن پهچائڻ. جيڪڏهن نه، آئون ڪوشش ڪرڻ جي صلاح ڏيان ٿو
پهرين توهان کي بنيادي اسڪيم تي فيصلو ڪرڻ جي ضرورت آهي. جيئن ته توهان عام طور تي وقت جي ترتيب سان لاگز حاصل ڪرڻ چاهيو ٿا، اهو منطقي لڳي ٿو انهن کي انهي طريقي سان ذخيرو ڪرڻ. جيڪڏهن لاگ ڪيٽيگريز جا ڪيترائي قسم آهن ۽ اهي سڀ هڪ ئي قسم جا آهن، ته پوءِ توهان لاگ ڪيٽيگري ٺاهي سگهو ٿا پرائمري ڪيٽيگري جي پهرين ڪالمن جي طور تي - اهو توهان کي اجازت ڏيندو ته ڪيترن جي بدران هڪ ٽيبل رکي، جيڪو هڪ وڏو پلس هوندو. ڪلڪ هائوس ۾ داخل ڪرڻ (هارڊ ڊرائيو سان سرورز تي، ڊيٽا داخل ڪرڻ جي سفارش ڪئي وئي آهي ~ 1 ڀيرا في سيڪنڊ کان وڌيڪ نه پوري سرور لاءِ).
اھو آھي، اسان کي ھيٺ ڏنل جدول منصوبي جي ضرورت آھي:
CREATE TABLE logs(
category LowCardinality(String), -- категория логов (опционально)
time DateTime, -- время события
millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)
بدقسمتي سان، مون کي فوري طور تي حقيقي لاگن سان ڪو به کليل ذريعو ڳولي نه سگهيو، جنهن کي مان پڪڙي ۽ ڊائون لوڊ ڪري سگهان ٿو، تنهنڪري مون ان جي بدران مثال طور ورتو
ClickHouse تي Amazon جائزو اپلوڊ ڪرڻ لاءِ هدايتون
اچو ته هڪ ٽيبل ٺاهيو:
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
Amazon dataset ۾ صرف هڪ جائزو وٺڻ جي تاريخ آهي، پر ڪو به صحيح وقت نه آهي، تنهنڪري اچو ته هن ڊيٽا کي رينڊن سان ڀريون.
توهان کي سڀني tsv فائلن کي ڊائون لوڊ ڪرڻ جي ضرورت ناهي ۽ پنهنجو پاڻ کي پهرين ~ 10-20 تائين محدود ڪرڻ لاءِ ڊيٽا جو ڪافي وڏو سيٽ حاصل ڪرڻ لاءِ جيڪو 16 GB جي رام ۾ نه هوندو. 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
1000 GB جي سائيز سان گوگل ڪلائوڊ ۾ هڪ معياري پرسسٽنٽ ڊسڪ (جيڪا HDD آهي) تي (مون هن سائيز کي بنيادي طور تي ورتو آهي ته رفتار ٿوري گهڻي هئي، جيتوڻيڪ شايد گهربل سائيز جي SSD سستي هجي ها) اپلوڊ رفتار تقريبن ~ 75 MB / سيڪنڊ 4 ڪور تي هئي.
- مون کي هڪ رزرويشن ڪرڻ گهرجي ته آئون گوگل تي ڪم ڪريان ٿو، پر مون هڪ ذاتي اڪائونٽ استعمال ڪيو آهي ۽ هن آرٽيڪل جو ڪمپني ۾ منهنجي ڪم سان ڪو به تعلق ناهي
مان هن خاص ڊيٽا سيٽ سان سڀ عڪس پيدا ڪندس، ڇاڪاڻ ته اهو سڀ ڪجهه مون وٽ هو.
ڏيکاريو ڊيٽا اسڪيننگ ترقي
جيئن ته ڪلڪ هاؤس ۾ اسان لاگز سان گڏ ٽيبل تي مڪمل اسڪين استعمال ڪنداسين، ۽ اهو آپريشن تمام گهڻو وقت وٺي سگهي ٿو ۽ شايد گهڻي وقت تائين ڪو به نتيجو پيدا نه ڪري سگهي جيڪڏهن ڪجهه ميچ مليا وڃن، اهو مشورو ڏنو ويندو آهي ته ڏيکاريو وڃي. سوال جي ترقي جيستائين نتيجو سان گڏ پهرين قطارون حاصل ڪيون وڃن. هن کي ڪرڻ لاء، HTTP انٽرفيس ۾ هڪ پيٽرولر آهي جيڪو توهان کي HTTP هيڊرز ۾ پيش رفت موڪلڻ جي اجازت ڏئي ٿو: send_progress_in_http_headers=1
. بدقسمتي سان، معياري Go لائبريري هيڊر نه پڙهي سگهي ٿي جيئن اهي وصول ڪيا ويا آهن، پر HTTP 1.0 انٽرفيس (1.1 سان پريشان نه ٿيڻ گهرجي!) ClickHouse جي حمايت ڪئي وئي آهي، تنهنڪري توهان ڪلڪ ڪري سگهو ٿا هڪ خام TCP ڪنيڪشن ClickHouse ڏانهن ۽ ان کي اتي موڪليو. 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
.
گو ۾ 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 لاڳاپيل لڪير کي واپس ڪري ٿو، اهو ڪيش ۾ ختم ٿئي ٿو ۽ عام طور تي درخواست تي عمل ڪيو وڃي ٿو تمام جلدي ۽ ٿورو سي پي يو استعمال ڪري ٿو (عام طور تي درخواست منهنجي ورچوئل مشين تي اٽڪل ~ 6 ms لڳندي آهي).
حقيقي وقت ۾ نوان پيغام ڏيکاريو
(تقريبا) حقيقي وقت ۾ ايندڙ پيغامن کي ڏيکارڻ لاءِ، اسان صرف هر چند سيڪنڊن ۾ هڪ ڀيرو درخواست تي عمل ڪندا آهيون، آخري ٽائم اسٽيمپ کي ياد ڪندي جيڪو اسان اڳ ۾ ڏٺو هو.
حڪم جا مثال
عام 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
حوالن
يوٽيلٽي ڪوڊ (بغير دستاويزن جي) گيٿب تي دستياب آهي
جو ذريعو: www.habr.com