using System; using System.Text; using UnityEngine; namespace Unity.Services.Authentication.Utilities { /// /// LogLevel is used to control the logs that are written to Unity for debugging. /// public enum LogLevel { /// /// Disable all logs from Authentication SDK. /// Off = 0, /// /// Show errors in Authentication SDK. /// ErrorsOnly = 1, /// /// Show warnings and errors in Authentication SDK. /// WarningsAndErrors = 2, /// /// Show all logs in Authentication SDK. /// Verbose = 3 } interface ILogger { void Info(string message); void Warning(string message); void Error(string message); void Info(string format, params object[] args); void Warning(string format, params object[] args); void Error(string format, params object[] args); } class Logger : ILogger { readonly string m_Prefix; delegate void LogMethod(object message); public LogLevel LogLevel { get; private set; } public Logger(string prefix, LogLevel logLevel = LogLevel.ErrorsOnly) { m_Prefix = prefix; LogLevel = logLevel; } public void SetLogLevel(LogLevel level) { LogLevel = level; } public void Info(string message) { if (LogLevel >= LogLevel.Verbose) { Log(Debug.Log, message); } } public void Info(string format, params object[] args) { if (LogLevel >= LogLevel.Verbose) { Log(Debug.Log, format, args); } } public void Warning(string message) { if (LogLevel >= LogLevel.WarningsAndErrors) { Log(Debug.LogWarning, message); } } public void Warning(string format, params object[] args) { if (LogLevel >= LogLevel.WarningsAndErrors) { Log(Debug.LogWarning, format, args); } } public void Error(string message) { if (LogLevel >= LogLevel.ErrorsOnly) { Log(Debug.LogError, message); } } public void Error(string format, params object[] args) { if (LogLevel >= LogLevel.ErrorsOnly) { Log(Debug.LogError, format, args); } } void Log(LogMethod log, string format, params object[] args) { try { var sb = new StringBuilder(); sb.Append(m_Prefix); sb.Append(" "); if (args?.Length == 0) { // There is no args, so it's supposed to be a raw string to log. // Don't do AppendFormat since it will throw FormatException if the format string contains // placeholder character {}. sb.Append(format); } else { sb.AppendFormat(format, args); } log(sb.ToString()); } catch (Exception e) { try { // It's possible to get FormatException if the format string doesn't match args. // Fallback to a non-formatted string var sb = new StringBuilder(); sb.Append(m_Prefix); sb.Append(" ["); sb.Append(e.Message); sb.Append("] "); sb.Append(format); foreach (var arg in args) { sb.Append(" "); sb.Append(arg); } log(sb.ToString()); } catch { // Ignore the exception if it fails again, best effort. // It's possible that log() itself throws exception, then there isn't a good way to write a log. } } } } }