הגדרת רישום מרכזי עם Loki ו-Grafana

האם הלוגים מפוזרים על פני שרתים, והופכים את חיפוש סיבת התקלה למסע ארוך? אנו מקימים ריכוז לוגים מרכזי עם Grafana Loki ו-Promtail, ואוספים את הנתונים במקום אחד. הצוות שלנו מספק את הפרויקט במפתח מלא—מהתצורה ועד יצירת לוחות מחוונים ידידותיים למשתמש—ומבטיח פעילות אמינה ותמיכה מתמשכת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
הגדרת רישום מרכזי עם Loki ו-Grafana
בינוני
~3-5 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1504
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1307
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1050
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

עם ניסיון של 7+ שנים ולמעלה מ-40 התקנות production, אנו מספקים מערכות Loki חזקות. לוגים מפוזרים על פני עשרות שרתים — מציאת שורש התקלה הופכת למסע של שבוע. בעומסי שיא, לוגים אובדים, וחיפוש שגיאה לוקח שעות. אנו פותרים זאת ביום אחד: הקמת ריכוז לוגים מרכזי עם Grafana Loki ו-Promtail. בניגוד ל-ELK, Loki אינו מבצע אינדקס לתוכן, אלא רק לתוויות (labels). בפועל, זה מניב חיסכון של עד 70% באחסון ופי שניים עד שלושה פחות עומס תפעולי. בפרויקט אחד עם 50 מיקרוסרוויסים (10 מיליון בקשות ביום), צמצמנו את זמן הגילוי מיומיים ל-15 דקות. צרו קשר — נשלים את ההתקנה תוך 2-3 ימים. עלות התקנה בסיסית מתחילה ב-$500 עבור המערכת (Loki, Promtail, Grafana על Docker; מקור לוג אחד).

למה Loki עדיף על Elasticsearch

לפי הנתונים הרשמיים של Grafana Labs, Loki מספק חיסכון של עד 70% באחסון בהשוואה ל-ELK. עם 500 GB של לוגים ביום, החיסכון החודשי יכול להגיע ל-$10,000. Loki מאחסן לוגים בנתחים דחוסים ללא אינדקס הפוך. מהירות השאילתה לפי תוויות היא במילישניות. אם אין צורך באגרגציה מורכבת על שדות שרירותיים, Loki הוא הבחירה הנכונה. החיסכון בתשתית יכול לנוע בין $5,000 ל-$15,000 בחודש בהתאם לנפח הלוגים.

קריטריון Loki ELK
עלות אחסון נמוכה (נתחים דחוסים) גבוהה (אינדקס הפוך)
מהירות חיפוש לפי תוויות מהירה בינונית
חיפוש טקסט מלא מוגבל מלא
מורכבות תפעולית נמוכה (קובץ בינארי יחיד) גבוהה (שלוש מערכות)
אינטגרציה עם Grafana טבעית דרך תוסף

כיצד אנו מתקינים את המערכת

אנו משתמשים ב-Docker Compose להתקנה מהירה. התצורה כוללת שלושה שירותים:

---
version: '3.8'
services:
  loki:
    image: grafana/loki:3.0.0
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/local-config.yaml
      - loki_data:/loki
    command:
      -config.file=/etc/loki/local-config.yaml
  promtail:
    image: grafana/promtail:3.0.0
    volumes:
      - /var/log:/var/log:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - ./promtail-config.yml:/etc/promtail/config.yml
    command:
      -config.file=/etc/promtail/config.yml
  grafana:
    image: grafana/grafana:11.0.0
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_SECURITY_ADMIN_PASSWORD=admin_password
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
volumes:
  loki_data:
  grafana_data:

תצורת Loki

---
auth_enabled: false
server:
  http_listen_port: 3100
  grpc_listen_port: 9096
common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory
schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h
limits_config:
  retention_period: 744h # 31 день
  ingestion_rate_mb: 16
  ingestion_burst_size_mb: 32
  max_query_length: 721h
compactor:
  working_directory: /loki/compactor
  retention_enabled: true
  delete_request_store: filesystem

תצורת Promtail

server:
  http_listen_port: 9080
  grpc_listen_port: 0
  positions:
    filename: /tmp/positions.yaml
  clients:
    - url: http://loki:3100/loki/api/v1/push
scrape_configs:
  - job_name: nginx
    static_configs:
      - targets: [localhost]
        labels:
          job: nginx
          env: production
          __path__: /var/log/nginx/access.log
    pipeline_stages:
      - regex:
          expression: '^(?P<ip>\S+) - (?P<user>\S+) \[(?P<timestamp>[^\]]+)\] "(?P<method>\S+) (?P<path>\S+) \S+" (?P<status>\d+) (?P<bytes>\d+)'
      - labels:
          status:
          method:
      - timestamp:
          source: timestamp
          format: "02/Jan/2006:15:04:05 -0700"
  - job_name: laravel
    static_configs:
      - targets: [localhost]
        labels:
          job: laravel-app
          env: production
          __path__: /var/www/app/storage/logs/laravel.log
    pipeline_stages:
      - multiline:
          firstline: '^\[\d{4}-\d{2}-\d{2}'
          max_wait_time: 3s
      - regex:
          expression: '^\[(?P<timestamp>[^\]]+)\] (?P<env>\w+)\.(?P<level>\w+): (?P<message>.*)'
      - labels:
          level:
          env:
      - timestamp:
          source: timestamp
          format: "2006-01-02 15:04:05"
  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 5s
    relabel_configs:
      - source_labels: [__meta_docker_container_name]
        target_label: container
      - source_labels: [__meta_docker_container_log_stream]
        target_label: logstream
התקנה ב-Kubernetes עבור Kubernetes, השתמשו ב-Helm charts: `helm install loki grafana/loki-stack` — זה יפרוס את Loki, Promtail ו-Grafana עם הגדרות ברירת מחדל. עבור production, כווננו retention, תוויות ו-pipeline_stages דרך values.yaml.

כיצד לשלב את Laravel עם Loki דרך Monolog

אנו כותבים handler מותאם אישית ל-Monolog ששולח רשומות לוג ל-Loki דרך HTTP API. זה עובד בשיטת fire-and-forget — אינו חוסם את הבקשה.

// app/Logging/LokiHandler.php
namespace App\Logging;

use Monolog\Handler\AbstractProcessingHandler;
use Monolog\LogRecord;

class LokiHandler extends AbstractProcessingHandler
{
    public function __construct(
        private string $lokiUrl,
        private array $labels = []
    ) {
        parent::__construct();
    }

    protected function write(LogRecord $record): void
    {
        $timestamp = (string)($record->datetime->getTimestamp() * 1_000_000_000);
        $payload = [
            'streams' => [[
                'stream' => array_merge($this->labels, [
                    'level' => $record->level->getName(),
                    'channel' => $record->channel,
                ]),
                'values' => [[$timestamp, $record->formatted]],
            ]],
        ];

        $context = stream_context_create(['http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/json',
            'content' => json_encode($payload),
            'timeout' => 1,
        ]]);

        @file_get_contents("{$this->lokiUrl}/loki/api/v1/push", false, $context);
    }
}

// config/logging.php
'loki' => [
    'driver' => 'monolog',
    'handler' => App\Logging\LokiHandler::class,
    'with' => [
        'lokiUrl' => env('LOKI_URL', 'http://loki:3100'),
        'labels' => [
            'app' => 'web-app',
            'env' => env('APP_ENV', 'production'),
        ],
    ],
],

התקנה שלב אחר שלב לאיסוף לוגים של Laravel

  1. צרו את המחלקה version: '3.8' services: loki: image: grafana/loki:3.0.0 ports: - "3100:3100" volumes: - ./loki-config.yml:/etc/loki/local-config.yaml - loki_data:/loki command: -config.file=/etc/loki/local-config.yaml promtail: image: grafana/promtail:3.0.0 volumes: - /var/log:/var/log:ro - /var/lib/docker/containers:/var/lib/docker/containers:ro - ./promtail-config.yml:/etc/promtail/config.yml command: -config.file=/etc/promtail/config.yml grafana: image: grafana/grafana:11.0.0 ports: - "3000:3000" environment: - GF_AUTH_ANONYMOUS_ENABLED=false - GF_SECURITY_ADMIN_PASSWORD=admin_password volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning volumes: loki_data: grafana_data: כפי שמוצג לעיל.
  2. רשמו את הערוץ auth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 9096 common: path_prefix: /loki storage: filesystem: chunks_directory: /loki/chunks rules_directory: /loki/rules replication_factor: 1 ring: kvstore: store: inmemory schema_config: configs: - from: 2024-01-01 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h limits_config: retention_period: 744h # 31 день ingestion_rate_mb: 16 ingestion_burst_size_mb: 32 max_query_length: 721h compactor: working_directory: /loki/compactor retention_enabled: true delete_request_store: filesystem ב-server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /tmp/positions.yaml clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name: nginx static_configs: - targets: [localhost] labels: job: nginx env: production __path__: /var/log/nginx/access.log pipeline_stages: - regex: expression: '^(?P<ip>\S+) - (?P<user>\S+) \[(?P<timestamp>[^\]]+)\] "(?P<method>\S+) (?P<path>\S+) \S+" (?P<status>\d+) (?P<bytes>\d+)' - labels: status: method: - timestamp: source: timestamp format: "02/Jan/2006:15:04:05 -0700" - job_name: laravel static_configs: - targets: [localhost] labels: job: laravel-app env: production __path__: /var/www/app/storage/logs/laravel.log pipeline_stages: - multiline: firstline: '^\[\d{4}-\d{2}-\d{2}' max_wait_time: 3s - regex: expression: '^\[(?P<timestamp>[^\]]+)\] (?P<env>\w+)\.(?P<level>\w+): (?P<message>.*)' - labels: level: env: - timestamp: source: timestamp format: "2006-01-02 15:04:05" - job_name: docker docker_sd_configs: - host: unix:///var/run/docker.sock refresh_interval: 5s relabel_configs: - source_labels: [__meta_docker_container_name] target_label: container - source_labels: [__meta_docker_container_log_stream] target_label: logstream .
  3. הוסיפו את משתנה הסביבה // app/Logging/LokiHandler.php namespace App\Logging; use Monolog\Handler\AbstractProcessingHandler; use Monolog\LogRecord; class LokiHandler extends AbstractProcessingHandler { public function __construct( private string $lokiUrl, private array $labels = [] ) { parent::__construct(); } protected function write(LogRecord $record): void { $timestamp = (string)($record->datetime->getTimestamp() * 1_000_000_000); $payload = [ 'streams' => [[ 'stream' => array_merge($this->labels, [ 'level' => $record->level->getName(), 'channel' => $record->channel, ]), 'values' => [[$timestamp, $record->formatted]], ]], ]; $context = stream_context_create(['http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => json_encode($payload), 'timeout' => 1, ]]); @file_get_contents("{$this->lokiUrl}/loki/api/v1/push", false, $context); } } // config/logging.php 'loki' => [ 'driver' => 'monolog', 'handler' => App\Logging\LokiHandler::class, 'with' => [ 'lokiUrl' => env('LOKI_URL', 'http://loki:3100'), 'labels' => [ 'app' => 'web-app', 'env' => env('APP_ENV', 'production'), ], ], ], ב-LokiHandler.
  4. אמתו את אספקת הלוגים דרך LogQL: loki.
  5. אופציונלית, הגדירו pipeline_stages לניתוח חריגות מרובות שורות.

כיצד לכתוב שאילתות LogQL

LogQL דומה ל-PromQL. תבניות בסיסיות:

# Все ошибки Laravel за последний час
{job="laravel-app", level="error"} |= "Exception"

# Nginx 5xx
{job="nginx"} | json | status >= 500

# Rate ошибок по минутам
rate({job="laravel-app", level="error"}[1m])

# Топ медленных запросов (если request_time в логе)
{job="nginx"} | regexp `request_time=(?P<rt>[0-9.]+)` | unwrap rt | quantile_over_time(0.95, [5m]) by (path)

# Подсчёт ошибок по типу
sum by (level) ( count_over_time({job="laravel-app"}[5m]) )

כיצד להגדיר התראות על עליות שגיאות

צרו כלל התראה דרך provisioning YAML. דוגמת תנאי: config/logging.php. ההתראה מופעלת אם הסף נחצה במשך יותר משתי דקות. מוגדר ב-LOKI_URL. הוסיפו גם התראה על עלייה פתאומית בשגיאות Nginx 5xx.

תהליך ולוחות זמנים

שלב מה אנו עושים משך
ניתוח זיהוי מקורות לוג, תוויות, retention 0.5 יום
עיצוב בחירת Promtail, תצורת Loki, datasource 0.5 יום
יישום פריסת המערכת, הגדרת איסוף, דשבורדים, התראות 0.5 יום
בדיקות אימות אספקה תקינה, פונקציונליות שאילתות 0.5 יום
פריסה מסירת תיעוד, אישורי גישה, הדרכת צוות כלול

סה"כ: 2-3 ימים עבור המערכת המלאה. התמחור מתחיל ב-$500 עבור המערכת הבסיסית (Loki, Promtail, Grafana על Docker; מקור לוג אחד). קבלו ייעוץ לפרויקט שלכם — נעריך ונציע פתרון.

מה כלול

  • מערכת Loki + Promtail + Grafana פרוסה ב-Docker Compose או על bare metal.
  • הגדרת retention, תוויות ו-pipeline_stages עבור המקורות שלכם.
  • handler מותאם אישית ל-Monolog עבור Laravel (או דומה עבור פריימוורקים אחרים).
  • דשבורדים של Grafana המציגים שגיאות, מגמות, נקודות קצה מובילות.
  • כללי התראה על עליות שגיאות, 5xx, שאילתות איטיות.
  • תיעוד תפעול ושחזור.
  • מסירה והדרכת צוות (שעה אחת).
  • אחריות לחודש אחד לפעולה תקינה של המערכת לאחר ההתקנה.

בעיות נפוצות ופתרונותיהן

  • הגדרת retention שגויה — compactor נשכח, לוגים לא נמחקים. תמיד בדקו את .env.
  • חוסר ב-pipeline_stages — תוויות לא מנותחות, סינון קשה. עבור Laravel, השתמשו תמיד בשלב multiline.
  • יותר מדי תוויות — כל תווית חדשה יוצרת אינדקס, ומאטה כתיבה. הגבילו תוויות ל-5-7 לכל מקור.

למדו עוד על לוגים בויקיפדיה. הזמינו את ההתקנה וקבלו ייעוץ לפרויקט שלכם.