No High Ceph Latency līdz Kernel Patch ar eBPF/BCC

No High Ceph Latency līdz Kernel Patch ar eBPF/BCC

Linux ir liels skaits rÄ«ku, lai debugētu kodolu un lietojumprogrammas. Lielākā daļa no tiem negatÄ«vi ietekmē lietojumprogrammu veiktspēju un tos nevar izmantot ražoÅ”anā.

Pirms dažiem gadiem tika izstrādāts vēl viens rÄ«ks — eBPF. Tas ļauj izsekot kodolu un lietotnes ar zemu pārslodzi, neradot nepiecieÅ”amÄ«bu pārbÅ«vēt programmas un ielādēt treÅ”o puÅ”u moduļus kodolā. Å obrÄ«d jau pastāv daudzi lietojumprogrammu rÄ«ki, kas izmanto eBPF, un Å”ajā rakstā mēs apskatÄ«sim, kā uzrakstÄ«t savu profila rÄ«ku, pamatojoties uz bibliotēku

PythonBCC . Raksts balstÄ«ts uz reāliem notikumiem. Mēs iepazÄ«simies ar problēmas raÅ”anos un lÄ«dz tās novērÅ”anai, lai parādÄ«tu, kā esoÅ”ie rÄ«ki var tikt izmantoti konkrētās situācijās.Ceph ir lēns

Cehā Ceph pievienots jauns hosts. Pēc datu daļas migrācijas uz to mēs pamanÄ«jām, ka rakstīŔanas pieprasÄ«jumu apstrādes ātrums ir ievērojami zemāks nekā citos serveros.

AtŔķirÄ«bā no citām platformām, Å”ajā hostā tika izmantots bcache un jauns linux kodols 4.15. Šādas konfigurācijas hosts Å”eit tika izmantots pirmo reizi. Un brÄ«dÄ«, kad tas notika, bija skaidrs, ka problēmu cēlonis teorētiski varētu bÅ«t jebkas.

No High Ceph Latency līdz Kernel Patch ar eBPF/BCC
Izpētot hostu

Sāksim ar to, ka paskatīsimies, kas notiek ceph-osd procesā. Lai to izdarītu, mēs izmantosim

perf flamescope un (vairāk par kuriem var izlasÄ«t Attēls norāda, ka funkcija Å”eit):

No High Ceph Latency līdz Kernel Patch ar eBPF/BCC
tērēja daudz laika pieprasÄ«juma nosÅ«tīŔanā funkcijā fdatasync() generic_make_request() . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.Pārbaudot hostu, mēs atklājām, ka dema systemd-udevd patērē lielu CPU laiku — apmēram 20% vairākos kodolos. Å Ä« ir dÄ«vaina uzvedÄ«ba, tāpēc nepiecieÅ”ams noskaidrot tās iemeslu. Tā kā Systemd-udevd darbojas ar uevent'iem, mēs nolēmām tos izvērtēt, izmantojot

udevadm monitor . IzrādÄ«jās, ka sistēmā tika Ä£enerēts liels skaits change notikumu katram blokēŔanas ierÄ«cei. Tas ir diezgan neparasti, tāpēc bÅ«s jāskatās, kas Ä£enerē visus Å”os gadÄ«jumus.Izmantojot BCC rÄ«ku komplektu

Kā jau mēs noskaidrojām, kodols (un ceph dema sistēmas izsaukumā) tērē daudz laika

. Mēģināsim izmērÄ«t Ŕīs funkcijas darbÄ«bas ātrumu. Jau . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.pastāv lielisks rÄ«ks — BCC funclatency funclatency. Mēs izsekosim demonam pēc tā PID ar intervālu starp informācijas izvadēm 1 sekunde un izvadÄ«sim rezultātu milisekundēs.

No High Ceph Latency līdz Kernel Patch ar eBPF/BCC
Parasti Ŕī funkcija darbojas ātri. Viss, ko tā dara – pārsÅ«ta pieprasÄ«jumu uz ierÄ«ces draivera rindu.

Bcache ir kompleksa ierīce, kas faktiski sastāv no trim diskdziņiem:

  • backing device (keŔējams disks), Å”ajā gadÄ«jumā tas ir lēns HDD;
  • caching device (keŔējoÅ”ais disks), Å”eit tas ir viens NVMe ierÄ«ces nodalÄ«jums;
  • virtuālo ierÄ«ci bcache, ar kuru darbojas lietotne.

Mēs zinām, ka pieprasÄ«juma pārsÅ«tīŔana aizkavējas, bet kura no Ŕīm ierÄ«cēm? Par to runāsim nedaudz vēlāk.

Å obrÄ«d mēs zinām, ka uevent'i, iespējams, izraisa problēmas. Atrast, kas tieÅ”i izraisa to Ä£enerāciju, nav tik viegli. Pieņemam, ka tas ir kāds softs, ko periodiski palaidz. ApskatÄ«sim, kurÅ” softs tiek palaidÄ«ts sistēmā, izmantojot skriptu execsnoop no tā paÅ”a BCC utilÄ«tu komplekta. PalaidÄ«sim to un novirzÄ«sim izvadi uz failu.

Piemēram, Ŕādi:

/usr/share/bcc/tools/execsnoop  | tee ./execdump

NeizvirzÄ«sim Å”eit pilnu execsnoop izvadi, bet viena interesējoÅ”a rinda izskatÄ«jās Ŕādi:

sh 1764905 5802 0 sudo arcconf getconfig 1 AD | grep Temperature | awk -F '[:\/]' '{print $2}' | sed 's\/^ ([0-9]*) C.*\/1\/'

TreŔā kolonna ir PPID (vecāku PID) procesa. Process ar PID 5802 izrādÄ«jās viens no mÅ«su uzraudzÄ«bas sistēmas pavedieniem. Pārbaudot uzraudzÄ«bas sistēmas konfigurāciju, tika atrastas nepareizi iestatÄ«tas parametru vērtÄ«bas. HBA adaptera temperatÅ«ra tika nolasÄ«ta katras 30 sekundes, kas bija daudz biežāk nekā nepiecieÅ”ams. Pēc pārbaudes intervāla pagarināŔanas mēs atklājām, ka pieprasÄ«jumu apstrādes aizture Å”ajā hostā vairs nav izteikta, salÄ«dzinot ar pārējiem hostiem.

Bet joprojām nav skaidrs, kāpēc bcache ierÄ«ce tik aizkavējās. Mēs izveidojām testēŔanas platformu ar identisku konfigurāciju un mēģinājām reproducēt problēmu, palaidzot fio uz bcache, periodiski palaidzot udevadm trigger Ä£enerācijai.

Rakstīt BCC bāzētus rīkus

Mēģināsim uzrakstÄ«t vienkārÅ”u utilÄ«tu izsekoÅ”anai un ekrānā izvadīŔanai vislēnākajiem zvaniem . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.. MÅ«s arÄ« interesē diska nosaukums, kuram tika izsaukta Ŕī funkcija.

Plāns ir vienkārŔs:

  • ReÄ£istrējam kprobe uz . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.:
    • Saglabājam atmiņā diska nosaukumu, kas pieejams caur funkcijas argumentu;
    • Saglabājam laika zÄ«mogu.

  • ReÄ£istrējam kretprobe uz atgrieÅ”anos no . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.:
    • Saņemam paÅ”reizējo laika zÄ«mogu;
    • Meklējam saglabāto laika zÄ«mogu un salÄ«dzinām to ar paÅ”reizējo;
    • Ja, ja rezultāts ir lielāks par noteikto, tad atrodam saglabāto diska nosaukumu un izvadām to terminālā.

Kprobes un kretprobes izmanto punktu pārtraukÅ”anas mehānismu, lai dinamiski mainÄ«tu funkciju kodu. JÅ«s varat izlasÄ«t dokumenti un labu rakstu par Å”o tēmu. Ja aplÅ«ko dažādu utilÄ«tu kodu, tad var pamanÄ«t, ka tām ir identiska struktÅ«ra. Tādēļ Å”ajā rakstā mēs izlaidÄ«sim skripta argumentu parsēŔanu un pāriesim pie paÅ”as BPF programmas. BCCTeksts eBPF iekÅ” python skripta izskatās Ŕādi:

bpf_text = """ # Šeit būs bpf programmas kods """

Lai apmainītos ar datiem starp funkcijām, eBPF programmas izmanto

hash-tabulas . Mēs rīkosimies tāpat. Kā atslēgu izmantosim procesa PID, bet kā vērtību definēsim struktūru:struct data_t { u64 pid; u64 ts; char comm[TASK_COMM_LEN]; u64 lat; char disk[DISK_NAME_LEN]; };BPF_HASH(p, u64, struct data_t); BPF_PERF_OUTPUT(events);

Šeit mēs reģistrējam hash-tabulu, kas saucas

, ar atslēgas tipu pun vērtÄ«bu tipu u64 struct data_t . Tabula bÅ«s pieejama mÅ«su BPF programmas kontekstā. Makro BPF_PERF_OUTPUT reÄ£istrē citu tabulu, kas saucas, un tā tiek izmantota eventsdatenu pārsÅ«tīŔanai lietotāja telpā. Izmērot aizturi starp funkcijas izsaukumu un tās atgrieÅ”anos, vai starp dažādu funkciju izsaukumiem, jāņem vērā, ka iegÅ«tajiem datiem jāpieder vienam kontekstam. Citiem vārdiem sakot, jāatceras par iespējamu funkciju paralēlu izpildi. Mums ir iespēja izmērÄ«t aizturi starp funkcijas izsaukumu viena procesa kontekstā un atgrieÅ”anos no Ŕīs funkcijas cita procesa kontekstā, bet tas, visticamāk, bÅ«s bezjēdzÄ«gi. Labi piemērs var bÅ«t

utilita biolatency , kur hash-tabulas atslēga ir norāde uzstruct request , kas atspoguļo vienu pieprasījumu uz disku.Pēc tam mums jāuzraksta kods, kas tiks izpildīts, kad tiek izsaukta pētāmā funkcija:

void start(struct pt_regs *ctx, struct bio *bio) { u64 pid = bpf_get_current_pid_tgid(); struct data_t data = {}; u64 ts = bpf_ktime_get_ns(); data.pid = pid; data.ts = ts; bpf_probe_read_str(&data.disk, sizeof(data.disk), (void*)bio->bi_disk->disk_name); p.update(&pid, &data); }

Šeit kā otrais arguments tiks aizvietots ar pirmo izsauktās funkcijas argumentu.

Pēc tam mēs iegÅ«stam procesa PID, kurā darbojamies, un paÅ”reizējo laika zÄ«mogu nanosekundēs. Viss tiek ierakstÄ«ts jaunizveidotajā . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.struct data_t data struct data_t dataDisku nosaukumu iegÅ«stam no struktÅ«ras bio, kas tiek nodota izsaukuma laikā . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi., un saglabājam to tajā paŔā struktÅ«rā data. Pēdējais solis ir ieraksta pievienoÅ”ana iepriekÅ” minētajā hash tabulā.

Nākamā funkcija tiks izsaukta atgriežoties no . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi.:

void stop(struct pt_regs *ctx) {
    u64 pid = bpf_get_current_pid_tgid();
    u64 ts = bpf_ktime_get_ns();
    struct data_t* data = p.lookup(&pid);
    if (data != 0 && data->ts > 0) {
        bpf_get_current_comm(&data->comm, sizeof(data->comm));
        data->lat = (ts - data->ts) / 1000;
        if (data->lat > MIN_US) {
            FACTOR
            data->pid >>= 32;
            events.perf_submit(ctx, data, sizeof(struct data_t));
        }
        p.delete(&pid);
    }
}

Å Ä« funkcija ir lÄ«dzÄ«ga iepriekŔējai: mēs uzzinām procesa PID un laika zÄ«mogu, bet neizveidojam jaunu data struktÅ«ru. Tā vietā mēs meklējam esoÅ”o struktÅ«ru hash tabulā, izmantojot atslēgu == paÅ”reizējo PID. Ja struktÅ«ra tiek atrasta, mēs uzzinām palaistā procesa nosaukumu un pievienojam to tai.

Binārais pārvietojums, ko mēs Å”eit izmantojam, ir nepiecieÅ”ams, lai iegÅ«tu pavediena GID, t.i., PID galvenajam procesam, kas uzsāka pavedienu, kurā mēs strādājam. MÅ«su izsauktā funkcija bpf_get_current_pid_tgid() atgriež gan pavediena GID, gan tā PID vienā 64-bit vērtÄ«bā.

Izvades terminālÄ« mÅ«s paÅ”laik neinteresē pavediena, bet interesē galvenais process. Pēc saņemtās kavēŔanās salÄ«dzināŔanas ar noteikto slieksni mēs nododam savu struktÅ«ru data lietotāja telpā caur tabulu events, pēc tam dzēŔam ierakstu no p.

Python skriptā, kas ielādēs Å”o kodu, mums bÅ«s jāaizvieto MIN_US un FACTOR ar kavēŔanās sliekŔņiem un laika vienÄ«bām, kuras mēs nodosim caur argumentiem:

bpf_text = bpf_text.replace('MIN_US',str(min_usec))
if args.milliseconds:
	bpf_text = bpf_text.replace('FACTOR','data->lat /= 1000;')
	label = "msec"
else:
	bpf_text = bpf_text.replace('FACTOR','')
	label = "usec"

Tagad mums jāpreparē BPF programma caur BPF makro un jāreģistrē mēri:

b = BPF(text=bpf_text)
b.attach_kprobe(event="generic_make_request",fn_name="start")
b.attach_kretprobe(event="generic_make_request",fn_name="stop")

Mums arī būs jādefinē . Tabula būs pieejama mūsu BPF programmas kontekstā. Makro BPF_PERF_OUTPUT reģistrē citu tabulu, kas saucas mūsu skriptā, pretējā gadījumā neko nevarēsim izlasīt:

TASK_COMM_LEN = 16	# linux/sched.h
DISK_NAME_LEN = 32	# linux/genhd.h
class Data(ct.Structure):
	_fields_ = [("pid", ct.c_ulonglong),
            	("ts", ct.c_ulonglong),
            	("comm", ct.c_char * TASK_COMM_LEN),
            	("lat", ct.c_ulonglong),
            	("disk",ct.c_char * DISK_NAME_LEN)]

Pēdējais solis — datu izvade uz termināla:

def print_event(cpu, data, size):
    global start
    event = ct.cast(data, ct.POINTER(Data)).contents
    if start == 0:
        start = event.ts
    time_s = (float(event.ts - start)) / 1000000000
    print("%-18.9f %-16s %-6d   %-1s %s   %s" % (time_s, event.comm, event.pid, event.lat, label, event.disk))

b["events"].open_perf_buffer(print_event)
# format output
start = 0
while 1:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()

Scripts ir pieejams GItHub. Mēģināsim to palaist izmēģinājuma platformā, kur darbojas fio, rakstot uz bcache, un izsaukt udevadm monitor:

No High Ceph Latency līdz Kernel Patch ar eBPF/BCC
Beidzot! Tagad mēs redzam, ka tas, kas izskatÄ«jās kā bcache ierÄ«ces aizkave, patiesÄ«bā ir aizkave, kas notiek . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi. kā rezultātā no keÅ”otā diska.

Iedziļinieties Kernel

Kas tieÅ”i aizkavē pieprasÄ«juma nodoÅ”anu? Mēs redzam, ka aizkave rodas pat pirms pieprasÄ«juma kontā, t.i., konkrēta pieprasÄ«juma uzskaitīŔana turpmākai statistikas izsniegÅ”anai (/,proc/,diskstats vai iostat) vēl nav sākusies. To ir viegli pārbaudÄ«t, palaist iostat problēmas reproducēŔanas laikā, vai BCC skriptu biolatency, kas balstās uz pieprasÄ«juma kontēŔanas sākumu un beigām. Neviens no Å”iem rÄ«kiem neparādÄ«s problēmas pieprasÄ«jumiem uz keÅ”oto disku.

Ja mēs paskatāmies uz funkciju . Tas nozÄ«mē, ka, visticamāk, problēmu cēlonis atrodas ārpus paÅ”a osd dema. Tas var bÅ«t gan kodols, gan diski. iostat izvade parādÄ«ja augstu bcache disku pieprasÄ«jumu apstrādes aizturi., mēs redzam, ka pirms pieprasÄ«juma konta tiek izsauktas vēl divas funkcijas. Pirmā — generic_make_request_checks(), veic pieprasÄ«juma likumÄ«bas pārbaudes attiecÄ«bā uz diska iestatÄ«jumiem. Otrā — blk_queue_enter(), kurā ir interesants izsaukums, wait_event_interruptible():

ret = wait_event_interruptible(q->mq_freeze_wq,
	(atomic_read(&q->mq_freeze_depth) == 0 &&
	(preempt || !blk_queue_preempt_only(q))) ||
	blk_queue_dying(q));

Šajā funkcijā kodols gaida, kad queue tiek atkausēta. Mēs izmērīsim aizkavi blk_queue_enter():

~# /usr/share/bcc/tools/funclatency blk_queue_enter -i 1 -m               	 
Izsekoju 1 funkciju "blk_queue_enter"... Nospiediet Ctrl-C, lai pabeigtu.

 	msecs           	: skaits 	distribūcija
     	0 -> 1      	: 341  	|****************************************|

 	msecs           	: skaits 	distribūcija
     	0 -> 1      	: 316  	|****************************************|

 	msecs           	: skaits 	distribūcija
     	0 -> 1      	: 255  	|****************************************|
     	2 -> 3      	: 0    	|                                    	|
     	4 -> 7      	: 0    	|                                    	|
     	8 -> 15     	: 1    	|                                    	|

Izskatās, ka mēs esam tuvu atminējuma. Funkcijas, kas tiek izmantotas "iesaldēŔanai/atkausēŔanai" rindā — tas ir blk_mq_freeze_queue un blk_mq_unfreeze_queue. Tās tiek izmantotas, kad nepiecieÅ”ams mainÄ«t rindas pieprasÄ«jumu iestatÄ«jumus, kas ir potenciāli bÄ«stami pieprasÄ«jumiem, kas jau atrodas Å”ajā rindā. Izsaucot blk_mq_freeze_queue() funkciju blk_freeze_queue_start() tiek palielināts skaitÄ«tājs q->mq_freeze_depth. Pēc tam kods gaida, lÄ«dz rinda ir iztukÅ”ota blk_mq_freeze_queue_wait().

Å Ä«s rindas iztukÅ”oÅ”anas gaidīŔanas laiks ir ekvivalents diska kavēŔanās laikam, jo ​​kods gaida, lÄ«dz tiek pabeigtas visas iepriekÅ” ieplānotās operācijas. TiklÄ«dz rinda ir tukÅ”a, tiek piemēroti iestatÄ«jumi. Pēc tam tiek izsaukts blk_mq_unfreeze_queue(), kas samazina skaitÄ«tāju freeze_depth.

Tagad mēs zinām pietiekami, lai novērstu situāciju. Komanda udevadm trigger rezultātā noved pie iestatÄ«jumu piemēroÅ”anas blokierÄ«cei. Å ie iestatÄ«jumi ir aprakstÄ«ti udev noteikumos. Mēs varam noskaidrot, kuri iestatÄ«jumi Ā«iesaldē» rindu, mēģinot tos mainÄ«t caur sysfs vai apskatot kodu. Varam arÄ« izmēģināt BCC trace, kas parādÄ«s terminālÄ« kodu steka pēdas un lietotāja telpu katram izsaukumam blk_freeze_queue, piemēram:

~# /usr/share/bcc/tools/trace blk_freeze_queue -K -U
PID 	TID 	COMM        	FUNC        	
3809642 3809642 systemd-udevd   blk_freeze_queue
    	blk_freeze_queue+0x1 [kernel]
    	elevator_switch+0x29 [kernel]
    	elv_iosched_store+0x197 [kernel]
    	queue_attr_store+0x5c [kernel]
    	sysfs_kf_write+0x3c [kernel]
    	kernfs_fop_write+0x125 [kernel]
    	__vfs_write+0x1b [kernel]
    	vfs_write+0xb8 [kernel]
    	sys_write+0x55 [kernel]
    	do_syscall_64+0x73 [kernel]
    	entry_SYSCALL_64_after_hwframe+0x3d [kernel]
    	__write_nocancel+0x7 [libc-2.23.so]
    	[unknown]

3809631 3809631 systemd-udevd   blk_freeze_queue
    	blk_freeze_queue+0x1 [kernel]
    	queue_requests_store+0xb6 [kernel]
    	queue_attr_store+0x5c [kernel]
    	sysfs_kf_write+0x3c [kernel]
    	kernfs_fop_write+0x125 [kernel]
    	__vfs_write+0x1b [kernel]
    	vfs_write+0xb8 [kernel]
    	sys_write+0x55 [kernel]
    	do_syscall_64+0x73 [kernel]
    	entry_SYSCALL_64_after_hwframe+0x3d [kernel]
    	__write_nocancel+0x7 [libc-2.23.so]
    	[unknown]

Udev noteikumi mainās diezgan reti un parasti tas notiek kontrolēti. Tāpēc mēs redzam, ka pat iepriekÅ” noteikto vērtÄ«bu izmantoÅ”ana izraisa pieprasÄ«juma sÅ«tīŔanas kavēŔanās pie diska pieaugumu. Protams, Ä£enerēt udev notikumus, kad nav izmaiņu disku konfigurācijā (piemēram, ierÄ«ce netiek pievienota/atslēgta), nav Ä«paÅ”i laba prakse. Tomēr mēs varam palÄ«dzēt kodam neveikt nevajadzÄ«gu darbu un neĀ«iesaldētĀ» pieprasÄ«jumu rindu, ja tam nav vajadzÄ«bas. TrÄ«s mazo komitēŔanas novērÅ” situāciju.

Secinājums

eBPF ir ļoti elastīgs un jaudīgs rīks. Šajā rakstā mēs apskatījām vienu praktisku gadījumu un demonstrējām nelielu daļu no tā, ko ir iespējams izdarīt. Ja jūs interesē BCC rīku izstrāde, noteikti ieskatieties oficiālajā pamācībā, kas labi apraksta darba pamatus.

Ir arÄ« citi interesanti rÄ«ki atkļūdoÅ”anai un profilēŔanai, kas balstÄ«ti uz eBPF. Viens no tiem ir bpftrace, kas ļauj rakstÄ«t jaudÄ«gus vienrindas skriptus un mazas programmas uz awk lÄ«dzÄ«gas valodas. Cits — ebpf_exporter, ļauj vācēt augstas izŔķirtspējas zemu lÄ«meņa metriku tieÅ”i uz jÅ«su prometheus serveri, ar iespēju vēlāk iegÅ«t skaistu vizualizāciju un pat brÄ«dinājumus.

Avots: habr.com

Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem šŸ”„ Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem | ProHoster