-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathFLog.cs
158 lines (146 loc) · 7.69 KB
/
FLog.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using VolumeControl.Log.Endpoints;
using VolumeControl.Log.Exceptions;
namespace VolumeControl.Log
{
/// <summary>
/// Static file logger class.
/// </summary>
/// <remarks>
/// The <see cref="Initialize"/> method must be called before accessing any properties.
/// </remarks>
public static class FLog
{
#region Fields
private static bool _initialized = false;
private static AsyncLogWriter _logWriter = null!;
#endregion Fields
#region Properties
/// <summary>
/// Gets the <see cref="AsyncLogWriter"/> instance.
/// </summary>
/// <remarks>
/// To preserve thread-safety, the <see cref="FileEndpoint"/> cannot be accessed through the log writer. It can be configured via the relevant setting in the Config.
/// </remarks>
public static AsyncLogWriter Log
{
get
{
if (!_initialized)
throw MakeLogNotInitializedException();
return _logWriter;
}
}
/// <inheritdoc cref="AsyncLogWriter.IsAsyncEnabled"/>
public static bool IsAsyncEnabled
{
get
{
if (!_initialized)
throw MakeLogNotInitializedException();
return _logWriter.IsAsyncEnabled;
}
set
{
if (!_initialized)
throw MakeLogNotInitializedException();
_logWriter.IsAsyncEnabled = value;
}
}
/// <summary>
/// Gets whether this log has been initialized yet or not.
/// </summary>
/// <remarks>
/// This does not throw exceptions.
/// </remarks>
public static bool IsInitialized => _initialized;
#endregion Properties
#region Methods
#region (Private)
/// <summary>
/// Creates a new string that contains the log init message that appears on the first line of the log.
/// </summary>
/// <param name="verb">Displayed in the header as "Log (verb)"</param>
private static string MakeInitMessage(string verb)
=> $"{AsyncLogWriter.DateTimeFormatString}{AsyncLogWriter.Indent(AsyncLogWriter.TimestampLength, AsyncLogWriter.DateTimeFormatString.Length)}{new string(' ', AsyncLogWriter.EventTypeLength)}=== Log {verb} @ {DateTime.UtcNow:U} === {{ LogFilter: {(int)Log.EventTypeFilter} ({Log.EventTypeFilter:G}) }}";
private static void WriteLineRaw(string text)
{
lock (Log.Endpoint)
{
Log.Endpoint.WriteLine(text);
}
}
private static NotInitializedException MakeLogNotInitializedException(Exception? innerException = null)
=> new(nameof(FLog), "The log hasn't been initialized yet!", innerException);
#endregion (Private)
#region Initialize
/// <summary>
/// Initializes the log. The settings object must be created before calling this method. This method can only be called once.
/// </summary>
/// <exception cref="InvalidOperationException">The method has already been called before.</exception>
/// <exception cref="NotInitializedException">The default config object hasn't been initialized yet.</exception>
public static void Initialize(string path, bool enable, EventType logFilter, bool deleteExisting = true)
{
if (_initialized) // already initialized
throw new InvalidOperationException($"{nameof(FLog)} is already initialized! {nameof(Initialize)}() can only be called once.");
_logWriter = new(new PersistentFileEndpoint(path, enable), logFilter);
_initialized = true; //< Log is valid here
if (deleteExisting)
{
Log.ResetEndpoint(MakeInitMessage("Initialized"));
}
else WriteLineRaw(MakeInitMessage("Initialized"));
}
#endregion Initialize
#region ChangeLogPath
/// <summary>
/// Sets the log path to a new location.
/// </summary>
/// <param name="newPath">The filepath to change the log path to.</param>
public static void ChangeLogPath(string newPath)
{
if (!_initialized)
throw MakeLogNotInitializedException();
((FileEndpoint)Log.Endpoint).Path = newPath;
}
#endregion ChangeLogPath
#region AsyncLogWriter Methods
/// <inheritdoc cref="AsyncLogWriter.FilterEventType(EventType)"/>
public static bool FilterEventType(EventType eventType) => Log.FilterEventType(eventType);
/// <inheritdoc cref="AsyncLogWriter.LogMessage(Log.LogMessage)"/>
public static void LogMessage(LogMessage logMessage) => Log.LogMessage(logMessage);
/// <inheritdoc cref="AsyncLogWriter.Trace(object?[])"/>
public static bool Trace(params object?[] lines) => Log.LogMessage(new(EventType.TRACE, lines));
/// <inheritdoc cref="AsyncLogWriter.Trace(Log.LogMessage)"/>
public static bool Trace(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.TRACE));
/// <inheritdoc cref="AsyncLogWriter.Debug(object?[])"/>
public static bool Debug(params object?[] lines) => Log.LogMessage(new(EventType.DEBUG, lines));
/// <inheritdoc cref="AsyncLogWriter.Debug(Log.LogMessage)"/>
public static bool Debug(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.DEBUG));
/// <inheritdoc cref="AsyncLogWriter.Info(object?[])"/>
public static bool Info(params object?[] lines) => Log.LogMessage(new(EventType.INFO, lines));
/// <inheritdoc cref="AsyncLogWriter.Info(Log.LogMessage)"/>
public static bool Info(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.INFO));
/// <inheritdoc cref="AsyncLogWriter.Warning(object?[])"/>
public static bool Warning(params object?[] lines) => Log.LogMessage(new(EventType.WARN, lines));
/// <inheritdoc cref="AsyncLogWriter.Warning(Log.LogMessage)"/>
public static bool Warning(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.WARN));
/// <inheritdoc cref="AsyncLogWriter.Error(object?[])"/>
public static bool Error(params object?[] lines) => Log.LogMessage(new(EventType.ERROR, lines));
/// <inheritdoc cref="AsyncLogWriter.Error(Log.LogMessage)"/>
public static bool Error(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.ERROR));
/// <inheritdoc cref="AsyncLogWriter.Fatal(object?[])"/>
public static bool Fatal(params object?[] lines) => Log.LogMessage(new(EventType.FATAL, lines));
/// <inheritdoc cref="AsyncLogWriter.Fatal(Log.LogMessage)"/>
public static bool Fatal(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.FATAL));
/// <inheritdoc cref="AsyncLogWriter.Critical(object?[])"/>
public static bool Critical(params object?[] lines) => Log.LogMessage(new(EventType.CRITICAL, lines));
/// <inheritdoc cref="AsyncLogWriter.Critical(Log.LogMessage)"/>
public static bool Critical(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.CRITICAL));
/// <inheritdoc cref="AsyncLogWriter.Blank(object?[])"/>
public static bool Blank(params object?[] lines) => Log.LogMessage(new(EventType.NONE, lines));
/// <inheritdoc cref="AsyncLogWriter.Blank(Log.LogMessage)"/>
public static bool Blank(LogMessage logMessage) => Log.LogMessage(logMessage.SetEventType(EventType.NONE));
#endregion AsyncLogWriter Methods
#endregion Methods
}
}