Unity Log Yakalama: Application.logMessageReceived ile Hata Yönetimi
Unity oyun geliştirme sürecinde, kodumuzun ne yaptığını anlamak, hataları tespit etmek ve performans sorunlarını gidermek için log mesajları hayati öneme sahiptir. Unity'nin yerleşik konsolu bu konuda bize çok yardımcı olsa da, bazen daha fazlasına ihtiyaç duyarız: özel log dosyaları oluşturmak, uzaktan hata bildirimleri göndermek veya oyun içi bir hata ayıklama konsolu geliştirmek gibi. İşte tam bu noktada Unity'nin Application.logMessageReceived olayı devreye girer.
Bu makalede, Application.logMessageReceived olayının ne olduğunu, nasıl kullanılacağını, pratik ipuçlarını, yaygın hataları ve performans optimizasyonlarını detaylı bir şekilde inceleyeceğiz. Amacımız, Unity Log Yakalama yeteneklerinizi bir üst seviyeye taşımak ve daha sağlam, hatasız oyunlar geliştirmenize yardımcı olmaktır.
Application.logMessageReceived Nedir?
Application.logMessageReceived, Unity'nin tüm log mesajlarını (Debug.Log, Debug.LogError, Debug.LogWarning, Debug.Assert ve istisnalar) yakalamak için kullandığı statik bir olaydır (event). Bu olaya abone olarak, Unity konsoluna yazılan her mesajı kendi özel fonksiyonunuzda işleyebilirsiniz. Bu sayede, log mesajlarını istediğiniz gibi yönlendirme, filtreleme veya kaydetme esnekliğine sahip olursunuz.
Bu olay, üç parametre ile bir geri çağırım (callback) fonksiyonu bekler:
string logString: Log mesajının kendisi (örneğin,Debug.Log("Merhaba Dünya")içindeki "Merhaba Dünya").string stackTrace: Log mesajının nereden geldiğini gösteren yığın izi (stack trace). Hata ayıklama için çok değerlidir.LogType type: Log mesajının türü (Log,Warning,Error,Assert,Exception).
Bu parametreler sayesinde, log mesajının içeriği, kaynağı ve önem derecesi hakkında tam bilgiye sahip olursunuz.
Application.logMessageReceived Kullanımı
Application.logMessageReceived olayına abone olmak ve aboneliği iptal etmek oldukça basittir. Genellikle, log yakalama işlemini yönetecek tek bir MonoBehaviour betiği (script) oluşturmak iyi bir yaklaşımdır.
Abone Olma ve Aboneliği İptal Etme
Bir betiğin OnEnable() veya Awake() metodunda olaya abone olabilir, OnDisable() veya OnDestroy() metodunda ise aboneliği iptal edebilirsiniz. Aboneliği iptal etmek, özellikle sahne geçişlerinde veya objenin yok edilmesi durumunda kaynak sızıntılarını ve istenmeyen davranışları önlemek için kritik öneme sahiptir.
using UnityEngine;
public class LogYakalaManager : MonoBehaviour
{
void OnEnable()
{
// Log olayına abone ol
Application.logMessageReceived += HandleLog;
Debug.Log("LogYakalaManager aktif: Log olayına abone olundu.");
}
void OnDisable()
{
// Log olayından aboneliği iptal et
Application.logMessageReceived -= HandleLog;
Debug.Log("LogYakalaManager devre dışı: Log olayından abonelik iptal edildi.");
}
void HandleLog(string logString, string stackTrace, LogType type)
{
// Yakalanan log mesajını işleme
string logEntry = $"[{type}] {logString}\n{stackTrace}";
switch (type)
{
case LogType.Error:
case LogType.Exception:
Debug.LogError($"[ÖZEL HATA YAKALANDI] {logEntry}");
// Hata bildirim servisine gönderilebilir
break;
case LogType.Warning:
Debug.LogWarning($"[ÖZEL UYARI YAKALANDI] {logEntry}");
break;
default:
// Diğer log türleri için farklı işlemler
// Debug.Log($"[ÖZEL LOG YAKALANDI] {logEntry}");
break;
}
}
// Örnek loglar oluşturmak için
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
Debug.Log("Bu bir normal log mesajıdır.");
}
if (Input.GetKeyDown(KeyCode.W))
{
Debug.LogWarning("Bu bir uyarı mesajıdır.");
}
if (Input.GetKeyDown(KeyCode.E))
{
Debug.LogError("Bu bir hata mesajıdır!");
}
if (Input.GetKeyDown(KeyCode.X))
{
// Bir istisna fırlatmak
throw new System.Exception("Bu bir test istisnasıdır.");
}
}
}
Yukarıdaki örnekte, HandleLog fonksiyonu her Unity log mesajı oluşturulduğunda çağrılır. İçinde, log türüne göre farklı işlemler yapabiliriz. Bu, Unity Log Yakalama için temel bir yapıdır.
Pratik İpuçları ve Kullanım Senaryoları
1. Kalıcı Log Dosyası Oluşturma
Özellikle mobil cihazlarda veya oyuncuların yaşadığı hataları analiz etmek için, logları cihazda kalıcı bir dosyaya yazmak çok faydalıdır. Bu sayede, oyuncular bir hata raporu gönderdiğinde log dosyasını da ekleyebilirler.
using UnityEngine;
using System.IO;
public class LogDosyasinaYaz : MonoBehaviour
{
private string logFilePath;
void OnEnable()
{
logFilePath = Path.Combine(Application.persistentDataPath, "game_logs.txt");
Application.logMessageReceived += HandleLogToFile;
Debug.Log($"Log dosyası yolu: {logFilePath}");
}
void OnDisable()
{
Application.logMessageReceived -= HandleLogToFile;
}
void HandleLogToFile(string logString, string stackTrace, LogType type)
{
string logEntry = $"[{System.DateTime.Now}] [{type}] {logString}\n{stackTrace}\n";
try
{
File.AppendAllText(logFilePath, logEntry);
}
catch (System.Exception e)
{
Debug.LogError($"Log dosyasına yazarken hata oluştu: {e.Message}");
}
}
}
Application.persistentDataPath, cihazlar arasında kalıcı verileri depolamak için güvenli bir yoldur. Bu yöntemle Unity Log Yakalama ve kaydetme işlemini kolayca yapabilirsiniz.
2. Uzaktan Hata Bildirimi ve Analiz
Ciddi hataları veya istisnaları anında bir sunucuya göndermek, oyununuzun stabilitesini izlemek için vazgeçilmezdir. Bu sayede, oyuncular bir hata yaşadığında otomatik olarak bildirim alabilir ve sorunu hızla çözebilirsiniz. Firebase Crashlytics, Sentry veya kendi özel web servisiniz gibi araçlarla entegrasyon sağlayabilirsiniz.
using UnityEngine;
public class UzaktanHataBildirici : MonoBehaviour
{
void OnEnable()
{
Application.logMessageReceived += SendRemoteError;
}
void OnDisable()
{
Application.logMessageReceived -= SendRemoteError;
}
void SendRemoteError(string logString, string stackTrace, LogType type)
{
if (type == LogType.Error || type == LogType.Exception || type == LogType.Assert)
{
// Burada bir web servisine veya üçüncü parti bir hata bildirim aracına
// (örn. Sentry, Firebase Crashlytics) hata bilgilerini gönderebilirsiniz.
string errorMessage = $"Hata: {logString}\nStack: {stackTrace}\nTür: {type}";
Debug.LogWarning($"[UZAKTAN BİLDİRİM] Hata gönderiliyor: {errorMessage.Substring(0, Mathf.Min(errorMessage.Length, 200))}...");
// Örneğin:
// WebClient.Post("https://your-error-reporting-service.com/api/report", errorMessage);
}
}
}
Bu, Unity Log Yakalama ile proaktif hata yönetimi için güçlü bir yöntemdir.
3. Oyun İçi Hata Ayıklama Konsolu
Geliştirme sırasında veya test kullanıcıları için, oyun içinde çalışan basit bir konsol, anlık geri bildirim almak için harikadır. Application.logMessageReceived ile yakalanan logları bir UI Text elemanına ekleyerek basit bir konsol oluşturabilirsiniz.
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class InGameConsole : MonoBehaviour
{
public Text consoleText;
public int maxLogEntries = 100; // Konsolda gösterilecek maksimum log sayısı
private List<string> logBuffer = new List<string>();
void OnEnable()
{
Application.logMessageReceived += HandleInGameLog;
}
void OnDisable()
{
Application.logMessageReceived -= HandleInGameLog;
}
void HandleInGameLog(string logString, string stackTrace, LogType type)
{
string formattedLog = $"[{type}] {logString}";
logBuffer.Add(formattedLog);
// Buffer boyutunu kontrol et
if (logBuffer.Count > maxLogEntries)
{
logBuffer.RemoveAt(0);
}
UpdateConsoleUI();
}
void UpdateConsoleUI()
{
if (consoleText != null)
{
consoleText.text = string.Join("\n", logBuffer);
}
}
}
Bu betiği bir UI Text bileşenine sahip bir GameObject'e ekleyerek hızlıca bir oyun içi konsol oluşturabilirsiniz. Bu sayede, Unity Log Yakalama olayını görselleştirebilirsiniz.
Yaygın Hatalar ve Çözümleri
1. Aboneliği İptal Etmeyi Unutmak
Hata: OnDisable veya OnDestroy içinde Application.logMessageReceived -= MyLogCallback; yapmayı unutmak, sahne geçişlerinde veya objeler yok edildiğinde birden fazla kez çağrılan callback'lere veya null referans hatalarına yol açabilir.
Çözüm: Her zaman OnEnable/Awake içinde abone olun ve OnDisable/OnDestroy içinde aboneliği iptal edin. Bu, temiz bir kaynak yönetimi sağlar.
2. Callback İçinde Ağırlıklı İşlemler Yapmak
Hata: HandleLog gibi callback fonksiyonları içinde dosya yazma, ağ isteği gönderme veya karmaşık hesaplamalar gibi performansı etkileyen işlemler yapmak, oyunun takılmasına veya kare hızının düşmesine neden olabilir.
Çözüm: Ağırlıklı işlemleri başka bir iş parçacığına (thread) aktarın veya asenkron (async) işlemler kullanın. Dosya yazma gibi işlemleri belirli aralıklarla veya toplu olarak (batch) yapmayı düşünebilirsiniz.
3. Callback İçinde Tekrar Log Oluşturmak
Hata: Log yakalama callback'inin içinde kontrolsüz bir şekilde Debug.Log veya Debug.LogError kullanmak, sonsuz bir log döngüsüne neden olabilir. Örneğin, bir hata log'unu yakalayıp sonra o hatayı tekrar loglamak.
Çözüm: Eğer callback içinde loglama yapmanız gerekiyorsa, bunu dikkatli yapın ve bir koşul (flag) kullanarak döngüyü önleyin. Örneğin, özel bir loglama fonksiyonu kullanabilir veya sadece belirli türdeki logları kendi iç loglama sisteminize gönderebilirsiniz.
4. Editor ve Build Ortamı Farklılıkları
Hata: Editörde sorunsuz çalışan bir log yakalama sisteminin, derlenmiş (build) bir oyunda farklı davranması.
Çözüm: Özellikle dosya yolları (Application.dataPath vs. Application.persistentDataPath) ve güvenlik izinleri build ortamında farklılık gösterebilir. Uygulamanızı farklı platformlarda test ederek bu tür sorunları önceden tespit edin. Ayrıca, #if UNITY_EDITOR gibi ön işlemci direktiflerini kullanarak editöre özel davranışlar tanımlayabilirsiniz.
Performans ve Optimizasyon Notları
- Log Mesajı Boyutu:
logStringvestackTraceparametreleri büyük dizeler (string) olabilir. Eğer bunları kullanmıyorsanız, gereksiz string işlemleri yapmaktan kaçının. - Dosya I/O ve Ağ İşlemleri: Daha önce de belirtildiği gibi, bu tür işlemler ana iş parçacığını bloke edebilir. Asenkron API'ler kullanın veya logları bir tamponda (buffer) toplayıp belirli aralıklarla toplu olarak yazın/gönderin.
- Sık Loglama: Her karede veya çok sık loglama yapmak,
Application.logMessageReceivedolayının çağrılma sıklığını artırır ve bu da küçük bir performans yükü oluşturabilir. Yalnızca kritik bilgileri loglamaya özen gösterin. - Derleme Ayarları: Production build'lerinde
Debug.Logçağrılarının kaldırılması için derleme ayarlarını kontrol edin. Unity'de 'Strip Engine Code' ve 'Scripting Define Symbols' (örn:UNITY_ASSERTIONS) gibi ayarlarla loglama davranışını değiştirebilirsiniz.
Unity Log Yakalama sisteminizi optimize etmek, özellikle performansın kritik olduğu mobil ve yüksek performanslı oyunlarda çok önemlidir.
Sonuç
Application.logMessageReceived, Unity geliştiricileri için son derece güçlü ve esnek bir araçtır. Bu olay sayesinde, oyununuzun loglama ve hata ayıklama süreçlerini tamamen kendi ihtiyaçlarınıza göre özelleştirebilirsiniz. İster uzaktan hata bildirimleri, ister özel log dosyaları, ister oyun içi bir konsol olsun, bu API size geniş imkanlar sunar.
Bu makalede anlatılan teknikleri kullanarak, Unity Log Yakalama konusunda uzmanlaşabilir ve oyunlarınızın kalitesini ve kararlılığını önemli ölçüde artırabilirsiniz. Doğru bir hata yönetimi stratejisi, geliştirme sürecinizi hızlandırır ve oyuncularınıza daha iyi bir deneyim sunar.
🧠 Ders Sonu Değerlendirme Testi
Dersi tamamladıktan sonra bilgilerinizi test edin ve ekstra puanlar kazanın.
Yorumlar (0)
İlk yorumu siz yapın!