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

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

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

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

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

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

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


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

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

6   голосов , оценка 4 из 5
Похожие ответы