备份CatanBuilding瘦身独立工程
This commit is contained in:
270
LocalPackages/PlayFabSDK/Shared/Public/PlayFabLogger.cs
Normal file
270
LocalPackages/PlayFabSDK/Shared/Public/PlayFabLogger.cs
Normal file
@@ -0,0 +1,270 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using PlayFab.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace PlayFab.Public
|
||||
{
|
||||
#if !UNITY_WSA && !UNITY_WP8 && !NETFX_CORE
|
||||
public interface IPlayFabLogger
|
||||
{
|
||||
IPAddress ip { get; set; }
|
||||
int port { get; set; }
|
||||
string url { get; set; }
|
||||
|
||||
// Unity MonoBehaviour callbacks
|
||||
void OnEnable();
|
||||
void OnDisable();
|
||||
void OnDestroy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is some unity-log capturing logic, and threading tools that allow logging to be caught and processed on another thread
|
||||
/// </summary>
|
||||
public abstract class PlayFabLoggerBase : IPlayFabLogger
|
||||
{
|
||||
private static readonly StringBuilder Sb = new StringBuilder();
|
||||
private readonly Queue<string> LogMessageQueue = new Queue<string>();
|
||||
private const int LOG_CACHE_INTERVAL_MS = 10000;
|
||||
|
||||
private Thread _writeLogThread;
|
||||
private readonly object _threadLock = new object();
|
||||
private static readonly TimeSpan _threadKillTimeout = TimeSpan.FromSeconds(60);
|
||||
private DateTime _threadKillTime = DateTime.UtcNow + _threadKillTimeout; // Kill the thread after 1 minute of inactivity
|
||||
private bool _isApplicationPlaying = true;
|
||||
private int _pendingLogsCount;
|
||||
|
||||
public IPAddress ip { get; set; }
|
||||
public int port { get; set; }
|
||||
public string url { get; set; }
|
||||
|
||||
protected PlayFabLoggerBase()
|
||||
{
|
||||
var gatherer = new PlayFabDataGatherer();
|
||||
var message = gatherer.GenerateReport();
|
||||
lock (LogMessageQueue)
|
||||
{
|
||||
LogMessageQueue.Enqueue(message);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnEnable()
|
||||
{
|
||||
PlayFabHttp.instance.StartCoroutine(RegisterLogger()); // Coroutine helper to set up log-callbacks
|
||||
}
|
||||
|
||||
private IEnumerator RegisterLogger()
|
||||
{
|
||||
yield return new WaitForEndOfFrame(); // Effectively just a short wait before activating this registration
|
||||
if (!string.IsNullOrEmpty(PlayFabSettings.LoggerHost))
|
||||
{
|
||||
#if UNITY_5 || UNITY_5_3_OR_NEWER
|
||||
Application.logMessageReceivedThreaded += HandleUnityLog;
|
||||
#else
|
||||
Application.RegisterLogCallback(HandleUnityLog);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnDisable()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PlayFabSettings.LoggerHost))
|
||||
{
|
||||
#if UNITY_5 || UNITY_5_3_OR_NEWER
|
||||
Application.logMessageReceivedThreaded -= HandleUnityLog;
|
||||
#else
|
||||
Application.RegisterLogCallback(null);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnDestroy()
|
||||
{
|
||||
_isApplicationPlaying = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs are cached and written in bursts
|
||||
/// BeginUploadLog is called at the begining of each burst
|
||||
/// </summary>
|
||||
protected abstract void BeginUploadLog();
|
||||
/// <summary>
|
||||
/// Logs are cached and written in bursts
|
||||
/// UploadLog is called for each cached log, between BeginUploadLog and EndUploadLog
|
||||
/// </summary>
|
||||
protected abstract void UploadLog(string message);
|
||||
/// <summary>
|
||||
/// Logs are cached and written in bursts
|
||||
/// EndUploadLog is called at the end of each burst
|
||||
/// </summary>
|
||||
protected abstract void EndUploadLog();
|
||||
|
||||
/// <summary>
|
||||
/// Handler to process Unity logs into our logging system
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="stacktrace"></param>
|
||||
/// <param name="type"></param>
|
||||
private void HandleUnityLog(string message, string stacktrace, LogType type)
|
||||
{
|
||||
if (!PlayFabSettings.EnableRealTimeLogging)
|
||||
return;
|
||||
|
||||
Sb.Length = 0;
|
||||
if (type == LogType.Log || type == LogType.Warning)
|
||||
{
|
||||
Sb.Append(type).Append(": ").Append(message);
|
||||
message = Sb.ToString();
|
||||
lock (LogMessageQueue)
|
||||
{
|
||||
LogMessageQueue.Enqueue(message);
|
||||
}
|
||||
}
|
||||
else if (type == LogType.Error || type == LogType.Exception)
|
||||
{
|
||||
Sb.Append(type).Append(": ").Append(message).Append("\n").Append(stacktrace).Append(StackTraceUtility.ExtractStackTrace());
|
||||
message = Sb.ToString();
|
||||
lock (LogMessageQueue)
|
||||
{
|
||||
LogMessageQueue.Enqueue(message);
|
||||
}
|
||||
}
|
||||
ActivateThreadWorker();
|
||||
}
|
||||
|
||||
private void ActivateThreadWorker()
|
||||
{
|
||||
lock (_threadLock)
|
||||
{
|
||||
if (_writeLogThread != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_writeLogThread = new Thread(WriteLogThreadWorker);
|
||||
_writeLogThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteLogThreadWorker()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool active;
|
||||
lock (_threadLock)
|
||||
{
|
||||
// Kill the thread after 1 minute of inactivity
|
||||
_threadKillTime = DateTime.UtcNow + _threadKillTimeout;
|
||||
}
|
||||
|
||||
var localLogQueue = new Queue<string>();
|
||||
do
|
||||
{
|
||||
lock (LogMessageQueue)
|
||||
{
|
||||
_pendingLogsCount = LogMessageQueue.Count;
|
||||
while (LogMessageQueue.Count > 0) // Transfer the messages to the local queue
|
||||
localLogQueue.Enqueue(LogMessageQueue.Dequeue());
|
||||
}
|
||||
|
||||
BeginUploadLog();
|
||||
while (localLogQueue.Count > 0) // Transfer the messages to the local queue
|
||||
UploadLog(localLogQueue.Dequeue());
|
||||
EndUploadLog();
|
||||
|
||||
#region Expire Thread.
|
||||
// Check if we've been inactive
|
||||
lock (_threadLock)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if (_pendingLogsCount > 0 && _isApplicationPlaying)
|
||||
{
|
||||
// Still active, reset the _threadKillTime
|
||||
_threadKillTime = now + _threadKillTimeout;
|
||||
}
|
||||
// Kill the thread after 1 minute of inactivity
|
||||
active = now <= _threadKillTime;
|
||||
if (!active)
|
||||
{
|
||||
_writeLogThread = null;
|
||||
}
|
||||
// This thread will be stopped, so null this now, inside lock (_threadLock)
|
||||
}
|
||||
#endregion
|
||||
|
||||
Thread.Sleep(LOG_CACHE_INTERVAL_MS);
|
||||
} while (active);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
_writeLogThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
public interface IPlayFabLogger
|
||||
{
|
||||
string ip { get; set; }
|
||||
int port { get; set; }
|
||||
string url { get; set; }
|
||||
|
||||
// Unity MonoBehaviour callbacks
|
||||
void OnEnable();
|
||||
void OnDisable();
|
||||
void OnDestroy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is just a placeholder. WP8 doesn't support direct threading, but instead makes you use the await command.
|
||||
/// </summary>
|
||||
public abstract class PlayFabLoggerBase : IPlayFabLogger
|
||||
{
|
||||
public string ip { get; set; }
|
||||
public int port { get; set; }
|
||||
public string url { get; set; }
|
||||
|
||||
// Unity MonoBehaviour callbacks
|
||||
public void OnEnable() { }
|
||||
public void OnDisable() { }
|
||||
public void OnDestroy() { }
|
||||
|
||||
protected abstract void BeginUploadLog();
|
||||
protected abstract void UploadLog(string message);
|
||||
protected abstract void EndUploadLog();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// This translates the logs up to the PlayFab service via a PlayFab restful API
|
||||
/// TODO: PLAYFAB - attach these to the PlayFab API
|
||||
/// </summary>
|
||||
public class PlayFabLogger : PlayFabLoggerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Logs are cached and written in bursts
|
||||
/// BeginUploadLog is called at the begining of each burst
|
||||
/// </summary>
|
||||
protected override void BeginUploadLog()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Logs are cached and written in bursts
|
||||
/// UploadLog is called for each cached log, between BeginUploadLog and EndUploadLog
|
||||
/// </summary>
|
||||
protected override void UploadLog(string message)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Logs are cached and written in bursts
|
||||
/// EndUploadLog is called at the end of each burst
|
||||
/// </summary>
|
||||
protected override void EndUploadLog()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user