מערכת רישום מרחוק לניפוי באגים באפליקציות מובייל

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

פיתוח ותמיכה בכל סוגי היישומים הניידים:

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
מערכת רישום מרחוק לניפוי באגים באפליקציות מובייל
מורכב
~3-5 ימים

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

שאלות נפוצות

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

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

מערכת רישום מרחוק לניפוי באגים באפליקציות מובייל

למה רישום מרחוק הוא קריטי

תארו לעצמכם: באג שמופיע רק במכשיר של משתמש מסוים בסביבת הייצור. Crashlytics מראה קריסה, אבל ללא הקשר — ללא שלבים, ללא מצב. ללא רישום מרחוק, אתם מבלים בממוצע 3–5 ימים בניסיון לשחזר, ו-80% מהבאגים נשארים לא מזוהים. רישום מרחוק שולח לוגים מפורטים לשרת בזמן אמת או לפי דרישה, ומקצר את זמן החיפוש ל-2–3 שעות.

היה לנו פעם מקרה שבו אפליקציה קרסה ב-iPad mini 5 בעת סיבוב המסך, עקב תנאי מרוץ ב-UICollectionView. ללא רישום מרחוק, היינו מבלים שבועות בניחושים. במקום זאת, הפעלנו לוגים מפורטים לכמה משתמשים, מצאנו את הבעיה ב-callback של הכיוון תוך שעה, ושחררנו תיקון חם.

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

מצב פסיבי (ברירת מחדל): לוגים נכתבים למאגר טבעתי מקומי. שום דבר לא נשלח לשרת.

מצב פעיל: מופעל על ידי אירוע — קריסה, מזהה משתמש ספציפי, דגל מ-Remote Config. המאגר נשלח לשרת.

סשן ניפוי למשתמש ספציפי: עם בקשת תמיכה, רישום מפורט מופעל עבור userId מסוים דרך Firebase Remote Config או דגל תכונה.

השוואת מצבים:

מצב מתי משתמשים נפח נתונים נדרש שרת
פסיבי ברירת מחדל מינימלי (רק מדדים) לא
פעיל בקריסות או תקלות בינוני (מאגר של N לוגים אחרונים) כן
סשן ניפוי למשתמש ספציפי גבוה (לוגים מלאים של הסשן) כן

Firebase Remote Config לשליטה דינמית ברישום

// Android: проверка флагов логирования при старте
val remoteConfig = Firebase.remoteConfig
remoteConfig.fetchAndActivate().addOnCompleteListener {
    val logLevel = remoteConfig.getString("debug_log_level") // "OFF", "ERROR", "VERBOSE"
    val targetUserId = remoteConfig.getString("debug_user_id") // пустая строка = все
    RemoteLogger.configure(
        level = LogLevel.fromString(logLevel),
        targetUserId = targetUserId
    )
}

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

הובלת לוגים

העלאה בקבוצות — מערכת איסוף לוגים מרחוק

אל תשלחו כל קריאת לוג כבקשת HTTP נפרדת: צברו בתור ושלחו בקבוצות של 100 רשומות.

class RemoteLogTransport(
    private val apiService: LogApiService,
    private val batchSize: Int = 100,
    private val flushIntervalMs: Long = 30_000
) {
    private val pendingLogs = ConcurrentLinkedQueue<LogEntry>()

    fun enqueue(entry: LogEntry) {
        pendingLogs.add(entry)
        if (pendingLogs.size >= batchSize) {
            flush()
        }
    }

    private fun flush() {
        val batch = mutableListOf<LogEntry>()
        repeat(batchSize) {
            pendingLogs.poll()?.let { batch.add(it) } ?: return@repeat
        }
        if (batch.isNotEmpty()) {
            scope.launch {
                runCatching {
                    apiService.sendLogs(
                        LogBatch(
                            sessionId = sessionId,
                            deviceInfo = deviceInfo,
                            logs = batch
                        )
                    )
                }
            }
        }
    }
}

WorkManager להעברה מובטחת כשהרשת חוזרת:

val logUploadWork = OneTimeWorkRequestBuilder<LogUploadWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
    .build()
WorkManager.getInstance(context).enqueue(logUploadWork)

iOS — שילוב OSLog עם הובלה מרחוק

// OSLog для системного логирования + remote transport actor RemoteLogger {
    private var buffer: [LogEntry] = []
    private var isRemoteEnabled = false
    private let transport: LogTransport

    func log(_ message: String, level: LogLevel) async {
        let entry = LogEntry(timestamp: Date(), level: level, message: message)
        buffer.append(entry)
        if buffer.count > 500 {
            buffer.removeFirst()
        }
        if isRemoteEnabled {
            await transport.enqueue(entry)
        }
    }

    func enableRemote(for userId: String) async {
        isRemoteEnabled = true
        // Отправляем буфер накопленных логов
        let bufferedLogs = buffer
        await transport.sendBatch(bufferedLogs)
    }
}

// Android: проверка флагов логирования при старте val remoteConfig = Firebase.remoteConfig remoteConfig.fetchAndActivate().addOnCompleteListener { val logLevel = remoteConfig.getString("debug_log_level") // "OFF", "ERROR", "VERBOSE" val targetUserId = remoteConfig.getString("debug_user_id") // пустая строка = все RemoteLogger.configure( level = LogLevel.fromString(logLevel), targetUserId = targetUserId ) } מבטיח בטיחות תהליכונים ללא נעילה מפורשת — הגישה הנכונה ב-Swift 5.5+. לפרטים נוספים על OSLog, עיינו בתיעוד של Apple.

צד שרת לאחסון לוגים

פתרונות סטנדרטיים:

אחסון מתאים ל הערות
Elasticsearch + Kibana חיפוש טקסט מלא בלוגים עתיר משאבים אך חזק
Loki + Grafana לוגים מובנים, משאבים נמוכים זול יותר מ-Elastic
Datadog SaaS, ללא תשתית יקר בקנה מידה גדול
Sentry כבר בשימוש לקריסות Breadcrumbs + לוגים מרחוק במקום אחד

Sentry Breadcrumbs — תכונה שלעתים קרובות לא מעריכים. Breadcrumbs מותאמים אישית מחוברים לכל אירוע (קריסה או שגיאה) ומראים מה קרה לפני הבעיה:

SentrySDK.configureScope { scope in
    scope.addBreadcrumb(Breadcrumb(
        level: .info,
        category: "navigation",
        message: "User opened PaymentScreen",
        data: ["orderId": orderId]
    ))
}

הערה: כאשר מתרחשת קריסה, Sentry מציג את 100 ה-breadcrumbs האחרונים — למעשה לוג מוכן של נתיב המשתמש.

אבטחה ועמידה ב-GDPR

לוגים מרחוק עשויים להכיל מידע אישי. אנו מבטיחים:

  • לוגים אינם מכילים שמות מלאים, אימיילים, מספרי כרטיסים — רק class RemoteLogTransport( private val apiService: LogApiService, private val batchSize: Int = 100, private val flushIntervalMs: Long = 30_000 ) { private val pendingLogs = ConcurrentLinkedQueue<LogEntry>() fun enqueue(entry: LogEntry) { pendingLogs.add(entry) if (pendingLogs.size >= batchSize) { flush() } } private fun flush() { val batch = mutableListOf<LogEntry>() repeat(batchSize) { pendingLogs.poll()?.let { batch.add(it) } ?: return@repeat } if (batch.isNotEmpty()) { scope.launch { runCatching { apiService.sendLogs(LogBatch( sessionId = sessionId, deviceInfo = deviceInfo, logs = batch )) } } } } } לצורך קורלציה.
  • נתוני לוג נשמרים לא יותר מ-30 יום (TTL ניתן להגדרה באחסון).
  • משתמשים יכולים לבטל איסוף אבחוני בהגדרות האפליקציה — הדגל נשמר ב-val logUploadWork = OneTimeWorkRequestBuilder<LogUploadWorker>() .setConstraints(Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build()) .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES) .build() WorkManager.getInstance(context).enqueue(logUploadWork) / // OSLog для системного логирования + remote transport actor RemoteLogger { private var buffer: [LogEntry] = [] private var isRemoteEnabled = false private let transport: LogTransport func log(_ message: String, level: LogLevel) async { let entry = LogEntry(timestamp: Date(), level: level, message: message) buffer.append(entry) if buffer.count > 500 { buffer.removeFirst() } if isRemoteEnabled { await transport.enqueue(entry) } } func enableRemote(for userId: String) async { isRemoteEnabled = true // Отправляем буфер накопленных логов let bufferedLogs = buffer await transport.sendBatch(bufferedLogs) } } ונבדק לפני כל העלאה.
  • מדיניות הפרטיות מתארת את איסוף הנתונים האבחוניים.

ניפוי תפעולי ללא שחרור

תרחיש: קריסות בייצור עבור 0.3% מהמשתמשים במכשיר ספציפי. רצף ללא רישום מרחוק:

  1. בקשו מהמשתמש להפעיל מצב מפתחים — לא סביר.
  2. חכו לשחזור — לא ידוע מתי.

עם רישום מרחוק:

  1. הפעילו מצב מפורט דרך Remote Config עבור userId ספציפי.
  2. המשתמש משחזר את הבעיה בסשן הבא.
  3. תוך 30 דקות, לוגים מפורטים של הסשן נראים ב-Kibana/Grafana.
  4. אתרו את הבעיה, שחררו תיקון חם, כבו מצב מפורט.

מה כלול

  • תיעוד ארכיטקטוני עם סכמת העברת לוגים.
  • SDK ל-iOS (Swift) ול-Android (Kotlin) עם תמיכה ב-OSLog ו-WorkManager.
  • אינטגרציה עם Firebase Remote Config ו-Sentry breadcrumbs.
  • אחסון צד שרת (Elasticsearch או Loki) עם דשבורדים מוגדרים.
  • מדיניות אבטחה ו-TTL בהתאם ל-GDPR.
  • הדרכת צוות על המערכת ותמיכה טכנית במהלך ההשקה.

תהליך

ניתוח ועיצוב

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

יישום ב-iOS וב-Android

אנו כותבים SDK ל-iOS (Swift, עם OSLog) ול-Android (Kotlin, עם WorkManager). מוסיפים Remote Config לשליטה דינמית. משלבים Sentry breadcrumbs.

בדיקות והשקה

אנו מבצעים בדיקות עומס: מוודאים שהאפליקציה לא מאטה ב-1000 לוגים בשנייה. פורסים את צד השרת, מגדירים דשבורדים. מאמנים את הצוות.

הערכות זמנים

מערכת רישום מרחוק בסיסית עם העלאה בקבוצות, שליטה ב-Remote Config ואינטגרציה עם Sentry — 1–2 שבועות. תשתית מלאה עם Elasticsearch, דשבורדים של Kibana, מנגנוני GDPR ו-iOS+Android — 3–4 שבועות. העלות מחושבת באופן אישי לאחר ביקורת של התשתית הנוכחית.

איך להפחית עלויות ניפוי?

רישום מרחוק חוסך עד 50% מהזמן המושקע באיתור ותיקון באגים. במקום להזמין מכשירי בדיקה ולשחזר בעיות בעיוורון, אתם רואים מיד לוגים ממשתמשים אמיתיים. זה מפחית עלויות QA ב-40% ומאיץ שחרורים ב-30%. לצוות שלנו יש ניסיון של 10+ שנים בפיתוח מובייל והוא יישם רישום מרחוק בלמעלה מ-200 פרויקטים. הזמינו אינטגרציה של רישום מרחוק לשיפור איכות האפליקציה. קבלו ייעוץ — המהנדסים שלנו ינתחו את התשתית שלכם ויציעו פתרון אופטימלי. צרו קשר כדי להתחיל לחסוך זמן ניפוי.