Как правильно организовать Log в приложении? - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Я хочу организовать в своем проекте логирование. Для этого набросал класс-логер. ILogger.cs
Листинг программы
  1. public interface ILogger
  2. {
  3. void Log(LogLevel logLevel, string Message);
  4. }
Logger.cs
Листинг программы
  1. public class AppLogger: ILogger
  2. {
  3. private static StreamWriter sw;
  4. private static string logFile;
  5. public AppLogger(string LogName , string FilePath = "")
  6. {
  7. string path;
  8. if (FilePath == string.Empty)
  9. {
  10. path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log");
  11. if (!Directory.Exists(FilePath))
  12. {
  13. Directory.CreateDirectory(path);
  14. }
  15. }
  16. else
  17. {
  18. path = FilePath;
  19. }
  20. logFile = Path.Combine(path, LogName);
  21. sw = new StreamWriter(logFile, true, Encoding.UTF8, 1024);
  22. sw.AutoFlush = true;
  23. }
  24. public void Log(LogLevel logLevel, string Message)
  25. {
  26. string str = string.Format("{0} ({1}): {2}",
  27. logLevel.ToString().PadRight(8),
  28. DateTime.Now.ToString("yyyy.MM.dd HH:MM:SS"),
  29. Message
  30. );
  31. Debug.WriteLine(str);
  32. sw.WriteLine(str);
  33. }
  34. }
LogLevel.cs
Листинг программы
  1. public enum LogLevel
  2. {
  3. None = 0,
  4. Debug = 1,
  5. Info = 2,
  6. Warning = 3,
  7. Error = 4,
  8. }
Пример применения Program.cs
Листинг программы
  1. MyLogger = new AppLogger(LogName: "MyLog");
  2. MyLogger.Log(LogLevel.Info, string.Format("Data Base type is {0}", Settings.ConnectionType));
У меня возник вопрос как эти классом пользоваться для журналирования действий в куче классов (например работы с БД)? Нужно ли в конструкторы классов передавать экземпляр логера? Например так: DatabaseProvider.cs
Листинг программы
  1. public abstract class DatabaseProvider
  2. {
  3. protected string CONNECT_STR = string.Empty;
  4. protected IDbConnection CNN = null;
  5. protected ILogger appLogger = null;
  6. public DatabaseProvider(string connectStr, ILogger AppLogger )
  7. {
  8. CONNECT_STR = connectStr;
  9. appLogger = AppLogger;
  10. }
  11. public abstract ProjectTableAbstract GetProjectTable();
  12. public abstract FirstUsageTableAbstract GetFirstUsageTable();
  13. public abstract OboznachenieTableAbstract GetOboznachenieTable();
  14. public abstract LiteralTableAbstract GetLiteralTable();
  15. public abstract IspolniteliTableAbstract GetIspolniteliTable();
  16. public abstract InventarNumberTableAbstract GetInventarNumberTable();
  17. public abstract MainTableAbstract GetMainTable();
  18. }
SqlCeDbProvider.cs
Листинг программы
  1. public class SqlCeDbProvider : DatabaseProvider
  2. {
  3. public SqlCeDbProvider(string connectStr, ILogger appLogger)
  4. : base(connectStr, appLogger)
  5. {
  6. CNN = new SqlCeConnection(CONNECT_STR);
  7. }
  8. public override ProjectTableAbstract GetProjectTable()
  9. {
  10. return new ProjectTableSqlCe(CNN, appLogger);
  11. }
  12. // остальные таблицы опущенны
  13. }
ProjectTableAbstract.cs
Листинг программы
  1. public abstract class ProjectTableAbstract
  2. {
  3. protected IDbConnection CNN = null;
  4. protected ILogger appLogger = null;
  5. public ProjectTableAbstract(IDbConnection Connection, ILogger AppLogger)
  6. {
  7. CNN = Connection;
  8. appLogger = AppLogger;
  9. }
  10. public abstract List<Project> GetEntities();
  11. public abstract bool AddToDB(string value);
  12. public abstract bool DeleteFromDB(string value, int id);
  13. public abstract bool RenameInDB(string oldValue, string newValue, int oldValueId);
  14. }
ProjectTableSqlCe.cs
Листинг программы
  1. public class ProjectTableSqlCe : ProjectTableAbstract
  2. {
  3. static SqlCeConnection SQLCeCon;
  4. public ProjectTableSqlCe(IDbConnection Connection, ILogger AppLogger) : base(Connection, AppLogger)
  5. {
  6. SQLCeCon = (SqlCeConnection)CNN;
  7. appLogger.Log(LogLevel.Info, string.Format("ProjectTable Init "));
  8. }
  9. public override List<Project> GetEntities()
  10. {
  11. List<Project> _lst = new List<Project>();
  12. if (SQLCeCon.State == ConnectionState.Closed)
  13. {
  14. SQLCeCon.Open();
  15. }
  16. _lst.Clear();
  17. CNN.Close();
  18. appLogger.Log(LogLevel.Info, string.Format("Project count {0}", _lst.Count));
  19. return _lst;
  20. }
  21. public override bool AddToDB(string value)
  22. {
  23. }
  24. public override bool DeleteFromDB(string value, int id)
  25. {
  26. }
  27. public override bool RenameInDB(string oldValue, string newValue, int oldValueId)
  28. {
  29. }
  30. }
При таком подходе получается, что экземпляр логера протаскивается через несколько уровней. Существуют ли другие способы бы работы с логером?

Решение задачи: «Как правильно организовать Log в приложении?»

textual
Листинг программы
  1. public static class MyLog()
  2. {
  3.    private static readonly Lazy<MyLog> instanceHolder = new Lazy<MyLog>(() => new MyLog());
  4.    //Constructor, logic, settings
  5.    public static MyLog Instance => instanceHolder.Value;
  6. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы