Dove posizionare le dichiarazioni di registrazione

5

Ho le seguenti classi:

class Task
{
    public void DoSomething()
    { 
        var s = new Service();
        s.First();
        s.Second();
        s.Third();
    }
}

class Service
{
    public void First() {};
    public void Second() {};
    public void Third() {};
}

Se voglio aggiungere la registrazione, dovrei inserire le dichiarazioni di registrazione come questa:

    public void DoSomething()
    { 
        Log("new");
        var s = new Service();

        Log("First");
        s.First();

        Log("Second");
        s.Second();

        Log("Third");
        s.Third();
    }

O dovrei inserire ogni istruzione nei metodi chiamati di Service class?

So che è piuttosto soggettivo e non cambierà molte cose, ma sono curioso dei pro e dei contro di ciascun approccio.

Aggiornamento: non sto chiedendo informazioni sulla verbosità o il livello, solo sul posizionamento delle istruzioni di registrazione.

    
posta mathieu 06.04.2011 - 10:59
fonte

6 risposte

8

È davvero soggettivo. Ogni progetto e ogni situazione richiede il proprio livello e verbosità di registrazione.

Personalmente, inserirò le dichiarazioni nei metodi a cui si riferiscono. Questo è più infallibile, poiché registra qualsiasi chiamata a questi metodi, non solo quelli all'interno di doSomething() . Questo può aiutarti a individuare bug sottili nel lungo periodo, se i metodi vengono chiamati quando non è appropriato.

Tuttavia, non inserisco le istruzioni del registro di entrata / uscita nel codice per impostazione predefinita, in quanto creano troppo rumore. Solo casi specifici li giustificano, ad es. quando si analizza un modulo complesso o si cerca un bug insidioso (come un problema di concorrenza).

    
risposta data 06.04.2011 - 11:01
fonte
1

Questo dipende strongmente da cosa ti serve. Senza conoscere la tua situazione ti suggerirei di considerare quanto segue:

  • Utilizza un framework di registrazione che consente a un messaggio di essere più importante di un altro. In genere ti interessa ERRORE (davvero pessimo), INFO (come un impulso) e DEBUG (ok, cosa è successo in realtà qui). Anche le dichiarazioni di registro sono con data e ora.
  • Tutte le eccezioni devono essere registrate a livello di ERRORE.
  • Le cose che devi vedere per essere convinto che le cose funzionino bene dovrebbero essere registrate al livello INFO. Non vuoi necessariamente molto qui. Quanto basta per vedere che le cose funzionano senza intoppi.
  • Le cose che devi vedere per capire dove vanno le cose lentamente o il log scorretto al livello DEBUG. Questo può essere molto prolisso poiché lo attivi solo quando hai bisogno di vedere i problemi.
  • Rendi i messaggi autonomi se possibile. Ciò consente di leggere i file di registro più rapidamente.

In questo caso considererei

public void DoSomething()
{ 
    Log.info("DoSomething()");
    var s = new Service();

    Log.debug("First");
    s.First();

    Log.debug("Second");
    s.Second();

    Log.debug("Third");
    s.Third();
}

Ma tu sei l'unico a sapere cosa devi sapere per eseguire il debug di un problema. Molte di queste conoscenze sfortunatamente derivano dal trovarsi in situazioni in cui non ce l'hai. Speriamo che questo eviterà alcuni di loro.

Buona fortuna.

    
risposta data 06.04.2011 - 11:27
fonte
0

Non ci sono regole fisse su questo come Peter ha scritto, Vorrei fare entrambi - inserire alcuni all'interno di ogni singolo metodo e anche prima.

Nell'esempio di codice corrente, se c'è un'eccezione in First (), probabilmente lo sapresti quando non vedi il logger prima di chiamare Second ()

Tuttavia, è possibile accedere a qualcosa in First () per assicurarsi che First () abbia eseguito correttamente l'operazione e quindi passare a Second () e così via

    
risposta data 06.04.2011 - 11:18
fonte
0

Sì, abbastanza soggettivo. Cosa faccio:

  • Registra la voce in un metodo pubblico (con valori param).
  • Esci dal medesimo registro (con valore di ritorno se ce n'è uno).
  • Registra le eccezioni (con l'appropriato i dettagli).

Personalmente ho scoperto che fare più di questo aggiunge più rumore per meno valore. Per esempio. Raramente registro la voce / uscita in metodi privati, I occassionaly registra percorsi imprevisti che possono essere errori ma non sono eccezioni, ma questo è molto raro. Se scrivessi il tuo codice sopra rimuoverò Log("First") etc e inserirò il log nel metodo First() (se fosse pubblico).

    
risposta data 06.04.2011 - 11:24
fonte
0

Update : I'm not asking about verbosity or level, just about placement of the logging statements

Ci dispiace, ma è l'atteggiamento sbagliato. Se non pensi a che stai loggando, allora dove registri non ha importanza. In effetti, puoi inserire le tue dichiarazioni di registrazione ovunque tu voglia, perché non aggiungeranno molto valore.

Prendendo un esempio dal tuo codice:

class Task
{
    public void DoSomething()
    { 
        var s = new Service();
        s.First();
        s.Second();
        s.Third();
    }
}

DoSomething non ha punti decisionali, quindi non ci sono buoni motivi per effettuare il log tra ogni istruzione. Se una qualsiasi delle chiamate al metodo fallisce, ovviamente è importante registrarla. Tuttavia, questo viene tipicamente gestito tramite un blocco catch .

D'altro canto, è di fondamentale importanza sapere quale attività viene elaborata e quale contesto circonda quell'attività (sto assumendo un ID di attività univoco e un utente qui):

class Task
{
    public void DoSomething()
    { 
        log("DoSomething: task " + getId() + " invoked by " + getUser());
        var s = new Service();
    
risposta data 06.04.2011 - 13:36
fonte
0

Preferisco separare la registrazione dal mio codice. Questo dà ad ogni classe un unico motivo per cambiare. La classe di registrazione cambia quando un dev di risoluzione dei problemi richiede più informazioni. Il codice attuale cambia con i requisiti dei suoi stakeholder. Quindi creerei un LoggableService che assomiglierebbe a questo (in C #).

public class LoggableService : Service 
{
  private Logger _logger

  public LoggableService(Args args, Logger logger) : base(args)
  {
    _logger = logger;
  }

  public override void First() {
  {
    LogStart(MethodBase.GetCurrentMethod().Name);
    base.First();
    LogSuccess(MethodBase.GetCurrentMethod().Name);
  }

  public override void Second() {
  {
    LogStart(MethodBase.GetCurrentMethod().Name);
    base.Second();
    LogSuccess(MethodBase.GetCurrentMethod().Name);
  }

  public override void Third() {
  {
    LogStart(MethodBase.GetCurrentMethod().Name);
    base.Third();
    LogSuccess(MethodBase.GetCurrentMethod().Name);
  }    

  private void LogStart(string method)
  {
    _logger.Info($"{method}: STARTED");
  }      

  private void LogSuccess(string method)
  {
    _logger.Info($"{method}: SUCCESS");
  }

}

Quindi quando viene chiamato LoggableService.First , il log mostrerà First: STARTED e First: SUCCESS . DoSomething sarà simile a questo.

public void DoSomething()
{
  var s = new LoggableService();
  s.First();
  s.Second();
  s.Third();
}

Il registro sarà simile a questo.

First: STARTED
First: SUCCESS
Second: STARTED
Second: SUCCESS
Third: STARTED
Third: SUCCESS
    
risposta data 31.08.2018 - 14:29
fonte

Leggi altre domande sui tag