The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Logger.cs 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net.Mail;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using Teknik.Configuration;
  9. using Teknik.Utilities;
  10. namespace Teknik.Logging
  11. {
  12. public static class Logger
  13. {
  14. private static readonly object Locker = new object();
  15. public static void WriteEntry(string message)
  16. {
  17. WriteEntry(LogLevel.Info, message, null);
  18. }
  19. public static void WriteEntry(LogLevel level, string message)
  20. {
  21. WriteEntry(level, message, null);
  22. }
  23. public static void WriteEntry(Exception ex)
  24. {
  25. WriteEntry(LogLevel.Error, ex.Message, ex);
  26. }
  27. public static void WriteEntry(string message, Exception ex)
  28. {
  29. WriteEntry(LogLevel.Error, message, ex);
  30. }
  31. public static void WriteEntry(LogLevel level, string message, Exception exception)
  32. {
  33. // write an entry to the logs
  34. LogMessage log = new LogMessage();
  35. log.Level = level;
  36. log.Message = message;
  37. log.Exception = exception;
  38. WriteLogMessage(log);
  39. }
  40. private static void WriteLogMessage(LogMessage log)
  41. {
  42. try
  43. {
  44. Config config = Config.Load();
  45. if (config.LoggingConfig.Enabled)
  46. {
  47. // Do we want to write a log for this level? (Default to Error)
  48. LogLevel minLogLevel = LogLevel.Error;
  49. Enum.TryParse(config.LoggingConfig.LogLevel, out minLogLevel);
  50. try
  51. {
  52. if (log.Level >= minLogLevel)
  53. {
  54. // Lock the file processing so only 1 thread is working on the log file at a time
  55. lock (Locker)
  56. {
  57. if (!Directory.Exists(config.LoggingConfig.OutputDirectory))
  58. {
  59. Directory.CreateDirectory(config.LoggingConfig.OutputDirectory);
  60. }
  61. // Get current log file
  62. string fileName = Constants.LOG_FILE_NAME_PREFIX + Constants.LOG_FILE_EXT;
  63. string logFile = Path.Combine(config.LoggingConfig.OutputDirectory, fileName);
  64. if (File.Exists(logFile))
  65. {
  66. // File already exists, so lets see if we need to rotate it
  67. if (config.LoggingConfig.RotateLogs)
  68. {
  69. FileInfo info = new FileInfo(logFile);
  70. if (config.LoggingConfig.MaxSize < info.Length && config.LoggingConfig.MaxSize > 0)
  71. {
  72. // File is too large, so let's create a new name for it based on todays date
  73. string newFileName = Constants.LOG_FILE_NAME_PREFIX + "_" + DateTime.Now.ToString("yyyyMMdd") + Constants.LOG_FILE_EXT;
  74. newFileName = FileHelper.MakeUniqueFilename(newFileName, config.LoggingConfig.OutputDirectory);
  75. string newLog = Path.Combine(config.LoggingConfig.OutputDirectory, newFileName);
  76. // Move the current file to the new file
  77. File.Move(logFile, newLog);
  78. }
  79. // Make sure we have less than the max number of logs
  80. List<string> totalFiles = Directory.GetFiles(config.LoggingConfig.OutputDirectory, string.Format("{0}*{1}", Constants.LOG_FILE_NAME_PREFIX, Constants.LOG_FILE_EXT), SearchOption.TopDirectoryOnly).ToList();
  81. if (totalFiles.Count + 1 > config.LoggingConfig.MaxCount && config.LoggingConfig.MaxCount > 0)
  82. {
  83. // We will have too many logs, so let's remove the last one
  84. totalFiles.Sort();
  85. string fileToRemove = totalFiles[totalFiles.Count - 1];
  86. File.Delete(fileToRemove);
  87. }
  88. }
  89. }
  90. // We have rotated if needed, so let's write the entry
  91. File.AppendAllText(logFile, log.ToString() + Environment.NewLine);
  92. }
  93. }
  94. }
  95. catch (Exception) { } // If we throw when writing the log, still try to send the email if needed
  96. // Send Email Message if enabled
  97. if (config.LoggingConfig.SendEmail)
  98. {
  99. // Do we want to send an email for this level? (Default to error)
  100. LogLevel minEmailLevel = LogLevel.Error;
  101. Enum.TryParse(config.LoggingConfig.EmailLevel, out minEmailLevel);
  102. if (log.Level >= minEmailLevel)
  103. {
  104. string subject = string.Format("{0} Log Message", log.Level);
  105. string message = "Message: " + log.Message;
  106. if (log.Exception != null)
  107. {
  108. message += Environment.NewLine + Environment.NewLine + "Exception: " + log.Exception.GetFullMessage(true, true);
  109. }
  110. SendErrorEmail(subject, message);
  111. }
  112. }
  113. }
  114. }
  115. catch (Exception)
  116. {
  117. // Can't do anything about it. :/
  118. }
  119. }
  120. private static void SendErrorEmail(string subject, string message)
  121. {
  122. try
  123. {
  124. Config config = Config.Load();
  125. // Let's also email the message to support
  126. SmtpClient client = new SmtpClient();
  127. client.Host = config.LoggingConfig.SenderAccount.Host;
  128. client.Port = config.LoggingConfig.SenderAccount.Port;
  129. client.EnableSsl = config.LoggingConfig.SenderAccount.SSL;
  130. client.DeliveryMethod = SmtpDeliveryMethod.Network;
  131. client.UseDefaultCredentials = true;
  132. client.Credentials = new System.Net.NetworkCredential(config.LoggingConfig.SenderAccount.Username, config.LoggingConfig.SenderAccount.Password);
  133. client.Timeout = 5000;
  134. MailMessage mail = new MailMessage(config.LoggingConfig.SenderAccount.EmailAddress, config.LoggingConfig.RecipientEmailAddress);
  135. mail.Subject = subject;
  136. mail.Body = message;
  137. mail.BodyEncoding = UTF8Encoding.UTF8;
  138. mail.DeliveryNotificationOptions = DeliveryNotificationOptions.Never;
  139. client.Send(mail);
  140. }
  141. catch (Exception ex) { /* don't handle something in the handler */
  142. }
  143. }
  144. }
  145. }