11using System ;
22using System . Collections . Generic ;
3+ using System . IO ;
34using System . Linq ;
45using System . Timers ;
56using MemPlus . Business . EXPORT ;
7+ using Timer = System . Timers . Timer ;
68
79namespace MemPlus . Business . LOG
810{
11+ /// <inheritdoc />
912 /// <summary>
1013 /// Class containing methods to control logs
1114 /// </summary>
12- public class LogController
15+ // ReSharper disable once InconsistentNaming
16+ public class LogController : IDisposable
1317 {
1418 #region Variables
1519 /// <summary>
1620 /// The list of available Log objects
1721 /// </summary>
1822 private readonly List < Log > _logList ;
23+ /// <summary>
24+ /// The timer that can be used to automatically clear logs
25+ /// </summary>
26+ private readonly Timer _autoClearTimer ;
27+ /// <summary>
28+ /// True if logs should be written to a file, otherwise false
29+ /// </summary>
30+ private bool _saveToFile ;
31+ /// <summary>
32+ /// The DateTime object at which the LogController object was initialized
33+ /// </summary>
34+ private readonly DateTime _startTime ;
35+ /// <summary>
36+ /// The path where logs can be stored
37+ /// </summary>
38+ private string _logPath ;
39+ /// <summary>
40+ /// The FileStream object that can be used to write logs to the disk
41+ /// </summary>
42+ private FileStream _fileStream ;
43+ /// <summary>
44+ /// The StreamWriter object that can be used to write logs to the disk
45+ /// </summary>
46+ private StreamWriter _streamWriter ;
47+ /// <summary>
48+ /// True if the StreamWriter is writing data to the log file, otherwise false
49+ /// </summary>
50+ private bool _isWriting ;
1951 #endregion
2052
2153 #region Delegates
2254 /// <summary>
2355 /// Delegate that will be called when a Log object was added
2456 /// </summary>
2557 /// <param name="l">The Log object that was added</param>
58+ // ReSharper disable once InconsistentNaming
2659 internal delegate void LogAdded ( Log l ) ;
2760 /// <summary>
2861 /// Delegate that will be called when a Log object was removed
2962 /// </summary>
3063 /// <param name="l">The Log object that was deleted</param>
64+ // ReSharper disable once InconsistentNaming
3165 internal delegate void LogDeleted ( Log l ) ;
3266 /// <summary>
3367 /// Delegate that will be called when all Log objects are removed
@@ -37,6 +71,7 @@ public class LogController
3771 /// Delegate that will be called when a list of Log objects with a specific LogType were removed
3872 /// </summary>
3973 /// <param name="clearedList">The list of Log objects that were removed</param>
74+ // ReSharper disable once InconsistentNaming
4075 internal delegate void LogTypeCleared ( List < Log > clearedList ) ;
4176 /// <summary>
4277 /// Method that will be called when a Log object was added
@@ -59,15 +94,108 @@ public class LogController
5994 /// <summary>
6095 /// Initialize a new LogController object
6196 /// </summary>
97+ internal LogController ( )
98+ {
99+ _logList = new List < Log > ( ) ;
100+
101+ _autoClearTimer = new Timer ( ) ;
102+ _autoClearTimer . Elapsed += OnTimedEvent ;
103+ _autoClearTimer . Interval = 600000 ;
104+ _autoClearTimer . Enabled = true ;
105+
106+ _saveToFile = false ;
107+ _startTime = DateTime . Now ;
108+ _logPath = null ;
109+ }
110+
111+ /// <summary>
112+ /// Initialize a new LogController object
113+ /// </summary>
114+ /// <param name="autoClear">True if the logs should be cleared automatically</param>
62115 /// <param name="clearInterval">The interval for when ApplicationLog objects should automatically be cleared</param>
63- internal LogController ( int clearInterval )
116+ /// <param name="saveToFile">True if logs should be written to a file</param>
117+ /// <param name="saveDirectory">The directory to which the logs should be written</param>
118+ internal LogController ( bool autoClear , int clearInterval , bool saveToFile , string saveDirectory )
64119 {
65120 _logList = new List < Log > ( ) ;
66121
67- Timer logTimer = new Timer ( ) ;
68- logTimer . Elapsed += OnTimedEvent ;
69- logTimer . Interval = clearInterval ;
70- logTimer . Enabled = true ;
122+ _autoClearTimer = new Timer ( ) ;
123+ _autoClearTimer . Elapsed += OnTimedEvent ;
124+ _autoClearTimer . Interval = clearInterval ;
125+ _autoClearTimer . Enabled = autoClear ;
126+
127+ _startTime = DateTime . Now ;
128+ // Set this after the DateTime has been established
129+ SetSaveDirectory ( saveDirectory ) ;
130+ /*
131+ * Make sure this is the last LogController method that is called
132+ * because this will only work properly when all other settings (especially the directory)
133+ * have been set correctly
134+ */
135+ SetSaveToFile ( saveToFile ) ;
136+ }
137+
138+ /// <summary>
139+ /// Set whether logs should be cleared automatically or not
140+ /// </summary>
141+ /// <param name="autoClear">True if logs should be cleared automatically, otherwise false</param>
142+ internal void SetAutoClear ( bool autoClear )
143+ {
144+ _autoClearTimer . Enabled = autoClear ;
145+ }
146+
147+ /// <summary>
148+ /// Set the automatic log clearing interval
149+ /// </summary>
150+ /// <param name="clearInterval">The time it takes in milliseconds before logs are cleared</param>
151+ internal void SetAutoClearInterval ( int clearInterval )
152+ {
153+ _autoClearTimer . Interval = clearInterval ;
154+ }
155+
156+ /// <summary>
157+ /// Set whether logs should be saved to a file
158+ /// </summary>
159+ /// <param name="saveToFile">True if logs should be saved to a file, otherwise false</param>
160+ internal void SetSaveToFile ( bool saveToFile )
161+ {
162+ if ( _saveToFile )
163+ {
164+ // Make sure the contents of the log file is written before disabling this function
165+ DisposeFileResources ( ) ;
166+ }
167+
168+ if ( saveToFile )
169+ {
170+ // Generate a new FileStream that allows other handles to access the file
171+ _fileStream = new FileStream ( _logPath ,
172+ FileMode . OpenOrCreate ,
173+ FileAccess . Write ,
174+ FileShare . ReadWrite ) ;
175+ _streamWriter = new StreamWriter ( _fileStream ) { AutoFlush = true } ;
176+ }
177+
178+ _saveToFile = saveToFile ;
179+ }
180+
181+ /// <summary>
182+ /// Set the directory to which logs can be saved
183+ /// </summary>
184+ /// <param name="saveDirectory">The directory to which logs can be saved</param>
185+ internal void SetSaveDirectory ( string saveDirectory )
186+ {
187+ if ( ! Directory . Exists ( saveDirectory ) ) throw new IOException ( "The selected log directory (" + saveDirectory + ") does not exist!" ) ;
188+
189+ // Format the directory string
190+ if ( saveDirectory . Substring ( saveDirectory . Length - 1 , 1 ) != "\\ " )
191+ {
192+ saveDirectory += "\\ " ;
193+ }
194+
195+ // Generate a new file path for the logs using the starting time of the LogController instance
196+ // ReSharper disable once StringLiteralTypo
197+ _logPath = saveDirectory + "memplus_" + _startTime . Year + _startTime . Month + _startTime . Day + "_" +
198+ _startTime . Hour + _startTime . Minute + _startTime . Second + ".log" ;
71199 }
72200
73201 /// <summary>
@@ -88,6 +216,18 @@ internal void AddLog(Log l)
88216 {
89217 _logList . Add ( l ) ;
90218 LogAddedEvent ? . Invoke ( l ) ;
219+ if ( _saveToFile ) WriteLogToFile ( l ) ;
220+ }
221+
222+ /// <summary>
223+ /// Write a log to a file
224+ /// </summary>
225+ /// <param name="l">The log that should be written to a file</param>
226+ private void WriteLogToFile ( Log l )
227+ {
228+ _isWriting = true ;
229+ _streamWriter . WriteLine ( "[" + l . Time + "]\t " + l . Data ) ;
230+ _isWriting = false ;
91231 }
92232
93233 /// <summary>
@@ -201,5 +341,32 @@ internal void Export(string path, LogType? logType, ExportTypes.ExportType expor
201341 break ;
202342 }
203343 }
344+
345+ /// <summary>
346+ /// Dispose of and flush the StreamWriter and FileStream objects that are in use to write logs to the disk
347+ /// </summary>
348+ private void DisposeFileResources ( )
349+ {
350+ while ( _isWriting )
351+ {
352+ // Wait for the StreamWriter to complete
353+ }
354+
355+ // Flush and close the StreamWriter if applicable
356+ _streamWriter ? . Close ( ) ;
357+
358+ // Close the FileStream if applicable
359+ _fileStream ? . Close ( ) ;
360+ }
361+
362+ /// <inheritdoc />
363+ /// <summary>
364+ /// Flush and close all used resources
365+ /// </summary>
366+ public void Dispose ( )
367+ {
368+ _autoClearTimer ? . Dispose ( ) ;
369+ DisposeFileResources ( ) ;
370+ }
204371 }
205372}
0 commit comments