ניתוח הבריאות והביצועים של האתר רץ היום מחוץ לליבה, אצל אולג AI המאוחסן (https://oleg.wizzo.market). בליבה נשאר מה שרק השרת של האתר יכול לעשות: לאסוף נתונים, למדוד תעבורה אמיתית, ולהריץ פעולה מוגנת אחת (בניית אינדקס). בדף הזה: מה נאסף ובאילו ספים, איך המנוע החיצוני קורא את זה, ומה הכלים החיים שנשארו בפאנל (server_load, error_log, sqllog).
חיבור האתר לאולג מנוהל ב-Wizzo Market. ללא מפתחות אולג באתר (PARAM oleg_ready), כל הפעולות של המנוע מחזירות unauthorized. ראו סקירת Wizzo Market ו-קטלוג השירותים.
SystemHealth: האוסף#
libraries/SystemHealth.php הוא collector בלבד: הוא לא שומר, לא מנתח ולא מציג. שתי מתודות ציבוריות עיקריות, ועוד עוזר אחד.
| מתודה | ערך החזרה | הערה |
|---|---|---|
SystemHealth::collect(): array | רשימת ממצאים {source, severity, title, details, count, ref} | severity הוא low, med או high. אוסף את כל המקורות שבטבלה למטה |
SystemHealth::vitals_now(): array | {load_per_core, cores, mem_used_pct, db_threads, db_max, db_conn_pct} | מספרים גולמיים, ללא ספים. כל שדה null כשהמקור לא זמין, והקריאה לא זורקת חריגה |
SystemHealth::time_ago(string $datetime): string | "לפני שעתיים", "לפני יום" וכו' | בעברית, עם צורות נקבה וזוגי תקינות |
$findings = SystemHealth::collect();
foreach ($findings as $f)
{
if ($f["severity"] === "high")
{
error_log($f["source"] . ": " . $f["title"]);
}
}
מקורות הנתונים והספים#
source | מה נבדק | ספים (med / high) |
|---|---|---|
error_log | שגיאות PHP מהשעה האחרונה. קורא את סוף הקובץ בחתיכות, מקבץ לפי חתימה ומזהה "הצפה" של חתימה אחת | חזרה של 5 פעמים בשעה היא "חוזרת". הצפה: לפחות 50 רשומות, וחתימה אחת מעל 60% מהשעה |
error_log_size | גודל קובץ ה-error_log | 128MB / 1GB |
heartbeat | האם ה-cron הראשי רץ (cron_runner_heartbeat ב-CRM_params) | ישן מ-300 שניות |
cron_log | משימות cron שנכשלו בשעה האחרונה (CRM_cron_logs, status='error') | לפי כשלים |
stuck_task | משימות עם next_run שעבר לפני יותר מ-10 דקות (CRM_cron_tasks) | לפי איחור |
server_resources | דיסק, inodes, load לליבה (ממוצע 15 דקות), זיכרון, swap | דיסק 80% / 90% או פחות מ-1GB פנוי. inodes 85% / 95%. load 1.0 / 1.5 לליבה. זיכרון 92% / 97%. swap 80% |
db_engine | חיבורי DB מול max_connections, והתאמת ה-buffer pool | חיבורים 70% / 85%. פגיעות buffer pool מתחת ל-95% / 85% |
ssl_expiry | תוקף תעודת ה-SSL של הדומיין של האתר | 21 / 7 ימים |
disposable_space | תיקיות זבל שגדלו (למשל .trash) | 1GB / 5GB. תקציב סריקה של 20 שניות בסך הכול, 8 לכל תיקייה |
הספים הם קבועים בראש הקובץ (DISK_WARN_PCT, ERRLOG_WARN_BYTES ועוד), בכוונה שמרניים: התראה שחוזרת כל שעה ואף אחד לא פועל לפיה מלמדת מנהלים להתעלם מכל הדוח.
collect() קורא את ה-error_log מהסוף ועוצר בגבול השעה, ולא דרך ADMINMODULE_error_log::get_error(), כי זה האחרון טוען את הקובץ כולו לזיכרון וקורס בלוגים גדולים, וזה בדיוק המצב שהבדיקה אמורה לתפוס.perf_runner: הדלת של אולג אל האתר#
system/perf_runner הוא controller של הליבה (נתיב system/ מנותב ישירות, בלי שורה ב-CRM_modules), מליבה 5.0.83 ומעלה. המנוע החיצוני קורא לו, והוא מעביר ל-OlegAgent (libraries/OlegAgent.php) את העבודה. הוא זהה בדפוסו ל-seo_runner (ראו חבילת ה-SEO).
אימות וגוף הבקשה#
- פעולות המנוע דורשות
Authorization: Bearer <api_key>:<secret_key>של שירות אולג, שנבדק ב-OlegHosted::request_ok()עםhash_equals. כשה-header נופל בדרך (אירוח cgi-fcgi),WIZZO_KEY::incoming()קורא גם את הערוצים החלופיים. - הגוף הוא JSON רגיל, או מעטפת gzip:
{"z":"<base64 של gzip של ה-JSON>"}. המעטפת קיימת כי שתי פעולות נושאות SQL בגוף (deep_diveו-apply_index) ו-WAF עלול לחסום אותן עוד לפני ש-PHP רואה אותן. כשהמעטפת בשימוש, התשובה כוללת"z": 1. - כל פעולה מתקבלת גם כ-
?do=<action>, למקרה שהשרת מנתבsystem/<controller>/<action>ל-index()ומאבד את הסגמנט האחרון. - כל תשובה היא
{"ok":true,...}או{"ok":false,"error":"..."}. לא מאומת:401 unauthorized. פעולות האתר:403 admin or engine only.
הפעולות#
| פעולה | גוף הבקשה | מי רשאי | מה היא עושה |
|---|---|---|---|
discovery | מנוע | מי האתר ומה הוא יודע לעשות | |
capture_start | minutes (ברירת מחדל 5), max_bytes | מנוע | פותחת חלון לכידת תעבורה אמיתית. הזרם הגולמי לא יוצא מהאתר |
capture_status | session_id | מנוע | מצב הלכידה |
capture_collect | session_id, tuning | מנוע | אוספת סיכום של הלכידה |
capture_abort | session_id | מנוע | מבטלת לכידה |
deep_dive | top_queries | מנוע | EXPLAIN וסכמה לשאילתות הכבדות |
health_collect | מנוע | את התוצאה של SystemHealth::collect(), בלי מגבלת זמן | |
vitals | מנוע | מצב המכונה, hazards, ואם לכידה פעילה כרגע | |
apply_index | sql, run | מנוע | בניית אינדקס מוגנת, ראו למטה |
code_bundle | locs, tables | מנוע | קוד לקריאה בלבד סביב נקודות הקריאה שנלכדו |
todo_meta, ticket, ticket_close | subject, details_html, project_id או id, comment_html | מנוע | עבודה עם ה-TODO של האתר |
export | מנוע | ההיסטוריה המקומית, להעברה חד-פעמית | |
register, migrate, status, panel_token | מנהל מחובר או מנוע | חיבור האתר למנוע, מעבר מההיסטוריה הישנה, מצב, ואסימון לפאנל המוטמע |
apply_index: האינדקס היחיד שהמנוע בונה#
OlegAgent::apply_index($sql, $run = false) מקבל רק פקודת CREATE INDEX או ALTER TABLE ... ADD INDEX פשוטה; כל דבר אחר נדחה עם הודעה להריץ ידנית. זה תהליך בשני שלבים:
runריק: בדיקה בלבד. מוחזרים גודל הטבלה, מנוע האחסון, וסימון אם הבנייה אונליין (mode: "info").runמלא: ב-InnoDB נבנהALGORITHM=INPLACE, LOCK=NONE. בטבלת MyISAM או Aria אין בנייה אונליין, ולכן היא מותרת רק לטבלה קטנה (עד 300,000 שורות ו-256MB). טבלה גדולה כזו נדחית עם פקודה להרצה ידנית בשעת שפל.
אם האינדקס כבר קיים, התשובה היא ok עם already: 1.
apply_index משנה את מבנה בסיס הנתונים של האתר. הוא נגיש רק למי שמחזיק במפתחות אולג של האתר. אל תתנו את המפתחות (api_key:secret_key) לשום צד שלישי. ראו מודל האבטחה.צורת התשובות שנשארו בליבה#
בנוסף ל-perf_runner, שני controllers ישנים נשארו כ"מעטפת" ריקה בכוונה, כדי ששורות cron ישנות באתרים לא יתמלאו באדום:
| כתובת cron | מה היא עונה |
|---|---|
system/system_health/run | SKIP: הבדיקה השעתית עברה לאולג. אפשר למחוק את המשימה |
system/perf_advisor/run | SKIP: המדידה המתוזמנת עברה לאולג והתזמון נקבע שם. אפשר למחוק את המשימה |
ראו Cron לניהול המשימות.
הכלים החיים בפאנל#
שלושה כלי ניטור נשארו בפאנל. כולם מופיעים תחת כלים למפתחים ב-{admin}.
server_load: עומסי השרת#
ADMINMODULE_server_load הוא דשבורד של משאבי השרת בזמן אמת, ומתרענן כל 2 שניות. {admin}/server_load/stats מחזיר JSON עם:
| מפתח | תוכן |
|---|---|
load | load average ל-1, 5 ו-15 דקות, ביחס לליבות |
cpu | ניצול רגעי (דגימה של /proc/stat שנמשכת כ-0.2 שניות) |
mem, swap, disk | זיכרון, swap ודיסק |
uptime, hostname | זמן פעולה ושם המארח |
php | גרסה, memory_limit, מצב opcache |
db | חיבורים מול max_connections, buffer pool, שאילתות איטיות, QPS, המתנות על נעילות שורה |
כל מדד נקרא בזהירות: במקום שאין /proc (Windows, אירוח מוגבל) הכרטיס מציג "לא זמין" ואינו שובר את העמוד.
| פעולה | מה היא עושה |
|---|---|
index() | הדשבורד |
stats() | JSON של המדדים הנוכחיים |
queries() | 40 השורות האחרונות מ-sqllog.txt, הכי חדשה ראשונה, כל שאילתה מקוצרת ל-260 תווים |
toggle_log() | מדליק ומכבה את הפרמטר log_sql. דורש ADMIN::is_admin() |
sqllog ולוג SQL#
כש-PARAMS log_sql הוא "1", DB::log_sql_to_file() כותבת כל שאילתה (עם url, date, source שהוא admin או site, ו-backtrace) כשורת JSON לקובץ sqllog.txt בשורש האתר. הקובץ מצמצם את עצמו: מעל 5MB נשמר רק השליש האחרון. הפאנל {admin}/sqllog מציג את הלוג בעמודים של 100 שורות, עם סינון filter_source=admin|site, ומאפשר להפעיל, לכבות ולרוקן.
sqllog.txt יושב בשורש האתר הציבורי ומכיל את כל השאילתות עם הערכים שלהן. הפעילו אותו רק לדיבוג קצר, כבו אותו מיד, ורוקנו את הקובץ. בנוסף, כל הפעלה מוסיפה backtrace לכל שאילתה, עלות אמיתית על כל בקשה. ראו דיבוג מסד נתונים.error_log#
ADMINMODULE_error_log קורא את הקובץ שמוגדר ב-ini_get('error_log') (עד 10MB האחרונים), מקבץ לפי סוג, קובץ ושורה, ומציג stack traces מקופלים. סינון ומיון נעשים בפרמטרי GET: sort_by, sort_dir, filter_type, filter_text, filter_file, filter_from_date.
| מתודה | חתימה | הערה |
|---|---|---|
index() | העמוד. ?clear_log=1 מרוקן את הקובץ | |
get_error | get_error($sortBy = 'last_date', $sortDir = 'desc', $filterType = '', $filterText = '', $filterFile = '', $filterFromDate = '') | מחזיר את הרשומות המקובצות. ציבורית, וקוד אחר משתמש בה |
server_load ו-error_log מסומנים skip_permission_check = true, כלומר פתוחים לכל מנהל מחובר ולא רק למפתחים. מחיקת הלוג נעשית בבקשת GET בלי אסימון CSRF, והעמוד חושף נתיבי שרת ו-stack traces. כשאתם בונים פאנל חדש אל תעתיקו את הדפוס הזה. ראו הרשאות מנהלים.ניקויים מתוזמנים#
שני controllers קטנים מנקים בלי מעורבות אדם, ומופעלים כמשימות cron בתיקיית "מערכת":
| כתובת | זמן מומלץ | מה היא עושה | פלט |
|---|---|---|---|
system/cache_cleanup/run?type=all|pages|items | 0 4 * * * | cache_engine::cleanup_expired($type, false) מוחק קבצי מטמון שפגו (עם גרייס של 48 שעות, cache_engine::$gc_grace_hours) | OK type=… deleted=N freed_mb=X |
admin_session_cleanup/run | 0 3 * * * | ADMIN::cleanup_expired_sessions() מוחק סשנים שפגו מ-CRM_adminPanel_sessions, ונסיונות כניסה כושלים בני יותר מ-24 שעות מ-CRM_adminPanel_admins_bad_attempts | OK sessions_cleaned=… attempts_cleaned=… |
הספירה ב-admin_session_cleanup אינה אמינה: attempts_cleaned תמיד 0, ו-sessions_cleaned נקרא אחרי שאילתה אחרת. הניקוי עצמו עובד, אבל אל תסתמכו על המספרים בלוג.
ראו גם#
- Cron, ניהול המשימות ו-heartbeat
- אבחון קוד ו-lint
- דיבוג מסד נתונים
- מערכת המטמון ו-ממשק המטמון
- סקירת Wizzo Market