นี่คือคำสั่ง perf-script-python ที่สามารถเรียกใช้ในผู้ให้บริการโฮสติ้งฟรีของ OnWorks โดยใช้หนึ่งในเวิร์กสเตชันออนไลน์ฟรีของเรา เช่น Ubuntu Online, Fedora Online, โปรแกรมจำลองออนไลน์ของ Windows หรือโปรแกรมจำลองออนไลน์ของ MAC OS
โครงการ:
ชื่อ
perf-script-python - ประมวลผลข้อมูลการติดตามด้วยสคริปต์ Python
เรื่องย่อ
perf ต้นฉบับ [-s [ไพธอน]:สคริปต์[.py] ]
DESCRIPTION
ตัวเลือกสคริปต์ perf นี้ใช้ในการประมวลผลข้อมูลสคริปต์ perf โดยใช้ Python . ในตัวของ perf
ล่าม. มันอ่านและประมวลผลไฟล์อินพุตและแสดงผลลัพธ์ของการติดตาม
การวิเคราะห์ดำเนินการในสคริปต์ Python ที่กำหนด หากมี
A QUICK ตัวอย่าง
ส่วนนี้แสดงกระบวนการ เริ่มจนจบ ของการสร้างสคริปต์ Python ที่ใช้งานได้ซึ่ง
รวบรวมและดึงข้อมูลที่เป็นประโยชน์จากสตรีมสคริปต์ perf ดิบ คุณสามารถหลีกเลี่ยง
อ่านส่วนที่เหลือของเอกสารนี้หากตัวอย่างเพียงพอสำหรับคุณ ส่วนที่เหลือของ
เอกสารให้รายละเอียดเพิ่มเติมในแต่ละขั้นตอนและแสดงรายการฟังก์ชั่นห้องสมุดที่มีให้
นักเขียนบท
ตัวอย่างนี้มีรายละเอียดขั้นตอนที่ใช้ในการสร้าง syscall-นับ ต้นฉบับ
คุณจะเห็นเมื่อคุณแสดงรายการสคริปต์ perf ที่มีอยู่ผ่านทาง perf ต้นฉบับ -l. เช่นนี้
สคริปต์ยังแสดงวิธีการรวมสคริปต์ของคุณเข้ากับรายการวัตถุประสงค์ทั่วไป perf
ต้นฉบับ สคริปต์ที่แสดงรายการโดยคำสั่งนั้น
สคริปต์การนับ syscall เป็นสคริปต์ธรรมดา แต่แสดงให้เห็นแนวคิดพื้นฐานทั้งหมด
จำเป็นในการสร้างสคริปต์ที่มีประโยชน์ นี่คือตัวอย่างผลลัพธ์ (ชื่อ syscall are
ยังไม่รองรับ จะปรากฏเป็นตัวเลข):
.ft ซี
เหตุการณ์ syscall:
จำนวนเหตุการณ์
---------------------------------------- ---------- -
sys_write455067
sys_getdents 4072
sys_close 3037
sys_swapoff 1769
sys_read 923
sys_sched_setparam 826
sys_open331
sys_newfstat 326
sys_mmap217
sys_munmap216
sys_futex 141
sys_select 102
sys_poll 84
sys_settimer 12
sys_writev8
15 8
sys_lsee 7
sys_rt_sigprocmask6
sys_wait4 3
sys_ioctl3
sys_set_robust_list 1
sys_exit1
56 1
sys_access1
.ฟุต
โดยพื้นฐานแล้ว หน้าที่ของเราคือเก็บจำนวนต่อซิสคอลที่ได้รับการอัปเดตทุกครั้งที่ระบบ
การโทรเกิดขึ้นในระบบ สคริปต์ของเราจะทำเช่นนั้น แต่ก่อนอื่นเราต้องบันทึกข้อมูล
ที่จะถูกประมวลผลโดยสคริปต์นั้น ในทางทฤษฎี มีอยู่สองสามวิธีที่เราทำได้
ทำอย่างนั้น:
· เราสามารถเปิดใช้งานทุกเหตุการณ์ภายใต้ไดเร็กทอรี tracing/events/syscalls แต่นี่คือ
มากกว่า 600 syscalls ซึ่งเกินจำนวนที่อนุญาตโดย perf syscall แต่ละตัวเหล่านี้
อย่างไรก็ตามเหตุการณ์จะเป็นประโยชน์หากเราต้องการใช้คำแนะนำที่เราได้รับจาก .ในภายหลัง
สคริปต์เอนกประสงค์เพื่อเจาะลึกและรับรายละเอียดเพิ่มเติมเกี่ยวกับ syscall แต่ละรายการของ
ดอกเบี้ย
· เราสามารถเปิดใช้งาน sys_enter และ/หรือ sys_exit syscalls ที่อยู่ภายใต้
การติดตาม/เหตุการณ์/raw_syscalls. สิ่งเหล่านี้ถูกเรียกสำหรับ syscall ทั้งหมด ที่ id สนามสามารถ
ใช้เพื่อแยกความแตกต่างระหว่างหมายเลข syscall แต่ละรายการ
สำหรับสคริปต์นี้ เราจำเป็นต้องรู้ว่ามีการป้อน syscall เท่านั้น เราไม่สนหรอกว่าจะเป็นเช่นไร
ออกแล้วเราจะใช้ perf ระเบียน เพื่อบันทึกเฉพาะเหตุการณ์ sys_enter:
.ft ซี
# บันทึก perf -a -e raw_syscalls:sys_enter
^C[ บันทึก perf: ตื่นมา 1 ครั้งเพื่อเขียนข้อมูล ]
[ บันทึก perf: จับภาพและเขียน perf.data 56.545 MB (~2470503 ตัวอย่าง) ]
.ฟุต
ตัวเลือกโดยทั่วไปบอกว่าจะรวบรวมข้อมูลสำหรับทุกเหตุการณ์ syscall ทั้งระบบและ
ทวีคูณเอาต์พุตต่อซีพียูลงในสตรีมเดียว สตรีมเดียวนั้นจะถูกบันทึกไว้ใน
ไฟล์ในไดเร็กทอรีปัจจุบันที่เรียกว่า perf.data
เมื่อเรามีไฟล์ perf.data ที่มีข้อมูลของเราแล้ว เราก็สามารถใช้ -g perf ต้นฉบับ ตัวเลือก
สร้างสคริปต์ Python ที่จะมีตัวจัดการการเรียกกลับสำหรับเหตุการณ์แต่ละประเภทที่พบใน
สตรีมการติดตาม perf.data (สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ส่วนสคริปต์เริ่มต้น)
.ft ซี
# สคริปต์ perf -g python
สร้างสคริปต์ Python: perf-script.py
ไฟล์เอาต์พุตที่สร้างในไดเร็กทอรีปัจจุบันยังมีชื่อว่า
perf-script.py นี่คือไฟล์ทั้งหมด:
# ตัวจัดการเหตุการณ์สคริปต์ perf สร้างโดย perf script -g python
# ได้รับอนุญาตภายใต้เงื่อนไขของ GNU GPL License รุ่น2
# ฟิลด์ตัวจัดการเหตุการณ์ common_* เป็นฟิลด์ที่มีประโยชน์ที่สุดร่วมกับ
#เหตุการณ์ทั้งหมด ไม่จำเป็นต้องตรงกับช่อง 'common_*'
#ในรูปแบบไฟล์. ฟิลด์เหล่านั้นไม่สามารถใช้ได้ในฐานะตัวจัดการ params can
# ถูกดึงโดยใช้ฟังก์ชัน Python ของแบบฟอร์ม common_*(บริบท)
# ดูเอกสารประกอบ perf-script-python สำหรับรายการฟังก์ชันที่มี
นำเข้าคุณ
sys นำเข้า
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
จากการนำเข้า perf_trace_context *
จากการนำเข้าหลัก *
def trace_begin():
พิมพ์ "ใน trace_begin"
def ติดตาม_end():
พิมพ์ "ใน trace_end"
def raw_syscalls__sys_enter (ชื่อเหตุการณ์, บริบท, common_cpu,
Common_secs, Common_nsecs, Common_pid, Common_comm,
รหัส, หาเรื่อง):
print_header(ชื่อเหตุการณ์, common_cpu, common_secs, common_nsecs,
Common_pid, Common_comm)
พิมพ์ "id=%d, args=%s\n" % \
(รหัส, หาเรื่อง),
def trace_unhandled (event_name, บริบท, common_cpu, common_secs, common_nsecs,
Common_pid, Common_comm):
print_header(ชื่อเหตุการณ์, common_cpu, common_secs, common_nsecs,
Common_pid, Common_comm)
def print_header (event_name, cpu, secs, nsecs, pid, comm):
พิมพ์ "%-20s %5u %05u.%09u %8u %-20s" % \
(event_name, cpu, วินาที, nsecs, pid, comm),
.ฟุต
ที่ด้านบนสุดคือบล็อกความคิดเห็น ตามด้วยคำสั่งนำเข้าและพาธผนวกซึ่ง
สคริปต์ perf ทุกสคริปต์ควรมี
ต่อไปนี้เป็นฟังก์ชันที่สร้างขึ้นสองสามอย่าง trace_begin() และ trace_end() ซึ่งเป็น
เรียกขึ้นต้นและท้ายบทตามลำดับ (ดูรายละเอียดเพิ่มเติมที่
SCRIPT_LAYOUT ด้านล่าง)
ต่อไปนี้คือ เหตุการณ์ จัดการ ฟังก์ชันที่สร้างขึ้นสำหรับทุกเหตุการณ์ใน perf
ระเบียน เอาท์พุท ฟังก์ชันตัวจัดการใช้รูปแบบระบบย่อยเหตุการณ์_ชื่อ, และ บรรจุ ชื่อ
พารามิเตอร์ หนึ่ง for แต่ละ สนาม in เหตุการณ์; in นี้ กรณี, มีสถานที่ เพียง หนึ่ง เหตุการณ์
raw_syscallssys_enter(). (ดูส่วนการจัดการเหตุการณ์ด้านล่างสำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์
ตัวจัดการ)
ฟังก์ชันคู่สุดท้ายเหมือนกับฟังก์ชันเริ่มต้นและสิ้นสุด ซึ่งสร้างขึ้นสำหรับทุกๆ
สคริปต์ ครั้งแรก trace_unhandled() ถูกเรียกทุกครั้งที่สคริปต์พบเหตุการณ์ใน
ไฟล์ perf.data ที่ไม่สอดคล้องกับตัวจัดการเหตุการณ์ในสคริปต์ นี้สามารถ
หมายความว่าขั้นตอนการบันทึกบันทึกประเภทเหตุการณ์ที่ไม่สนใจจริงๆ
หรือสคริปต์ถูกเรียกใช้โดยเทียบกับไฟล์การติดตามที่ไม่สอดคล้องกับสคริปต์
สคริปต์ที่สร้างโดยตัวเลือก -g เพียงพิมพ์บรรทัดสำหรับแต่ละเหตุการณ์ที่พบใน trace
กระแสคือโดยพื้นฐานแล้วเพียงแค่ทิ้งเหตุการณ์และค่าพารามิเตอร์ไปที่ stdout ดิ
ฟังก์ชัน print_header() เป็นเพียงฟังก์ชันยูทิลิตี้ที่ใช้เพื่อจุดประสงค์นั้น มาเปลี่ยนชื่อกันเถอะ
สคริปต์และเรียกใช้เพื่อดูผลลัพธ์เริ่มต้น:
.ft ซี
#mv perf-script.py syscall-counts.py
# สคริปต์ perf -s syscall-counts.py
raw_syscalls__sys_enter 1 00840.847582083 7506 perf id=1, หาเรื่อง=
raw_syscalls__sys_enter 1 00840.847595764 7506 perf id=1, หาเรื่อง=
raw_syscalls__sys_enter 1 00840.847620860 7506 perf id=1, หาเรื่อง=
raw_syscalls__sys_enter 1 00840.847710478 6533 npviewer.bin id=78, args=
raw_syscalls__sys_enter 1 00840.847719204 6533 npviewer.bin id=142, args=
raw_syscalls__sys_enter 1 00840.847755445 6533 npviewer.bin id=3, args=
raw_syscalls__sys_enter 1 00840.847775601 6533 npviewer.bin id=3, args=
raw_syscalls__sys_enter 1 00840.847781820 6533 npviewer.bin id=3, args=
.
.
.
.ฟุต
แน่นอน สำหรับสคริปต์นี้ เราไม่สนใจที่จะพิมพ์ทุกเหตุการณ์การติดตาม แต่
รวบรวมไว้อย่างมีประโยชน์ ดังนั้นเราจะกำจัดทุกอย่างที่เกี่ยวกับการพิมพ์เช่นกัน
เป็นฟังก์ชัน trace_begin() และ trace_unhandled() ซึ่งเราจะไม่ใช้งาน ใบนั้น
พวกเราด้วยโครงกระดูกที่เรียบง่ายนี้:
.ft ซี
นำเข้าคุณ
sys นำเข้า
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
จากการนำเข้า perf_trace_context *
จากการนำเข้าหลัก *
def ติดตาม_end():
พิมพ์ "ใน trace_end"
def raw_syscalls__sys_enter (ชื่อเหตุการณ์, บริบท, common_cpu,
Common_secs, Common_nsecs, Common_pid, Common_comm,
รหัส, หาเรื่อง):
.ฟุต
ใน trace_end() เราจะพิมพ์ผลลัพธ์ง่ายๆ แต่ก่อนอื่น เราต้องสร้างผลลัพธ์ขึ้นมาก่อน
ปริ้น. ในการทำเช่นนั้นเราจำเป็นต้องมีตัวจัดการ sys_enter() ทำการนับที่จำเป็น
จนกว่าจะนับเหตุการณ์ทั้งหมด ตารางแฮชที่จัดทำดัชนีโดย syscall id เป็นวิธีที่ดีในการ
จัดเก็บข้อมูลนั้น ทุกครั้งที่มีการเรียกตัวจัดการ sys_enter() เราเพียงแค่เพิ่มขึ้น
จำนวนที่เกี่ยวข้องกับรายการแฮชที่จัดทำดัชนีโดย syscall id นั้น:
.ft ซี
syscalls = อัตโนมัติ ()
ลอง:
syscalls[id] += 1
ยกเว้น TypeError:
syscalls[id] = 1
.ฟุต
syscalls อัตโนมัติ object เป็นพจนานุกรม Python ชนิดพิเศษ (ใช้งานใน
Core.py) ที่ใช้ Perl's การทำให้เป็นอัตโนมัติ แฮชใน Python เช่น autovivifying
แฮช คุณสามารถกำหนดค่าแฮชที่ซ้อนกันได้โดยไม่ต้องไปสร้างปัญหาให้ยุ่งยาก
ระดับกลางหากไม่มีอยู่เช่น syscalls[comm][pid][id] = 1 จะสร้าง
ระดับแฮชระดับกลางและสุดท้ายกำหนดค่า 1 ให้กับรายการแฮชสำหรับ id (เพราะ
ค่าที่กำหนดไม่ใช่แฮชออบเจกต์ ค่าเริ่มต้นถูกกำหนดใน
ข้อยกเว้น TypeError อาจมีวิธีที่ดีกว่าในการทำเช่นนี้ใน Python แต่นั่นคือสิ่งที่
ใช้งานได้ในตอนนี้)
การใส่รหัสนั้นลงในตัวจัดการ raw_syscalls__sys_enter() เราจะได้ a . อย่างมีประสิทธิภาพ
พจนานุกรมระดับเดียวบน syscall id และมีการนับที่เรานับเป็นค่า
ฟังก์ชัน print_syscall_totals() จะวนซ้ำรายการในพจนานุกรมและ
แสดงบรรทัดสำหรับแต่ละรายการที่มีชื่อ syscall (คีย์พจนานุกรมประกอบด้วย
รหัส syscall ซึ่งส่งผ่านไปยังฟังก์ชัน Util syscall_name() ซึ่งแปลว่า
หมายเลข syscall ดิบไปยังสตริงชื่อ syscall ที่เกี่ยวข้อง) ผลลัพธ์คือ
แสดงหลังจากประมวลผลเหตุการณ์ทั้งหมดในการติดตามแล้ว โดยเรียก
ฟังก์ชัน print_syscall_totals() จากตัวจัดการ trace_end() ที่เรียกที่ส่วนท้ายของสคริปต์
การประมวลผล
สคริปต์สุดท้ายที่สร้างผลลัพธ์ที่แสดงด้านบนจะแสดงอย่างครบถ้วนด้านล่าง
(syscall_name() helper ยังไม่พร้อมใช้งาน คุณสามารถจัดการกับ id ได้ในตอนนี้เท่านั้น):
.ft ซี
นำเข้าคุณ
sys นำเข้า
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
จากการนำเข้า perf_trace_context *
จากการนำเข้าหลัก *
จาก Util นำเข้า *
syscalls = อัตโนมัติ ()
def ติดตาม_end():
print_syscall_totals()
def raw_syscalls__sys_enter (ชื่อเหตุการณ์, บริบท, common_cpu,
Common_secs, Common_nsecs, Common_pid, Common_comm,
รหัส, หาเรื่อง):
ลอง:
syscalls[id] += 1
ยกเว้น TypeError:
syscalls[id] = 1
def print_syscall_totals ():
ถ้า for_comm ไม่ใช่ None:
พิมพ์ "\nsyscall events for %s:\n\n" % (for_comm),
อื่น:
พิมพ์ "\nsyscall events:\n\n",
พิมพ์ "%-40s %10s\n" % ("เหตุการณ์", "นับ"),
พิมพ์ "%-40s %10s\n" % ("------------------------------------------- ---", \
"-----------"),
สำหรับ id, val ใน sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \
ย้อนกลับ = จริง):
พิมพ์ "%-40s %10d\n" % (syscall_name(id), val),
.ฟุต
สคริปต์สามารถรันได้เหมือนเมื่อก่อน:
# สคริปต์ perf -s syscall-counts.py
นั่นคือขั้นตอนสำคัญในการเขียนและรันสคริปต์ กระบวนการสามารถ
สรุปไปยังจุดติดตามหรือชุดของจุดติดตามที่คุณสนใจ โดยทั่วไป find
จุดติดตามที่คุณสนใจโดยดูจากรายการเหตุการณ์ที่มีอยู่ซึ่งแสดงโดย
perf รายการ และ/หรือดูใน /sys/kernel/debug/tracing events สำหรับรายละเอียดเหตุการณ์และ field
ข้อมูล บันทึกข้อมูลการติดตามที่เกี่ยวข้องโดยใช้ perf ระเบียน, ผ่านรายการของ
เหตุการณ์ที่น่าสนใจ สร้างสเกเลตันสคริปต์โดยใช้ perf ต้นฉบับ -g หลาม และแก้ไข
รหัสเพื่อรวมและแสดงผลตามความต้องการเฉพาะของคุณ
หลังจากที่คุณทำเสร็จแล้ว คุณอาจได้สคริปต์เอนกประสงค์ที่คุณต้องการเก็บไว้
และพร้อมสำหรับการใช้งานในอนาคต ด้วยการเขียนเชลล์สคริปต์ง่ายๆ สองสามตัว
และวางไว้ในที่ที่ถูกต้อง คุณสามารถแสดงสคริปต์ของคุณควบคู่ไปกับรายการอื่นๆ ได้
สคริปต์รายการโดย perf ต้นฉบับ -l คำสั่งเช่น:
.ft ซี
root@tropicana:~# สคริปต์ perf -l
รายการของสคริปต์การติดตามที่ใช้ได้:
เวลาในการตอบสนองของ Wakeup-latency ต่ำสุด/สูงสุด/เฉลี่ยทั่วทั้งระบบ
rw-by-file กิจกรรม r/w สำหรับโปรแกรม โดย file
rw-by-pid กิจกรรม r/w ทั่วทั้งระบบ
.ฟุต
ผลข้างเคียงที่ดีของการทำเช่นนี้ก็คือคุณจะจับภาพความยาวได้ perf
ระเบียน คำสั่งที่จำเป็นในการบันทึกเหตุการณ์สำหรับสคริปต์
เพื่อให้สคริปต์ปรากฏเป็น built-in สคริปต์ คุณเขียนสคริปต์ง่ายๆ สองสคริปต์ สคริปต์หนึ่งสำหรับ
บันทึกและหนึ่งสำหรับ การรายงาน.
พื้นที่ ระเบียน script เป็นเชลล์สคริปต์ที่มีชื่อฐานเดียวกับสคริปต์ของคุณ แต่มี
-record ต่อท้าย ควรใส่เชลล์สคริปต์ลงใน perf/scripts/python/bin
ไดเร็กทอรีในแผนผังต้นทางเคอร์เนล ในสคริปต์นั้น คุณเขียน perf ระเบียน
บรรทัดคำสั่งที่จำเป็นสำหรับสคริปต์ของคุณ:
.ft ซี
# cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-record
#!/ bin / bash
บันทึก perf -a -e raw_syscalls:sys_enter
.ฟุต
พื้นที่ รายงาน สคริปต์ยังเป็นเชลล์สคริปต์ที่มีชื่อฐานเดียวกับสคริปต์ของคุณ แต่มี
- รายงานต่อท้าย นอกจากนี้ยังควรอยู่ในไดเร็กทอรี perf/scripts/python/bin ใน
สคริปต์นั้นคุณเขียน perf ต้นฉบับ -s บรรทัดคำสั่งที่จำเป็นสำหรับการรันสคริปต์ของคุณ:
.ft ซี
# cat เคอร์เนลแหล่งที่มา / เครื่องมือ / perf / scripts / python / bin / syscall-counts-report
#!/ bin / bash
# คำอธิบาย: จำนวน syscall ทั้งระบบ
สคริปต์ perf -s ~/libexec/perf-core/scripts/python/syscall-counts.py
.ฟุต
โปรดทราบว่าตำแหน่งของสคริปต์ Python ที่ระบุในเชลล์สคริปต์อยู่ใน
libexec/perf-core/scripts/python ไดเร็กทอรี - นี่คือที่ที่สคริปต์จะถูกคัดลอกโดย
ทำ ติดตั้ง เมื่อคุณติดตั้งประสิทธิภาพ สำหรับการติดตั้งเพื่อติดตั้งสคริปต์ของคุณที่นั่น
สคริปต์ของคุณต้องอยู่ในไดเร็กทอรี perf/scripts/python ในแหล่งเคอร์เนล
ต้นไม้:
.ft ซี
# ls -al เคอร์เนลซอร์ส / เครื่องมือ / perf / scripts / python
root@tropicana:/home/trc/src/tip# ls -al tools/perf/scripts/python
รวม 32
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 น.
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
drwxr-xr-x 2 trz trz 4096 2010-01-26 22:29 น
-rw-r--r-- 1 trz trz 2548 2010-01-26 22:29 check-perf-script.py
drwxr-xr-x 3 trz trz 4096 2010-01-26 22:49 Perf-Trace-Util
-rw-r--r-- 1 trz trz 1462 2010-01-26 22:30 น. syscall-counts.py
.ฟุต
เมื่อคุณทำเสร็จแล้ว (อย่าลืมทำใหม่ ทำ ติดตั้งมิฉะนั้นสคริปต์ของคุณจะไม่
ปรากฏขึ้นที่รันไทม์) perf ต้นฉบับ -l ควรแสดงรายการใหม่สำหรับสคริปต์ของคุณ:
.ft ซี
root@tropicana:~# สคริปต์ perf -l
รายการของสคริปต์การติดตามที่ใช้ได้:
เวลาในการตอบสนองของ Wakeup-latency ต่ำสุด/สูงสุด/เฉลี่ยทั่วทั้งระบบ
rw-by-file กิจกรรม r/w สำหรับโปรแกรม โดย file
rw-by-pid กิจกรรม r/w ทั่วทั้งระบบ
syscall-counts ทั้งระบบ syscall counts
.ฟุต
ตอนนี้คุณสามารถทำตามขั้นตอนการบันทึกผ่าน perf ต้นฉบับ ระเบียน:
# บันทึกสคริปต์ perf syscall-counts
และแสดงผลโดยใช้ perf ต้นฉบับ รายงาน:
# รายงานสคริปต์ perf syscall-counts
STARTER สคริปต์
คุณสามารถเริ่มต้นเขียนสคริปต์สำหรับชุดข้อมูลการติดตามโดยเฉพาะได้อย่างรวดเร็วโดย
การสร้างสคริปต์โครงกระดูกโดยใช้ perf ต้นฉบับ -g หลาม ในไดเร็กทอรีเดียวกับ an
ไฟล์การติดตาม perf.data ที่มีอยู่ ที่จะสร้างสคริปต์เริ่มต้นที่มีตัวจัดการ
สำหรับแต่ละประเภทเหตุการณ์ในไฟล์การติดตาม มันเพียงแค่พิมพ์ทุกฟิลด์ที่มีอยู่สำหรับ
แต่ละเหตุการณ์ในไฟล์การติดตาม
คุณยังสามารถดูสคริปต์ที่มีอยู่ใน ~/libexec/perf-core/scripts/python for
ตัวอย่างทั่วไปที่แสดงวิธีทำสิ่งพื้นฐาน เช่น ข้อมูลเหตุการณ์รวม ผลการพิมพ์
เป็นต้น นอกจากนี้ สคริปต์ check-perf-script.py ซึ่งไม่น่าสนใจสำหรับผลลัพธ์ของมัน
พยายามใช้คุณลักษณะการเขียนสคริปต์หลักทั้งหมด
เหตุการณ์ แฮนด์เลอร์
เมื่อเรียกใช้สคริปต์ perf โดยใช้สคริปต์การติดตาม ผู้ใช้กำหนด จัดการ ฟังก์ชัน is
เรียกแต่ละเหตุการณ์ในการติดตาม หากไม่มีฟังก์ชันตัวจัดการที่กำหนดไว้สำหรับ
ประเภทเหตุการณ์ เหตุการณ์จะถูกละเว้น (หรือส่งผ่านไปยังa ติดตาม_จัดการ ฟังก์ชั่น ดูด้านล่าง) และ
กิจกรรมถัดไปจะได้รับการประมวลผล
ค่าฟิลด์ของเหตุการณ์ส่วนใหญ่จะถูกส่งผ่านเป็นอาร์กิวเมนต์ไปยังฟังก์ชันตัวจัดการ บางส่วนของ
สิ่งที่พบได้น้อยกว่านั้นไม่มี - สิ่งเหล่านี้มีให้สำหรับการโทรกลับเข้าสู่โปรแกรมปฏิบัติการที่สมบูรณ์แบบ
(ดูด้านล่าง)
ตัวอย่างเช่น คำสั่ง perf record ต่อไปนี้สามารถใช้บันทึก sched_wakeup . ทั้งหมดได้
เหตุการณ์ในระบบ:
# บันทึก perf -a -e sched:sched_wakeup
ร่องรอยที่ตั้งใจจะประมวลผลโดยใช้สคริปต์ควรถูกบันทึกด้วยตัวเลือกด้านบน: -a
เพื่อเปิดใช้งานการรวบรวมทั้งระบบ
ไฟล์รูปแบบสำหรับเหตุการณ์ sched_wakep กำหนดฟิลด์ต่อไปนี้ (ดู
/sys/kernel/debug/tracing/events/sched/sched_wakeup/รูปแบบ):
.ft ซี
รูปแบบ:
ฟิลด์:unsigned สั้น ๆ common_type;
ฟิลด์:ถ่านที่ไม่ได้ลงนาม common_flags;
ฟิลด์:ถ่านที่ไม่ได้ลงนาม common_preempt_count;
ฟิลด์:int common_pid;
ฟิลด์:char comm[TASK_COMM_LEN];
ฟิลด์:pid_t pid;
ฟิลด์:int พรีโอ;
field:int สำเร็จ;
ฟิลด์:int target_cpu;
.ฟุต
ฟังก์ชันตัวจัดการสำหรับเหตุการณ์นี้จะถูกกำหนดเป็น:
.ft ซี
def sched__sched_wakeup (ชื่อเหตุการณ์, บริบท, common_cpu, common_secs,
Common_nsecs, Common_pid, Common_comm,
comm, pid, prio, สำเร็จ, target_cpu):
ส่ง
.ฟุต
ฟังก์ชันตัวจัดการใช้รูปแบบ subsystem__event_name
อาร์กิวเมนต์ common_* ในรายการอาร์กิวเมนต์ของ handler คือชุดของอาร์กิวเมนต์ที่ส่งผ่านไปยัง
ตัวจัดการเหตุการณ์ทั้งหมด ฟิลด์บางฟิลด์สอดคล้องกับฟิลด์ common_* ในรูปแบบ
ไฟล์ แต่บางส่วนถูกสังเคราะห์ และฟิลด์ common_* บางฟิลด์ไม่ธรรมดาพอที่จะ
ถูกส่งไปยังทุกเหตุการณ์เป็นอาร์กิวเมนต์ แต่มีให้ใช้งานเป็นฟังก์ชันไลบรารี
ต่อไปนี้คือคำอธิบายสั้น ๆ ของ args เหตุการณ์ที่ไม่เปลี่ยนแปลงแต่ละรายการ:
event_name ชื่อของเหตุการณ์เป็นข้อความ
บริบท 'คุกกี้' ทึบแสงที่ใช้ในการโทรกลับเป็น perf
common_cpu ซีพียูที่เหตุการณ์เกิดขึ้น
common_secs ส่วนวินาทีของการประทับเวลาเหตุการณ์
common_nsecs ส่วน nsecs ของการประทับเวลาของเหตุการณ์
common_pid pid ของงานปัจจุบัน
common_comm ชื่อของกระบวนการปัจจุบัน
ฟิลด์ที่เหลือทั้งหมดในไฟล์รูปแบบของเหตุการณ์มีคู่เป็นตัวจัดการ
อาร์กิวเมนต์ของฟังก์ชันที่มีชื่อเดียวกัน ดังแสดงในตัวอย่างด้านบน
ข้อมูลข้างต้นเป็นพื้นฐานที่จำเป็นในการเข้าถึงทุกฟิลด์ของทุกเหตุการณ์ใน .โดยตรง
trace ซึ่งครอบคลุม 90% ของสิ่งที่คุณต้องรู้เพื่อเขียนสคริปต์การติดตามที่มีประโยชน์ NS
ส่วนด้านล่างครอบคลุมส่วนที่เหลือ
สคริปต์ การจัดวาง
สคริปต์ Perf ทุกสคริปต์ Python ควรเริ่มต้นด้วยการตั้งค่าเส้นทางการค้นหาโมดูล Python และ
'นำเข้า' โมดูลสนับสนุนบางส่วน (ดูคำอธิบายโมดูลด้านล่าง):
.ft ซี
นำเข้าคุณ
sys นำเข้า
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
จากการนำเข้า perf_trace_context *
จากการนำเข้าหลัก *
.ฟุต
สคริปต์ที่เหลือสามารถมีฟังก์ชันตัวจัดการและฟังก์ชันสนับสนุนในลำดับใดก็ได้
นอกเหนือจากฟังก์ชันตัวจัดการเหตุการณ์ที่กล่าวถึงข้างต้น ทุกสคริปต์สามารถใช้ set . ได้
ของฟังก์ชั่นเสริม:
ติดตาม_เริ่มต้นหากกำหนดไว้ จะถูกเรียกก่อนที่จะประมวลผลเหตุการณ์ใดๆ และให้สคริปต์ a
โอกาสในการทำงานตั้งค่า:
.ft ซี
def trace_begin:
ส่ง
.ฟุต
ติดตาม_endหากกำหนดไว้ จะถูกเรียกหลังจากเหตุการณ์ทั้งหมดได้รับการประมวลผลและให้สคริปต์ a
โอกาสในการทำงานส่วนท้ายของสคริปต์ เช่น แสดงผล:
.ft ซี
กำหนดการติดตาม_end:
ส่ง
.ฟุต
ติดตาม_ไม่ได้จัดการหากกำหนดไว้ จะถูกเรียกหลังจากเหตุการณ์ใดๆ ที่ไม่มีตัวจัดการ
กำหนดไว้อย่างชัดเจนสำหรับมัน ชุดมาตรฐานของอาร์กิวเมนต์ทั่วไปถูกส่งผ่านเข้าไป:
.ft ซี
def trace_unhandled (event_name, บริบท, common_cpu, common_secs,
Common_nsecs, Common_pid, Common_comm):
ส่ง
.ฟุต
ส่วนที่เหลือให้คำอธิบายของสคริปต์ perf ที่มีอยู่แล้วภายในแต่ละตัว
โมดูล Python และฟังก์ชันที่เกี่ยวข้อง
พร้อมใช้งาน โมดูล AND ฟังก์ชั่น
ส่วนต่อไปนี้จะอธิบายฟังก์ชันและตัวแปรที่พร้อมใช้งานผ่าน perf . ต่างๆ
สคริปต์โมดูล Python ในการใช้ฟังก์ชันและตัวแปรจากโมดูลที่กำหนด ให้เพิ่ม
ตรงกัน ราคาเริ่มต้นที่ xxxx นำเข้า ไปที่สคริปต์สคริปต์ perf ของคุณ
Core.py โมดูล
ฟังก์ชันเหล่านี้จัดเตรียมฟังก์ชันที่จำเป็นบางอย่างให้กับสคริปต์ผู้ใช้
พื้นที่ flag_str และ symbol_str ฟังก์ชันจัดเตรียมสตริงที่มนุษย์สามารถอ่านได้สำหรับแฟล็กและสัญลักษณ์
ฟิลด์ สิ่งเหล่านี้สอดคล้องกับสตริงและค่าที่แยกวิเคราะห์จาก พิมพ์ เอฟเอ็มที ทุ่งนา
ไฟล์รูปแบบเหตุการณ์:
flag_str(event_name, field_name, field_value) - ส่งคืนการแสดงสตริงที่สอดคล้องกับ field_value สำหรับฟิลด์แฟล็ก field_name ของเหตุการณ์ event_name
symbol_str(event_name, field_name, field_value) - ส่งคืนการแสดงสตริงที่สอดคล้องกับ field_value สำหรับฟิลด์สัญลักษณ์ field_name ของเหตุการณ์ event_name
พื้นที่ อัตโนมัติ ฟังก์ชั่นส่งคืนพจนานุกรม Python ชนิดพิเศษที่ใช้ Perl's
การทำให้เป็นอัตโนมัติ แฮชใน Python เช่น แฮช autovivifying คุณสามารถกำหนด hash ที่ซ้อนกันได้
ค่าโดยไม่ต้องไปลำบากในการสร้างระดับกลางถ้าไม่
มีอยู่
autodict() - คืนค่าอินสแตนซ์พจนานุกรมอัตโนมัติ
perf_trace_context โมดูล
บางส่วนของ ร่วมกัน ฟิลด์ในไฟล์รูปแบบเหตุการณ์นั้นไม่ธรรมดาทั้งหมด แต่ต้องเป็น
ทำให้สามารถเข้าถึงสคริปต์ผู้ใช้ได้
perf_trace_context กำหนดชุดของฟังก์ชันที่สามารถใช้เพื่อเข้าถึงข้อมูลนี้ใน
บริบทของเหตุการณ์ปัจจุบัน แต่ละฟังก์ชันเหล่านี้ต้องการตัวแปรบริบท ซึ่งก็คือ
เหมือนกับตัวแปรบริบทที่ส่งผ่านไปยังตัวจัดการเหตุการณ์ทุกตัวเป็นอาร์กิวเมนต์ที่สอง
common_pc(บริบท) - ส่งกลับจำนวน common_preempt สำหรับเหตุการณ์ปัจจุบัน
common_flags(บริบท) - ส่งคืน common_flags สำหรับเหตุการณ์ปัจจุบัน
common_lock_depth(บริบท) - ส่งคืน common_lock_depth สำหรับเหตุการณ์ปัจจุบัน
Util.py โมดูล
ฟังก์ชันยูทิลิตี้ต่างๆ สำหรับใช้กับสคริปต์ perf:
nsecs(secs, nsecs) - ส่งคืน nsec ทั้งหมดที่ได้รับคู่ secs/nsecs
nsecs_secs(nsecs) - ส่งคืนส่วนวินาทีทั้งหมดที่กำหนด nsecs
nsecs_nsecs(nsecs) - ส่งคืน nsecs ส่วนที่เหลือที่กำหนด nsecs
nsecs_str(nsecs) - ส่งคืนสตริงที่พิมพ์ได้ในรูปแบบ secs.nsecs
เฉลี่ย (รวม n) - ส่งกลับค่าเฉลี่ยโดยให้ผลรวมและจำนวนค่าทั้งหมด
ใช้ perf-script-python ออนไลน์โดยใช้บริการ onworks.net