Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

การ Monitor Monolithic อย่างมีประสิทธิภาพ: จัดระเบียบข้อมูลด้วย Namespaces

Namespaces คืออะไร?

ทุกสิ่งที่เกิดขึ้นในแอปพลิเคชันที่ AppSignal monitor จะถูกล็อกไว้ภายใต้ namespace Namespaces ทำงานเหมือนโฟลเดอร์ จัดกลุ่ม events, issues และข้อมูล monitoring ให้เป็นชิ้นๆ ที่จัดการได้

โดยค่าเริ่มต้น ทุกแอปพลิเคชันเริ่มต้นด้วยสาม default namespaces: web, background, และ frontend

  • Web namespace เก็บ HTTP requests ทั้งหมด ใน MVC frameworks เช่น Rails หรือ Sinatra รวมถึง controller actions
  • Background namespace เก็บกิจกรรมจาก background jobs, libraries และ tasks
  • Frontend namespace ล็อก events ที่ส่งโดย AppSignal for JavaScript integration

AppSignal map incoming events ด้วย built-in per-application และ per-integration rules แต่คุณเปลี่ยน mapping ได้ตลอดเวลาและสร้าง namespace ใหม่เพื่อ model โครงสร้างแอปพลิเคชัน

ลอง Namespaces ใน Ruby

ลอง namespaces บนแอป Ruby on Rails (ROR) หลังสร้าง Rails project ใหม่ด้วย rails new และ setup rails integration จะพบ namespace web ใน dashboard

AppSignal แสดง namespace ทันทีที่รับ transactions จาก controllers ใดๆ

Default namespaces ที่เหลือจะไม่現身จนกว่าจะมีกิจกรรมในนั่น มาเพิ่มอะไรสักอย่างใน background namespace ให้น่าสนใจ นี่คือ dashboard หลังเพิ่ม Sidekiq ในโปรเจกต์ (เช็คโค้ดใน examples repository)

AppSignal กำหนด action ให้ background namespace เพราะรู้จัก Sidekiq เป็น job processor AppSignal integrate กับ background processors ยอดนิยมส่วนใหญ่ แต่ถ้าของคุณไม่อยู่ในรายการ สามารถเพิ่ม instrumentation ให้ jobs เองได้

สร้าง Custom Namespaces

ในแอป monolithic ใหญ่ Default namespaces อาจ generic เกินไป เว็บไซต์ใหญ่ปกติ serve static content, dynamic pages, API endpoints และ web services อื่นๆ ส่วนใหญ่จะรวมอยู่ใน namespace web

นอกจากนี้ ทุกส่วนของแอปมี priority ต่างกัน ปัญหาหน้า login ด่วนกว่าภายใน admin panel แต AppSignal จัดการ issues ทั้งหมดใน namespace เท่าๆ กัน เมื่อกิจกรรมเยอะ ยากที่จะระบุ issues สำคัญที่สุด

ดังนั้นควรจัดระเบียบ namespaces ตาม priority และพื้นที่ความรับผิดชอบ แล้วผูก notification policies แยกกัน และแจ้งเตือนเฉพาะฝ่ายที่เกี่ยวข้อง ตามเหตุผลนี้ สร้าง custom namespaces สำหรับ login_page, api_endpoints, และ admin_panel

สร้าง namespace ใหม่ใน Ruby ใช้ Appsignal.set_namespace ดูโค้ดสร้าง job ใน namespace urgent_background:

class FetchPricesWorker
  include Sidekiq::Worker

  def perform
    Appsignal.set_namespace("urgent_background")
    # worker code ...
  end
end

หลังเปลี่ยนและ restart app job ใหม่จะปรากฏใน namespace ที่สร้างใหม่:

ยืนยันได้ว่า job จริงถูกล็อกโดยเช็ค action name ใน dashboard:

Custom namespaces ทำงานใน integrations ทั้งหมด

การ Ignore Namespaces

ประโยชน์อีกอย่างของ custom namespaces คือปล่อยให้เราไม่สนใจ events จากส่วนของแอปที่ไม่สนใจ เช่น ignore events จาก admin_panel ทั้งหมด

Ignore namespace 3 ขั้นตอน:

  1. Assign ส่วนที่ไม่อยาก monitor ให้ custom namespace
  2. Config integration ให้ ignore namespace นั้น
  3. Restart app

สำหรับ Ruby เพิ่ม option ignore_namespaces ใน AppSignal config file:

production:
  ignore_namespaces:
    - "admin_panel"

Ignore namespace ข้าม transaction และ span data ทั้งหมดที่ source Custom metric data ยังรายงานต่อ

Elixir และ JavaScript integrations มี options เหมือนกัน ดูรายละเอียดใน ignoring namespaces guide

Namespaces สำหรับ Monolithic Applications

ตอนนี้รู้ namespaces works แล้ว มาดูวิธีใช้ partition monolithic application

ไม่มีกติกาตายตัว แต partition สิ้นสุดลงที่สองกลยุทธ์ เลือกอย่างใดอย่างหนึ่งหรือผสมทั้งสอง:

  • By role (ตามบทบาท): assign namespaces ให้ functional หรือ logical units ในโปรเจกต์ อาจเหมาะสม define namespaces เช่น billing, sign_in หรือ sign_up, admin_panel, และ homepage เพียงสายตา AppSignal dashboard เข้าใจทุกส่วนของแอป วิธีนี้ดีเมื่อโค้ดแยกด้วยขอบเขตชัดเจน
  • By severity (ตามความรุนแรง): ใช้ namespaces เป็นเครื่องมือ prioritizing ตัดสินใจเองว่าส่วนไหน critical, important, medium, หรือ low วิธีนี้ให้ sort ปัญหาที่อยากแก้ก่อนได้ทันที

สมมติมี controllers จัดการ user sign in และ registration เลือก partition by role map ให้ namespace user_login:

# ใน Rails ใช้ before_action callback เปลี่ยน namespace ก่อน request เริ่ม
class LoginController < ApplicationController
  before_action :set_appsignal_namespace

  def set_appsignal_namespace
    # Sets the namespace
    Appsignal.set_namespace("user_login")
  end

  # controller actions ...
end

แต่ถ้าชอบ priority namespaces controller จัดการ billing น่าจะไปใน namespace critical:

class BillingPageController < ApplicationController
  before_action :set_appsignal_namespace

  def set_appsignal_namespace
    Appsignal.set_namespace("critical")
  end
end

Controllers ที่สืบทอดจากนี้ share namespace เดียวกับ parent:

# controllers ใดๆ ที่สืบทอดจาก LoginController
# ก็เป็นส่วนของ namespace "user_login" เช่นกัน
class RegistrationController < LoginController
  # ไม่ต้อง before_action ที่นี่
  # controller นี้ report ไป namespace ของ parent แล้ว
end

Jobs และ tasks ถูก assign ให้ background namespace อัตโนมัติ ควร assign ให้ specific namespaces มากขึ้น เช่น database cleanup job ไปใน database namespace:

class ActiveJobDatabaseCleanupJob < ActiveJob::Base
  queue_as :default

  def perform(argument = nil, options = {})
    Appsignal.set_namespace("database")
    ...
  end
end

Priorities ทำงานกับ jobs ได้ เช่น assign unimportant tasks ให้ low ใน Rake task:

task :unimportant_job do
  # Run this rake job in the low namespace
  Appsignal.set_namespace("low")
  # job code ...
end

บางกรณีอยาก log actions ด้วย manual transaction กำหนด namespace ขณะสร้างได้ เช่น custom mailer job:

class Job
  def perform
    # Create a transaction for this job and set the namespace
    transaction = Appsignal::Transaction.create(
      SecureRandom.uuid,
      "mailer",
      Appsignal::Transaction::GenericRequest.new(ENV.to_hash)
    )
    # job code ...
  end
end

Namespaces และ Notifications

ไม่ใช่ทุกคนในทีมต้องได้รับแจ้งทุกปัญหา Frontend specialists ไม่สนใจ background jobs เท่า backend developers แต่พวกเขาอาจอยากรู้เวลามีปัญหาใน backend Backend developers แน่ใจอยากได้แจ้ง performance issues ใน namespace web Namespaces ให้ route notifications ไปคนที่เหมาะสม

ตั้งค่า Per-Namespace Notifiers

สร้าง notification groups ที่ active เฉพาะ namespace เฉพาะ เช่น ส่ง email สำหรับ errors ใน web namespace หรือส่งข้อความไป #frontend Slack channel สำหรับ issues ใน frontend namespace

สร้าง per-namespace notification groups ไปที่ App Settings > Notifications > Notifiers คลิก Add Integration

เลือก integration และพิมพ์ชื่อ เลือกประเภทข้อความที่ส่งและ namespace ไหน เช่น สร้าง Slack notification สำหรับ channel #frontend

ขณะอยู่ที่นี่ สร้าง notification ที่สองสำหรับ backend developers:

Config notifiers ได้เท่าที่ต้องการเพื่อให้ทีม up-to-date กับทุกสิ่งที่เกิดขึ้น

เปลี่ยน Per-Namespace Notifications

เมื่อ incident ถูกสร้าง AppSignal จะ apply notification policy โดยอิง namespace ที่ error มา สามารถ define policies แยกต่อ namespace ได้

ดู namespace defaults ของแอปที่ App Settings > Notifications > Namespace defaults

ที่นี่มี options ปรับแต่ง error และ performance notifications สำหรับทุก namespace:

  • Every occurrence: ส่ง notification ทุกครั้งที่ incident triggered พร้อม 5-minute cooldown
  • First on deploy: แจ้ง error แรกหลัง deploy แอป
  • First after close: ส่ง notification ครั้งแรกที่ issue ที่ปิดแล้วถูกเปิดใหม่
  • Never notify: ปิด notifications ทั้งหมด

สร้าง Per-Namespace Triggers

Triggers บอก AppSignal สร้าง incident และส่ง notifications เมื่อ metric ข้ามเกินหรือต่ำกว่าค่าที่กำหนด เนื่องจากส่วนต่างๆ ของแอปอาจมี threshold ต่างกัน ควรสร้าง triggers แยกต่อ namespace ตัวอย่างคลาสสิกคือ trigger แจ้งเมื่อ throughput ต่ำเกินไปใน web namespace

สร้าง trigger ไปที่ Anomaly Detection > Triggers คลิก Add your first trigger

เลือก Actions trigger type ด้านซ้าย และเลือก namespace ที่เกี่ยวข้อง ตั้ง thresholds ที่ trigger alert

ที่นี่ยัง define ได้ว่ากลุ่มไหนควรได้รับแจ้ง คลิก Save Trigger เพื่อเสร็จสิ้น

สรุป

Namespaces ช่วยทำความเข้าใจข้อมูล monitoring ของแอปพลิเคชัน ยังจำเป็นสำหรับการยิง notifications และ incidents บนระดับละเอียด จำกัด noise และหลีกเลี่ยง false positives

หลังเช็ค custom namespaces works บน Ruby, Node.js, และ Elixir อ่านต่อเพื่อเรียนรู้การใช้ namespaces:

  • Namespaces in AppSignal
  • Grouping with namespaces
  • What's The Difference Between Monitoring Webhooks and Background Jobs
  • Gem 2.2 - Custom namespaces!