Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Classi utili - CV-Log

C# > C# - Classi utili

Introduzione

  • La classe CV-Log è una classe utile per scrivere il log delle applicazioni.
  • Le caratteristiche sono:
    • Utilizzo molto semplice.
    • Sono configurabili i seguenti parametri: (1) Dimensione del file di log; (2) Numero massimo di file da conservare; (3) Directory di scrittura dei file log.
    • Le righe di log hanno: (1) Categoria (anch'essa configurabile); (2) Classe; (3) Metodo; (4) Testo.
    • Utilizzo del pattern 'Singleton', didatticamente interessante.

Classe CV_Log
  • Di seguito, la classe.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace MyLog
{
   public class CV_Log
   {
       // Utilizzo del pattern 'Singleton'.
       private static CV_Log _instance;

       // Parametri di configurazione.
       int MaxFileSize = 1048576;
       int MaxNumberFiles = 10;
       string LogDirectory = @"c:\log\";

       string FileToUse = "";

       public enum Category
       {
           DEBUG,
           ERROR,
           MESSAGE,
           TRACE
       }

       protected CV_Log()
       {
       }

       public static CV_Log Instance()
       {
           if (_instance == null)
           {
               _instance = new CV_Log();
           }

           return _instance;
       }

       public bool WriteLog(Category category, string className, string functionName, string freeText)
       {
           try
           {
               // Stringa da scrivere.
               StringBuilder sb = new StringBuilder();
               sb.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
               sb.Append(" ");
               sb.Append(category.ToString().PadRight(7));
               sb.Append(" ");
               sb.Append("<" + className + ">");
               sb.Append(" ");
               sb.Append("<" + functionName + ">");
               sb.Append(" ");
               sb.Append(freeText);
               sb.Append(Environment.NewLine);

               // Cerca se un file è già stato utilizzato dalla classe.
               if (FileToUse == String.Empty)
               {
                   // Crea la directory.
                   if (!Directory.Exists(LogDirectory))
                   {
                       Directory.CreateDirectory(LogDirectory);
                   }

                   // Ultimo file generato nella cartella.
                   DirectoryInfo dInfo = new DirectoryInfo(LogDirectory);
                   List<FileInfo> files = dInfo.GetFiles("*.log").OrderByDescending(fi => fi.Name).ToList();
                   if (files.Count > 0)
                   {
                       FileToUse = files[0].FullName;
                   }
               }

               // Se non c'è nessun file, se ne genera uno.
               bool checkForDeleting = false;
               if (FileToUse == String.Empty)
               {
                   FileToUse = LogDirectory + DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss") + ".log";
                   checkForDeleting = true;
               }
               else
               {
                   // Verifica della dimensione del file attuale.
                   FileInfo fInfo = new System.IO.FileInfo(FileToUse);
                   if (fInfo.Length >= MaxFileSize)
                   {
                       FileToUse = Path.Combine(LogDirectory, DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss") + ".log");
                       checkForDeleting = true;
                   }
               }

               // Scrittura del file.
               using (FileStream fsWrite = new FileStream(FileToUse, FileMode.Append))
               {
                   Byte[] arInput = new UTF8Encoding(true).GetBytes(sb.ToString());
                   fsWrite.Write(arInput, 0, arInput.Length);
               }

               // Elimina i file vecchi.
               if (checkForDeleting)
               {
                   DirectoryInfo dInfo = new DirectoryInfo(LogDirectory);
                   List<FileInfo> files = dInfo.GetFiles("*.log").OrderBy(fi => fi.Name).ToList();
                   if (files.Count > MaxNumberFiles)
                   {
                       for (int i = 0; i < files.Count - MaxNumberFiles; i++)
                       {
                           File.Delete(files[i].FullName);
                       }
                   }
               }
           }
 
           catch (Exception ex)
           {
               return false;
           }

           return true;
       }
   }
}

Dettagli
  • Nelle prime righe della classe sono presenti le seguenti istruzioni che permettono di configurare rispettivamente:
    • La dimensione dei file di log.
    • Il numero massimo di file da tenere.
    • La directory dove scrivere i file di log.

  int MaxFileSize = 1048576;
  int MaxNumberFiles = 10;
  string LogDirectory = @"c:\log\";

  • Le categorie presenti sono le seguenti, ovviamente configurabili.

  public enum Category
  {
      DEBUG,
      ERROR,
      MESSAGE,
      TRACE
  }

  • Essendo utilizzato il pattern 'Singleton', il progetto che utilizza la classe utilizzerà una sola istanza della classe.

Esempio di utilizzo
  • Per utilizzare la classe e far sì che nei file di log vengano correttamente scritti la classe e il metodo è necessario aggiungere il namespace seguente.

   using System.Reflection;

  • L'utilizzo della classe è il seguente. Nel primo esempio il codice è eseguito all'interno di un evento; nel secondo all'interno di un metodo.

   private void button1_Click(object sender, EventArgs e)
   {
       CV_Log LogFile = CV_Log.Instance();
       LogFile.WriteLog(CV_Log.Category.TRACE, MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, "Messaggio");
   }

   private void Metodo1()
   {
       CV_Log LogFile = CV_Log.Instance();
       LogFile.WriteLog(CV_Log.Category.TRACE, MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, "Inizio Metodo");
       // ...
       LogFile.WriteLog(CV_Log.Category.TRACE, MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, "Fine Metodo");
   }

  • Le righe nei file di log generati, sono le seguenti:

2019-08-09 11:15:51.057 TRACE <Form1> <button1_Click> Messaggio
2019-08-09 11:16:04.456 TRACE <Form1> <Metodo1> Inizio Metodo
2019-08-09 11:16:04.456 TRACE <Form1> <Metodo1> Fine Metodo




© 2020 Carlo Vecchio
Torna ai contenuti