using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Threading; namespace Tango.Logging { /// /// Represents an file logger. /// /// public class FileLogger : ILogger { private DateTime _logFileTimeDate; private System.Timers.Timer _removal_timer; private int _writeCount; private int _fileExtensionIndex; private const int FILE_SIZE_CHECK_COUNT = 100; public const string FILE_SET_EXTENSION = "__"; /// /// Gets the logs folder. /// public static String DefaultLogsFolder { get; private set; } /// /// Gets or sets the log file. /// public String LogFile { get; private set; } /// /// Gets the tag name which will be appended to the file. /// public String Tag { get; private set; } /// /// Gets or sets the log file folder. /// public String Folder { get; private set; } /// /// Gets or sets a value indicating whether [enable automatic log removal]. /// public bool EnableAutoLogRemoval { get; set; } /// /// Gets or sets the automatic log removal period. /// public TimeSpan AutoLogRemovalPeriod { get; set; } private TimeSpan _autoLogRemovalCheckPeriod; /// /// Gets or sets the automatic log removal check period. /// public TimeSpan AutoLogRemovalCheckPeriod { get { return _autoLogRemovalCheckPeriod; } set { _autoLogRemovalCheckPeriod = value; if (_removal_timer != null) { _removal_timer.Interval = _autoLogRemovalCheckPeriod.TotalMilliseconds; } } } /// /// Gets or sets a value indicating whether [enable maximum file size limit]. /// public bool EnableMaxFileSizeLimit { get; set; } /// /// Gets or sets the maximum file size limit. /// public long MaxFileSizeLimit { get; set; } public String GetFileSetExtension(int index) { return FILE_SET_EXTENSION + index; } /// /// Initializes the class. /// static FileLogger() { DefaultLogsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Logs", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName)); } /// /// Initializes a new instance of the class. /// /// Logs folder path. /// The tag name which will be appended to the file name. public FileLogger(String folder, String tag) { _isEnabled = true; Tag = tag; Folder = folder; Directory.CreateDirectory(Folder); _logFileTimeDate = DateTime.Now; LogFile = CreateLogFileName(); EnableAutoLogRemoval = false; AutoLogRemovalCheckPeriod = TimeSpan.FromHours(1); AutoLogRemovalPeriod = TimeSpan.FromDays(7); _removal_timer = new System.Timers.Timer(); _removal_timer.Interval = AutoLogRemovalCheckPeriod.TotalMilliseconds; _removal_timer.Elapsed += _removal_timer_Elapsed; _removal_timer.Start(); EnableMaxFileSizeLimit = true; MaxFileSizeLimit = 1000000 * 10; _fileExtensionIndex = 0; } /// /// Initializes a new instance of the class. /// public FileLogger() : this(DefaultLogsFolder, Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName)) { } /// /// Called when a new library trace is available. /// /// The output. public void OnLog(LogItemBase output) { try { if (DateTime.Now.Date > _logFileTimeDate.Date) { _fileExtensionIndex = 0; _writeCount = 0; _logFileTimeDate = DateTime.Now; CreateNewLogFile(); } else if (EnableMaxFileSizeLimit && ++_writeCount > FILE_SIZE_CHECK_COUNT) { if (new FileInfo(LogFile).Length > MaxFileSizeLimit) { if (_fileExtensionIndex == 0) { _fileExtensionIndex = 1; string oldPath = LogFile; LogFile = CreateLogFileName(); File.Move(oldPath, LogFile); } _fileExtensionIndex++; CreateNewLogFile(); _writeCount = 0; } } File.AppendAllText(LogFile, output.ToString() + Environment.NewLine); } catch { Debug.WriteLine("Error Writing To Log File!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } } private bool _isEnabled; /// /// Gets or sets a value indicating whether this is enabled. /// public bool Enabled { get { return _isEnabled; } set { _isEnabled = value; } } /// /// Creates the name of the log file. /// /// private String CreateLogFileName() { return Path.Combine(Folder, string.Format("{1}-{0:dd-MM-yyyy_HH-mm-ss}{2}.log", _logFileTimeDate, Tag, EnableMaxFileSizeLimit && _fileExtensionIndex > 0 ? GetFileSetExtension(_fileExtensionIndex) : String.Empty)); } private void CreateNewLogFile() { File.AppendAllText(LogFile, Environment.NewLine + Environment.NewLine + "### This log file continues on the next log file ###" + Environment.NewLine); LogFile = CreateLogFileName(); File.AppendAllText(LogFile, "### This log file is a continuation of a previous log file ###" + Environment.NewLine + Environment.NewLine); } #region Auto Log Removal /// /// Handles the Elapsed event of the _removal_timer control. /// /// The source of the event. /// The instance containing the event data. private void _removal_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (EnableAutoLogRemoval) { RemoveOldLogFiles(); } } /// /// Removes the old files. /// public void RemoveOldLogFiles() { try { if (Directory.Exists(Folder)) { DateTime removalDateTime = DateTime.Now - AutoLogRemovalPeriod; string[] fileEntries = Directory.GetFiles(Folder, "*.log"); foreach (string fileName in fileEntries) { try { FileInfo fi = new FileInfo(fileName); if (fi != null && fi.LastWriteTime < removalDateTime) { File.Delete(fi.FullName); } } catch (Exception ex) { Debug.WriteLine(ex); } } } } catch (Exception ex) { Debug.WriteLine(ex); } } #endregion } }