c4353b8e
New Member
- May 26, 2018
- 20
- 8
I know a lot of emulators use the package log4net & a few others but I've always seen it as overload, especially how emulators never really get into using even half of the functionality of that package. I put together a simple clone of what NLog does in a single class.
If anybody likes writing their own code, or just need something minimal, here you go. It could be written a lot better but what couldn't, it serves its purpose & I'm happy with the code quality it's at. You probably don't need the File.Exists part inside the final method, but I just put it there for safety. Id recommend throwing an interface on this too so you can have multiple types of ILogger
Update: Improved code quality, cached streams, & better logic for getting the files & colors via log type.
Here are the other files.
& the interface
Here's some usage, using statement for instant disposal.
Don't do the using approach in production, it'll close the streams instantly and the caching is useless. Create a property for each class that requires to log and you can use it throughout its lifetime.
If anybody likes writing their own code, or just need something minimal, here you go. It could be written a lot better but what couldn't, it serves its purpose & I'm happy with the code quality it's at. You probably don't need the File.Exists part inside the final method, but I just put it there for safety. Id recommend throwing an interface on this too so you can have multiple types of ILogger
Code:
public class ConsoleLogger <TClass> : ILogger, IDisposable
{
private readonly string _filePath;
private readonly Type _className;
private readonly Dictionary<string, StreamWriter> _streams;
public ConsoleLogger()
{
_filePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location + "/resources/logging/");
_className = typeof(TClass);
_streams = new Dictionary<string, StreamWriter>();
}
private readonly Dictionary<LogType, string> _fileForLogType = new Dictionary<LogType, string> {
{LogType.Success , "trace.log"},
{LogType.Warn , "error.log"},
{LogType.Error , "error.log"},
{LogType.Debug , "debug.log"},
};
private readonly Dictionary<LogType, ConsoleColor> _colorForLogType = new Dictionary<LogType, ConsoleColor> {
{LogType.Success , ConsoleColor.Green},
{LogType.Warn , ConsoleColor.Yellow},
{LogType.Error , ConsoleColor.Red},
{LogType.Debug , ConsoleColor.Cyan},
};
public void Trace(string message, bool logToFile = false)
{
Log(message, LogType.Trace, logToFile);
}
public void Warn(string message, bool logToFile = false)
{
Log(message, LogType.Warn, logToFile);
}
public void Debug(string message, bool logToFile = false)
{
Log(message, LogType.Debug, logToFile);
}
public void Success(string message, bool logToFile = false)
{
Log(message, LogType.Success, logToFile);
}
public void Error(string message, bool logToFile = false)
{
Log(message, LogType.Error, logToFile);
}
public void Error(Exception e, bool logToFile = true)
{
Log("An error occurred: " + Environment.NewLine + e, LogType.Error, logToFile);
}
private void Log(string message, LogType logType, bool logToFile = false)
{
var oldColor = Console.ForegroundColor;
Console.ForegroundColor = _colorForLogType[logType];
Console.WriteLine($"[{DateTime.Now:MM/dd HH:mm:ss}] " + message);
Console.ForegroundColor = oldColor;
if (logToFile)
{
LogToFile(_fileForLogType[logType], $"Occurred at [{DateTime.Now:MM/dd HH:mm:ss}] in [{_className.FullName}]: {message}");
}
}
private void LogToFile(string file, string content)
{
var fullPath = Path.Combine(_filePath, file);
if (!Directory.Exists(_filePath))
{
Directory.CreateDirectory(_filePath);
}
if (!File.Exists(fullPath))
{
File.Create(fullPath);
}
if (!_streams.ContainsKey(file))
{
_streams.Add(file, new StreamWriter(_filePath + file, true));
}
_streams[file].WriteLine(content);
}
public void Dispose()
{
foreach (var stream in _streams.Values)
{
stream.Dispose();
}
}
}
Update: Improved code quality, cached streams, & better logic for getting the files & colors via log type.
Here are the other files.
Code:
public enum LogType
{
Trace,
Warn,
Debug,
Success,
Error
}
& the interface
Code:
public interface ILogger
{
void Trace(string message, bool logToFile = false);
void Warn(string message, bool logToFile = false);
void Debug(string message, bool logToFile = false);
void Success(string message, bool logToFile = false);
void Error(string message, bool logToFile = false);
void Error(Exception e, bool logToFile = true);
}
Here's some usage, using statement for instant disposal.
Code:
using (var logger = new ConsoleLogger(typeof(Program)))
{
logger.Debug("test");
logger.Warn("test");
logger.Trace("test");
logger.Success("test");
logger.Error("test", true);
}
Don't do the using approach in production, it'll close the streams instantly and the caching is useless. Create a property for each class that requires to log and you can use it throughout its lifetime.
Last edited: