الدعم الفعال هو جزء من نواة ريلز التي توفر ملحقات للغة روبي والأدوات المساعدة وغيرها من الأشياء. أحد الأشياء التي يتضمنها هو واجهة برمجية لأدوات قياس (instrumentation API) يمكن استخدامها داخل تطبيق لقياس إجراءات معينة تحدث داخل شيفرة روبي، مثل تلك الموجودة داخل تطبيق ريلز أو إطار العمل نفسه، إذ لا يقتصر ذلك على ريلز فقط. يمكن استخدامها بشكل مستقل في شيفرات روبي البرمجية الأخرى إذا كان ذلك مطلوبًا.
في هذا الدليل، ستتعلم كيفية استخدام الواجهة البرمجية لأدوات القياس (instrumentation API) داخل الدعم الفعال لقياس الأحداث داخل ريلز وغيرها من شيفرات روبي.
بعد قراءة هذا الدليل، ستتعلم:
- ما هي الأدوات المتوافرة.
- الخطافات داخل إطار ريلز لأدوات القياس.
- إضافة مُشترِك (subscriber) إلى خطاف.
- بناء تنفيذ مخصص لأداة قياس.
مقدمة إلى الأدوات
تسمح الواجهة البرمجية لأدوات القياس التي يوفرها الدعم الفعال لمطوري البرامج بتوفير خطافات يمكن لمطوري البرامج الآخرين استعمالها. هناك العديد منها في إطار ريلز. باستخدام واجهة برمجة التطبيقات هذه، يمكن للمطورين اختيار كيفية تنبيههم عند وقوع أحداث معينة داخل التطبيق أو في جزء آخر من شيفرة روبي.
على سبيل المثال، هناك خطاف يتوفر ضمن السجل الفعال يستدعى في كل مرة يستخدم السجل الفعال استعلام SQL في قاعدة بيانات. يمكن الاشتراك في هذا الخطاف واستخدامه لتتبع عدد طلبات البحث أثناء تنفيذ إجراء معين. هناك خطاف آخر حول معالجة إجراء وحدة التحكم. يمكن استخدام هذا، على سبيل المثال، لتتبع مدة تنفيذ إجراء معين.
يمكنك حتى إنشاء أحداثك الخاصة داخل تطبيقك والتي يمكنك الاشتراك فيها لاحقًا.
خطافات إطار ريلز
ضمن إطار ريلز، هناك عدد من الخطافات المتوافرة للأحداث الشائعة سنتظرق إليها في الأقسام الآتية.
وحدة التحكم
Write_fragment.action_controller
المفتاح
|
القيمة
|
:key
|
المفتاح الكامل.
|
{
key: 'posts/1-dashboard-view'
}
Read_fragment.action_controller
المفتاح
|
القيمة
|
:key
|
المفتاح الكامل.
|
{
key: 'posts/1-dashboard-view'
}
Expire_fragment.action_controller
المفتاح
|
القيمة
|
:key
|
المفتاح الكامل.
|
{
key: 'posts/1-dashboard-view'
}
Exist_fragment?.action_controller
المفتاح
|
القيمة
|
:key
|
المفتاح الكامل.
|
{
key: 'posts/1-dashboard-view'
}
Write_page.action_controller
المفتاح
|
القيمة
|
:key
|
المفتاح الكامل.
|
Expire_page.action_controller
المفتاح
|
القيمة
|
:path
|
المسار الكامل.
|
Start_processing.action_controller
المفتاح
|
القيمة
|
:controller
|
اسم وحدة التحكم
|
:action
|
الإجراء
|
:params
|
جدول Hash من معاملات الطلب دون أي معامل مرشح
|
:headers
|
ترويسات طلب
|
:format
|
html/js/json/xml ...إلخ.
|
:method
|
فعل طلب HTTP
|
:path
|
طلب المسار
|
{
controller: "PostsController",
action: "new",
params: { "action" => "new", "controller" => "posts" },
headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
format: :html,
method: "GET",
path: "/posts/new"
}
Process_action.action_controller
المفتاح
|
القيمة
|
:controller
|
اسم وحدة التحكم
|
:action
|
الإجراء
|
:params
|
جدول Hash لمعاملات الطلب من غير أي معامل مرشح
|
:headers
|
ترويسات الطلب
|
:format
|
html/js/json/xml ...إلخ.
|
:method
|
فعل طلب HTTP
|
:path
|
طلب المسار
|
:status
|
رمز حالة HTTP
|
:view_runtime
|
الكمية المستغرقة في واجهة العرض بالمللي ثانية.
|
:db_runtime
|
الكمية المستغرقة لتنفيذ استعلامات قاعدة البيانات بالميللي ثانية.
|
{
controller: "PostsController",
action: "index",
params: {"action" => "index", "controller" => "posts"},
headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
format: :html,
method: "GET",
path: "/posts",
status: 200,
view_runtime: 46.848,
db_runtime: 0.157
}
Send_file.action_controller
المفتاح
|
القيمة
|
:path
|
المسار الكامل.
|
ملاحظة: يمكن إضافة مفاتيح إضافية من قبل المتصل.
Send_data.action_controller
ليس لدى المتحكم ActionController
أي معلومات محددة للحمولة (payload). تُمرر جميع الخيارات إلى الحمولة (payload).
Redirect_to.action_controller
المفتاح
|
القيمة
|
:status
|
رمز استجابة HTTP
|
:location
|
عنوان URL لإعادة التوجيه إليه
|
{
status: 302,
location: "http://localhost:3000/posts/new"
}
Halted_callback.action_controller
القيمة
|
المفتاح
|
:filter
|
المرشح الذي أوقف الإجراء.
|
{
filter: ":halting_filter"
}
Unpermitted_parameters.action_controller
المفتاح
|
القيمة
|
:keys
|
المفاتيح غير مسموح بها.
|
إجراء العرض
Render_template.action_view
القيمة
|
المفتاح
|
المسار الكامل للقالب.
|
:identifier
|
تخطيط قابل للتطبيق.
|
:layout
|
{
identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb",
layout: "layouts/application"
}
Render_partial.action_view
القيمة
|
المفتاح
|
المسار الكامل للقالب.
|
:identifier
|
{
identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
}
Render_collection.action_view
المفتاح
|
القيمة
|
:identifier
|
المسار الكامل للقالب.
|
:count
|
حجم المجموعة.
|
:cache_hits
|
عدد الجزيئات التي جُلبت من ذاكرة التخزين المؤقت.
|
Cache_hits: يُضمن فقط إذا كانت المجموعة مقدمة مع cached: true.
{
identifier: "/Users/adam/projects/notifications/app/views/posts/_post.html.erb",
count: 3,
cache_hits: 0
}
السجل النشط
Sql.active_record
القيمة
|
المفتاح
|
جملة SQL.
|
:sql
|
اسم العملية.
|
:name
|
self.object_id
|
:connection_id
|
معاملات الربط.
|
:binds
|
تضاف true عند استخدام الاستعلامات المخبأة
|
:cached
|
ملاحظة: ستضيف المحولات البيانات الخاصة بها أيضًا.
{
sql: "SELECT \"posts\".* FROM \"posts\" ",
name: "Post Load",
connection_id: 70307250813140,
binds: []
}
Instantiation.active_record
القيمة
|
المفتاح
|
عدد السجلات التي أُنشئت نسخ لها.
|
:record_count
|
سجل الفئة.
|
:class_name
|
{
record_count: 1,
class_name: "User"
}
إجراء الإرسال
Receive.action_mailer
المفتاح
|
القيمة
|
:mailer
|
اسم فئة الارسال.
|
:message_id
|
معرف الرسالة، التي أُنشئت بواسطة جوهرة البريد.
|
:subject
|
موضوع البريد.
|
:to
|
لمعالجة (عناوين) البريد.
|
:from
|
من عنوان البريد.
|
:bcc
|
عناوين BCC للبريد.
|
:cc
|
عناوين CC للبريد.
|
:date
|
تاريخ البريد.
|
:mail
|
شكل مشفر للبريد.
|
{
mailer: "Notification",
message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",
subject: "Rails Guides",
to: ["users@rails.com", "dhh@rails.com"],
from: ["me@rails.com"],
date: Sat, 10 Mar 2012 14:18:09 +0100,
mail: "..." # omitted for brevity
}
Deliver.action_mailer
المفتاح
|
القيمة
|
:mailer
|
اسم فئة الارسال.
|
:message_id
|
معرف الرسالة، التي أُنشئت بواسطة جوهرة البريد.
|
:subject
|
موضوع البريد.
|
:to
|
لمعالجة (عناوين) البريد.
|
:from
|
من عنوان البريد.
|
:bcc
|
عناوين BCC للبريد.
|
:cc
|
عناوين CC للبريد.
|
:date
|
تاريخ البريد.
|
:mail
|
شكل مشفر للبريد.
|
{
mailer: "Notification",
message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",
subject: "Rails Guides",
to: ["users@rails.com", "dhh@rails.com"],
from: ["me@rails.com"],
date: Sat, 10 Mar 2012 14:18:09 +0100,
mail: "..." # omitted for brevity
}
Process.action_mailer
القيمة
|
المفتاح
|
اسم فئة الارسال.
|
:mailer
|
الإجراء.
|
:action
|
الحجج.
|
:args
|
{
mailer: "Notification",
action: "welcome_email",
args: []
}
الدعم الفعال
Cache_read.active_support
المفتاح
|
القيمة
|
:key
|
المفتاح المستخدم في المخزن.
|
:hit
|
إذا كانت هذه القراءة هي النتيجة.
|
:super_operation
|
#fetch عند إضافة قراءة مع :fetch
|
Cache_generate.active_support
يستخدم هذا الحدث فقط عندما تستدعى #fetch بعلامة.
القيمة
|
المفتاح
|
المفتاح المستخدم في المخزن.
|
:key
|
ملاحظة: تدمج الخيارات التي مُررت لجلب البيانات مع الحمولة عند الكتابة إلى المخزن.
{
key: 'name-of-complicated-computation'
}
Cache_fetch_hit.active_support
يستخدم هذا الحدث فقط عندما تستدعى #fetch بعلامة.
القيمة
|
المفتاح
|
المفتاح المستخدم في المخزن.
|
:key
|
ملاحظة: ملاحظة: تدمج الخيارات التي مُررت لجلب البيانات مع الحمولة.
{
key: 'name-of-complicated-computation'
}
Cache_write.active_support
القيمة
|
المفتاح
|
المفتاح المستخدم في المخزن.
|
:key
|
ملاحظة: قد تضيف مخازن ذاكرة التخزين المؤقت مفاتيحها الخاصة.
{
key: 'name-of-complicated-computation'
}
Cache_delete.active_support
القيمة
|
المفتاح
|
المفتاح المستخدم في المخزن.
|
:key
|
{
key: 'name-of-complicated-computation'
}
Cache_exist?.active_support
القيمة
|
المفتاح
|
المفتاح المستخدم في المخزن.
|
:key
|
{
key: 'name-of-complicated-computation'
}
الوظيفة النشطة
Enqueue_at.active_job
القيمة
|
المفتاح
|
كائن QueueAdapter يعالج الوظيفة.
|
:adapter
|
كائن الوظيفة.
|
:job
|
Enqueue.active_job
القيمة
|
المفتاح
|
كائن QueueAdapter يعالج الوظيفة.
|
:adapter
|
كائن الوظيفة.
|
:job
|
Perform_start.active_job
القيمة
|
المفتاح
|
كائن QueueAdapter يعالج الوظيفة.
|
:adapter
|
كائن الوظيفة.
|
:job
|
Perform.active_job
القيمة
|
المفتاح
|
كائن QueueAdapter يعالج الوظيفة.
|
:adapter
|
كائن الوظيفة.
|
:job
|
كابل العمل
Perform_action.action_cable
القيمة
|
المفتاح
|
اسم فئة القناة.
|
:channel_class
|
الإجراء.
|
:action
|
تجزئة البيانات.
|
:data
|
Transmit.action_cable
القيمة
|
المفتاح
|
اسم فئة القناة.
|
:channel_class
|
تجزئة البيانات.
|
:data
|
عبر.
|
:via
|
Transmit_subscription_confirmation.action_cable
القيمة
|
المفتاح
|
اسم فئة القناة.
|
:channel_class
|
Transmit_subscription_rejection.action_cable
القيمة
|
المفتاح
|
اسم فئة القناة.
|
:channel_class
|
Broadcast.action_cable
المفتاح
|
القيمة
|
:broadcasting
|
بث مسمى.
|
:message
|
تجزئة للرسالة.
|
:coder
|
المبرمج.
|
التخزين النشط
Service_upload.active_storage
القيمة
|
المفتاح
|
رمز آمن.
|
:key
|
اسم الخدمة.
|
:service
|
تدقيق لضمان السلامة.
|
:checksum
|
Service_streaming_download.active_storage
القيمة
|
المفتاح
|
رمز آمن.
|
:key
|
اسم الخدمة.
|
:service
|
Service_download.active_storage
القيمة
|
المفتاح
|
رمز آمن.
|
:key
|
اسم الخدمة.
|
:service
|
Service_delete.active_storage
القيمة
|
المفتاح
|
رمز آمن.
|
:key
|
اسم الخدمة.
|
:service
|
Service_delete_prefixed.active_storage
القيمة
|
المفتاح
|
بادئة المفتاح.
|
:prefix
|
اسم الخدمة.
|
:service
|
Service_exist.active_storage
القيمة
|
المفتاح
|
رمز آمن.
|
:key
|
اسم الخدمة.
|
:service
|
الملف أو السقوط موجود أم لا.
|
:exist
|
Service_url.active_storage
القيمة
|
المفتاح
|
رمز آمن.
|
:key
|
اسم الخدمة.
|
:service
|
عنوان URL أُنشأ.
|
:url
|
Railties
Load_config_initializer.railties
القيمة
|
المفتاح
|
المسار لتحميل مُهيئ من config / initializers.
|
:initializer
|
Rails
Deprecation.rails
القيمة
|
المفتاح
|
تحذير الانتقاص.
|
:message
|
من اين جاء الانتقاص.
|
:callstack
|
الاشتراك في الحدث
الاشتراك في حدث أمر سهل. استخدم ActiveSupport :: Notifications.subscribe مع كتلة للاستماع إلى أي إخطار.
يتلقى الكتلة الوسيطات التالية:
- اسم الحدث.
- الوقت عند البدء.
- الوقت عند الانتهاء.
- معرف فريد لهذا الحدث.
- الحمولة (الموضحة في الأقسام السابقة).
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, data|
# your own custom stuff
Rails.logger.info "#{name} Received!"
End
تعريف كل وسيطات الكتلة هذه في كل مرة يمكن أن تكون مملة. يمكنك بسهولة إنشاء ActiveSupport :: Notifications :: Event من وسيطات حظر مثل هذا:
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
event = ActiveSupport::Notifications::Event.new *args
event.name # => "process_action.action_controller"
event.duration # => 10 (in milliseconds)
event.payload # => {:extra=>information}
Rails.logger.info "#{event} Received!"
End
في معظم الأحيان، لا تهتم إلا بالبيانات نفسها. هنا هو اختصار للحصول على البيانات فقط.
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
data = args.extract_options!
data # { extra: :information }
End
يمكنك أيضًا الاشتراك في الأحداث التي تتطابق مع تعبير عادي. يتيح لك هذا الاشتراك في أحداث متعددة في وقت واحد. هنا يمكنك الاشتراك في كل شيء من ActionController.
ActiveSupport::Notifications.subscribe /action_controller/ do |*args|
# inspect all ActionController events
End
إنشاء أحداث مخصصة
إضافة الأحداث الخاصة بك من السهل كذلك. ActiveSupport::Notifications سيعتني بكل الرفع الثقيل من أجلك. ببساطة تستدعى instrument مع الاسم والحمولة والكتلة. سيرسل الإخطار بعد إرجاع الكتلة. ينشئ ActiveSupport أوقات البدء والانتهاء بالإضافة إلى المعرف الفريد. جميع البيانات التي مُررت إلى استدعاء instrument تجعلها في الحمولة.
إليك مثال على ذلك:
ActiveSupport::Notifications.instrument "my.custom.event", this: :data do
# do your custom stuff here
End
الآن يمكنك الاستماع إلى هذا الحدث مع:
ActiveSupport::Notifications.subscribe "my.custom.event" do |name, started, finished, unique_id, data|
puts data.inspect # {:this=>:data}
End
يجب عليك اتباع معايير Rails عند تحديد الأحداث الخاصة بك. التنسيق هو: event.library. إذا كان تطبيقك يرسل التغريدات، فيجب إنشاء حدث باسم tweet.twitter.
مصادر