Log.cs
author Thomas
Mon, 12 Feb 2018 16:40:36 +0100
changeset 1999 dfab19314f7d
parent 1979 cf610012e16d
child 2163 a0204de8d671
permissions -rw-r--r--
OUT-151: Only create partial PEPMessage with recipients and direction for outgoing rating
     1 ´╗┐using System;
     2 using System.IO;
     3 
     4 namespace pEp
     5 {
     6     /// <summary>
     7     /// Class to handle all the logging of pEp for Outlook.
     8     /// </summary>
     9     internal class Log
    10     {
    11         private const string LOG_FILE_NAME              = "log.txt";
    12         private const string LOG_FILE_FOLDER            = "pEp";
    13         private const string LOG_FILE_DATE_FORMAT       = "yyyyMMddHHmmss";
    14         private const string LOG_FILE_ARCHIVE_PREFIX    = "log_";
    15         private const int    LOG_MAX_LINES              = 20000;      // The maximum lines a log file can reach before the log gets rotated
    16         private const int    LOG_MAX_FILES              = 10;      // The maximum count of log files before deletion of the oldest
    17 
    18         private static int          logLineCount = 0;
    19         private static StreamWriter logWriter    = null;
    20         private static object       mutexLogFile = new object();
    21 
    22         /**************************************************************
    23          * 
    24          * Methods
    25          * 
    26          *************************************************************/
    27 
    28         /// <summary>
    29         /// Gets the path of the log file.
    30         /// </summary>
    31         /// <returns>The path of the log file.</returns>
    32         private static string GetLogFilePath()
    33         {
    34             return (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), LOG_FILE_FOLDER, LOG_FILE_NAME));
    35         }
    36 
    37         /// <summary>
    38         /// Adds the given info text to the pEp for Outlook log.
    39         /// </summary>
    40         /// <param name="text">The text to add to the log.</param>
    41         public static void Info(string text)
    42         {
    43             if (text != null)
    44             {
    45                 Log.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " | " + text);
    46             }
    47             return;
    48         }
    49 
    50         /// <summary>
    51         /// Adds the given error text to the pEp for Outlook log.
    52         /// </summary>
    53         /// <param name="text">The error text to add to the log.</param>
    54         public static void Error(string text)
    55         {
    56             if (text != null)
    57             {
    58                 Log.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " |E| " + text);
    59             }
    60             return;
    61         }
    62 
    63         /// <summary>
    64         /// Adds the given sensitive text to the pEp for Outlook log only
    65         /// when sensitive data logging is enabled.
    66         /// </summary>
    67         /// <param name="text">The sensitive text to add to the log.</param>
    68         public static void SensitiveData(string text)
    69         {
    70             if ((text != null) &&
    71                 (Globals.ThisAddIn != null) &&
    72                 (Globals.ThisAddIn.Settings.IsSensitiveDataLoggingEnabled))
    73             {
    74                 Log.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " |S| " + text);
    75             }
    76             return;
    77         }
    78 
    79         /// <summary>
    80         /// Adds the given warning text to the pEp for Outlook log.
    81         /// </summary>
    82         /// <param name="text">The warning text to add to the log.</param>
    83         public static void Warning(string text)
    84         {
    85             if (text != null)
    86             {
    87                 Log.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " |W| " + text);
    88             }
    89             return;
    90         }
    91 
    92         /// <summary>
    93         /// Adds the given verbose text to the pEp for Outlook log only
    94         /// when verbose logging is enabled.
    95         /// </summary>
    96         /// <param name="text">The verbose text to add to the log.</param>
    97         public static void Verbose(string text)
    98         {
    99             if ((text != null) &&
   100                 (Globals.ThisAddIn != null) &&
   101                 (Globals.ThisAddIn.Settings.IsVerboseLoggingEnabled))
   102             {
   103                 Log.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " |V| " + text);
   104             }
   105             return;
   106         }
   107 
   108         /// <summary>
   109         /// Writes the given text to the log file.
   110         /// </summary>
   111         /// <param name="text">The text to write to the log file.</param>
   112         private static void Write(string text)
   113         {
   114             try
   115             {
   116                 if (text != null)
   117                 {
   118                     lock (mutexLogFile)
   119                     {
   120                         if (Log.logWriter == null)
   121                         {
   122                             // If file exists, set line counter to file line count
   123                             if (File.Exists(Log.GetLogFilePath()))
   124                             {
   125                                 try
   126                                 {
   127                                     var lines = File.ReadAllLines(Log.GetLogFilePath());
   128                                     Log.logLineCount = lines.Length;
   129                                 }
   130                                 catch { }
   131                             }
   132 
   133                             // Open the file
   134                             Log.logWriter = File.AppendText(Log.GetLogFilePath());
   135                         }
   136 
   137                         Log.logWriter.WriteLine(text);
   138 
   139                         Log.logLineCount++;
   140 
   141                         // If the maximum line count was reached, clean up the log file by removing the first lines.
   142                         if (Log.logLineCount >= Log.LOG_MAX_LINES)
   143                         {
   144                             // Log.Sanitize();
   145                             Log.Archive();
   146                             Log.logLineCount = 0;
   147                         }
   148                     }
   149                 }
   150             }
   151             catch { }
   152 
   153             return;
   154         }
   155 
   156         /// <summary>
   157         /// Reads all lines of text from the log file.
   158         /// This will never return null.
   159         /// </summary>
   160         /// <returns>The lines of text in the log file.</returns>
   161         public static string Read()
   162         {
   163             string log = "";
   164             string path;
   165             StreamReader logReader;
   166 
   167             try
   168             {
   169                 Log.Close();
   170 
   171                 lock (mutexLogFile)
   172                 {
   173                     path = Log.GetLogFilePath();
   174                     if (File.Exists(path))
   175                     {
   176                         logReader = new StreamReader(path);
   177                         log = logReader.ReadToEnd();
   178 
   179                         logReader.Close();
   180                     }
   181                 }
   182 
   183                 // Never allow null
   184                 if (log == null)
   185                 {
   186                     log = "";
   187                 }
   188             }
   189             catch { }
   190 
   191             return (log);
   192         }
   193 
   194         /// <summary>
   195         /// Closes and releases any open log file writer.
   196         /// </summary>
   197         public static void Close()
   198         {
   199             try
   200             {
   201                 lock (mutexLogFile)
   202                 {
   203                     if (Log.logWriter != null)
   204                     {
   205                         Log.logWriter.Flush();
   206                         Log.logWriter.Close();
   207                         Log.logWriter.Dispose();
   208                         Log.logWriter = null;
   209                     }
   210                 }
   211             }
   212             catch { }
   213 
   214             return;
   215         }
   216 
   217         /// <summary>
   218         /// Clears all logged text by deleting the file.
   219         /// </summary>
   220         public static void Clear()
   221         {
   222             string path;
   223 
   224             try
   225             {
   226                 Log.Close();
   227 
   228                 lock (mutexLogFile)
   229                 {
   230                     path = Log.GetLogFilePath();
   231                     if (File.Exists(path))
   232                     {
   233                         File.Delete(path);
   234                     }
   235                 }
   236             }
   237             catch { }
   238 
   239             return;
   240         }
   241 
   242         /// <summary>
   243         /// Rotates the log by saving a copy of the current log file to an archived file 
   244         /// and deleting older archived logs if necessary.
   245         /// </summary>
   246         public static void Archive()
   247         {
   248             int counter = 0;
   249             string[] logFiles = null;
   250             string archiveFile = null;
   251 
   252             // Create archive file with current date and timestamp
   253             try
   254             {
   255                 archiveFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), LOG_FILE_FOLDER, LOG_FILE_ARCHIVE_PREFIX);
   256                 archiveFile += DateTime.Now.ToString(LOG_FILE_DATE_FORMAT);
   257                 archiveFile += ".txt";
   258 
   259                 while (File.Exists(archiveFile))
   260                 {
   261                     archiveFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), LOG_FILE_FOLDER, LOG_FILE_ARCHIVE_PREFIX);
   262                     archiveFile += DateTime.Now.ToString(LOG_FILE_DATE_FORMAT);
   263                     archiveFile += ".txt";
   264 
   265                     // Just to be sure in case there is an error somewhere
   266                     if (counter++ > 100)
   267                     {
   268                         throw new Exception("The file already exists.");
   269                     }
   270                 }
   271             }
   272             catch (Exception ex)
   273             {
   274                 Log.Error("Could not archive log file. Error creating archive file. " + ex.ToString());
   275                 archiveFile = null;
   276             }
   277 
   278             // Move current log to archive log file
   279             if (archiveFile != null)
   280             {
   281                 lock (mutexLogFile)
   282                 {
   283                     Log.Close();
   284 
   285                     try
   286                     {
   287                         File.Move(Log.GetLogFilePath(), archiveFile);
   288                     }
   289                     catch (Exception ex)
   290                     {
   291                         Log.Warning("Could not archive log file. " + ex.ToString());
   292                     }
   293 
   294                     Log.Clear();
   295                 }
   296             }
   297 
   298             // Delete older log files if necessary
   299             try
   300             {
   301                 logFiles = Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), LOG_FILE_FOLDER));
   302                 logFiles = Array.FindAll(logFiles, a => a.ToUpperInvariant().Contains(LOG_FILE_ARCHIVE_PREFIX.ToUpperInvariant()));
   303             }
   304             catch
   305             {
   306                 logFiles = null;
   307             }
   308 
   309             if ((logFiles != null) &&
   310                 (logFiles.Length > LOG_MAX_FILES))
   311             {
   312                 Array.Sort(logFiles, StringComparer.Ordinal);
   313 
   314                 for (int i = 0; i < (logFiles.Length - LOG_MAX_FILES); i++)
   315                 {
   316                     try
   317                     {
   318                         File.Delete(logFiles[i]);
   319                     }
   320                     catch (Exception ex)
   321                     {
   322                         Log.Warning("LogRotate: Could not delete old log file. " + ex.ToString());
   323                     }
   324                 }
   325             }
   326         }
   327     }
   328 }