0

Bóc Tách Các Thành Phần Có Trong Class LogSlackQueue Trong Laravel

Trong các hệ thống xử lý nghiệp vụ phức tạp (như E-commerce, Logistics, Giao vận), việc theo dõi (monitor) trạng thái ứng dụng real-time qua các ứng dụng chat như Slack là vô cùng quan trọng.

Để tránh việc gửi log lên Slack làm chậm ứng dụng chính, người ta thường xây dựng một Queue Job chuyên trách mang tên LogSlackQueue. Vậy bên trong LogSlackQueue gồm có những thành phần nào và mỗi thành phần đóng vai trò gì? Hãy cùng bóc tách chi tiết dưới đây.

1. Cấu Trúc Tổng Quan Của Class LogSlackQueue

Một Class LogSlackQueue tiêu chuẩn trong Laravel thường có cấu trúc dạng:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;

class LogSlackQueue implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    // 1. Các thuộc tính (Properties)
    protected string $title;
    protected array $payload;
    protected string $channel;
    protected bool $isFullRequest;

    // 2. Hàm khởi tạo (Constructor)
    public function __construct(
        string $title,
        array $payload = [],
        string $channel = 'default',
        bool $isFullRequest = false
    ) {
        $this->title = $title;
        $this->payload = $payload;
        $this->channel = $channel;
        $this->isFullRequest = $isFullRequest;
    }

    // 3. Hàm xử lý chính (Handle)
    public function handle(): void
    {
        // Logic format dữ liệu & bắn webhook sang Slack
    }
}

2. Chi Tiết Các Thành Phần Bắt Buộc Phải Có

🧩 Thành Phần 1: Các Trait & Interface Chuẩn Của Laravel Queue

  • implements ShouldQueue: Khai báo cho Laravel biết Class này không chạy ngay lập tức mà sẽ được quăng vào hàng đợi (Queue) để chạy ngầm (asynchronous).
  • use Dispatchable: Cho phép gọi hàm dạng LogSlackQueue::dispatch(...) cực kỳ ngắn gọn.
  • use Queueable: Cho phép gắn các method điều hướng hàng đợi như ->onQueue('slack'), ->delay(...).
  • use InteractsWithQueue: Giúp Job có thể tự xóa ($this->delete()), thử lại ($this->release()) hoặc kiểm tra số lần đã thử ($this->attempts()).
  • use SerializesModels: Đảm bảo các Model truyền vào Constructor được mã hóa an toàn khi lưu vào database/Redis queue và giải mã lại khi Worker xử lý.

🧩 Thành Phần 2: Các Thuộc Tính Đầu Vào (Data Properties)

Đây là "nguyên liệu" truyền từ ứng dụng vào Job để chuẩn bị gửi lên Slack:

  • $title (string): Tiêu đề của Log (ví dụ: App\Services\OrderService::chooseStock - SendNextStockWarehouseChatJob). Giúp Dev nhìn vào biết ngay log này phát sinh từ chức năng nào.
  • $payload / $data (array): Chứa dữ liệu chi tiết cần kiểm tra, thường bao gồm mảng ['request' => ..., 'response' => ...].
  • $channel / $webhookUrl (string): Kênh Slack sẽ nhận thông báo (ví dụ: kênh #log-order-debug, #log-errors...).
  • $isFullRequest (bool): Cờ (flag) điều khiển việc cắt ngắn hay giữ nguyên 100% dữ liệu log.

🧩 Thành Phần 3: Hàm Khởi Tạo __construct()

Nơi nhận toàn bộ dữ liệu khi bạn gọi lệnh dispatch(). Nhờ tính năng PHP 8 Named Arguments, bạn có thể linh hoạt chọn truyền hoặc bỏ qua các tham số mặc định khi khởi tạo:

// Ví dụ khi truyền bằng Named Arguments
LogSlackQueue::dispatch(
    title: 'Order Status Changed',
    payload: $data,
    isFullRequest: true // Bỏ qua tham số $channel để lấy mặc định
);

🧩 Thành Phần 4: Hàm Xử Lý Chi Tiết handle()

Đây là "trái tim" của Class. Khi Worker nhặt Job này ra khỏi Queue, hàm handle() sẽ tự động chạy với các bước:

Step A: Format & Làm sạch dữ liệu (Data Formatting) Xử lý cờ $isFullRequest để tránh làm tràn màn hình Slack:

$formattedPayload = $this->payload;

// Nếu isFullRequest = false, tiến hành cắt ngắn bớt chuỗi JSON quá dài
if (!$this->isFullRequest) {
    $formattedPayload = $this->truncateData($formattedPayload);
}

Step B: Dựng giao diện tin nhắn Slack (Slack Block Kit Format) Chuyển đổi mảng dữ liệu thành định dạng JSON đẹp mắt mà Slack hỗ trợ (gồm các block, màu sắc đánh dấu error/info, timestamp):

$slackMessage = [
    'text' => "📢 *{$this->title}*",
    'attachments' => [
        [
            'color' => '#36a64f', // Màu xanh lục lá cây cho Success, đỏ cho Error
            'fields' => [
                [
                    'title' => 'Environment',
                    'value' => config('app.env'),
                    'short' => true,
                ],
                [
                    'title' => 'Payload',
                    'value' => "```" . json_encode($formattedPayload, JSON_PRETTY_PRINT) . "```",
                    'short' => false,
                ]
            ],
            'footer' => 'System Log Monitor',
            'ts' => time()
        ]
    ]
];

Step C: Bắn dữ liệu sang Slack qua Webhook API Sử dụng Http client của Laravel để gửi Request:

Http::post($this->getSlackWebhookUrl($this->channel), $slackMessage);

💡 Tóm Lược Sơ Đồ Hoạt Động

[ Controller / Service ]
          │
          ▼  (1) LogSlackQueue::dispatch(title, payload, isFullRequest: true)
   [ Queue Storage ] (Redis / Database / SQS)
          │
          ▼  (2) Worker nhặt Job ra xử lý ngầm
   [ LogSlackQueue -> handle() ]
          ├── (a) Kiểm tra isFullRequest để giữ/cắt bớt payload
          ├── (b) Format mảng thành Slack Block JSON đẹp mắt
          └── (c) Gọi HTTP POST đến Slack Webhook URL
          │
          ▼
    [ Kênh Slack nhận thông báo ]

🎯 Tóm lại:

Class LogSlackQueue là sự kết hợp hoàn hảo giữa Queue trong Laravel (giúp chạy ngầm không hoãn request của khách) và Slack Webhook API (giúp thông báo real-time). Việc nắm rõ các thành phần bên trong giúp bạn dễ dàng tùy biến giao diện log hoặc thêm bớt các thuộc tính debug theo nhu cầu dự án.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí