Skip to content

Instantly share code, notes, and snippets.

@nekomimi-daimao
Last active December 13, 2023 19:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nekomimi-daimao/b9baa2282cd548fe066cf44d2fd35e7d to your computer and use it in GitHub Desktop.
Save nekomimi-daimao/b9baa2282cd548fe066cf44d2fd35e7d to your computer and use it in GitHub Desktop.
Unity, write logfile
20210825022416 [L] (0.4, -0.8, -0.4)
20210825022416 [W] RGBA(0.545, 0.403, 0.468, 1.000)
20210825022416 [E] (0.4, 0.5, 0.5, 0.6)
20210825022416 [L] (-0.2, 0.9, -0.4)
20210825022416 [W] RGBA(0.078, 0.413, 0.256, 1.000)
20210825022416 [E] (0.0, -0.2, 0.7, 0.6)
20210825022417 [L] (0.6, 0.7, 0.3)
20210825022417 [W] RGBA(0.914, 0.453, 0.567, 1.000)
20210825022417 [E] (0.9, 0.0, 0.0, 0.3)
20210825022417 [L] (-0.1, -0.1, -1.0)
20210825022417 [W] RGBA(0.639, 0.688, 0.682, 1.000)
20210825022417 [E] (0.6, 0.3, 0.4, 0.7)
20210825022417 [L] (0.3, 0.0, 1.0)
20210825022417 [W] RGBA(0.274, 0.541, 0.482, 1.000)
20210825022417 [E] (0.0, -0.6, 0.2, 0.8)
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace Nekomimi.Daimao
{
public class LogWriter
{
/// <summary>
/// LogFilePath
/// </summary>
public readonly string LogPath;
public LogWriter(string logPath, CancellationToken cancellationToken)
{
this.LogPath = logPath;
Application.logMessageReceivedThreaded += OnLogMessageReceivedThreaded;
LogWriteLoop(cancellationToken).Forget();
}
private readonly Dictionary<int, string> logLevelCase = new Dictionary<int, string>()
{
{(int) LogType.Error, "E"},
{(int) LogType.Assert, "A"},
{(int) LogType.Warning, "W"},
{(int) LogType.Log, "L"},
{(int) LogType.Exception, "Ex"},
};
private const string DateTimeFormat = "yyyyMMddHHmmss";
private void OnLogMessageReceivedThreaded(string condition, string stacktrace, LogType type)
{
logQueue.Add($"{DateTimeOffset.Now.ToString(DateTimeFormat)} [{logLevelCase[(int) type]}] {condition}");
}
private readonly BlockingCollection<string> logQueue = new BlockingCollection<string>(new ConcurrentQueue<string>());
private async UniTaskVoid LogWriteLoop(CancellationToken cancellationToken)
{
StreamWriter streamWriter = null;
try
{
var parentDir = new FileInfo(LogPath).Directory;
if (parentDir != null && !parentDir.Exists)
{
parentDir.Create();
}
streamWriter = new StreamWriter(LogPath, true, Encoding.UTF8);
while (true)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
await UniTask.SwitchToThreadPool();
var log = logQueue.Take(cancellationToken);
await streamWriter.WriteLineAsync(log);
}
}
finally
{
if (streamWriter != null)
{
await streamWriter.FlushAsync();
streamWriter.Close();
streamWriter.Dispose();
}
}
}
}
}
private void Start()
{
// /Assets/StreamingAssets/log/example.txt
var path = Path.Combine(Application.streamingAssetsPath, "log", "example.txt");
var logWriter = new LogWriter(path, this.GetCancellationTokenOnDestroy());
}
private void Update()
{
Debug.Log(UnityEngine.Random.onUnitSphere);
Debug.LogWarning(UnityEngine.Random.ColorHSV());
Debug.LogError(UnityEngine.Random.rotation);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment