Ewerton
Ewerton

Reputation: 4533

How to log the "path taken" by the code and its exceptions

I have a requirement of compose the log message through the path taken by a code in a user click. Let me give an example:

Imagine the classical example: A user clicks in a button in a View, that calls code from the Business Layer that call code from Data Access Layer, that returns data to the Business, that return to a View. I want to compose my log message through these layers. The caller method (in a View) that started the whole process will receive the full message. Here are some code sample just to help me explain what i am trying to achieve.

public void ViewMethod()
{
    try
    {
        BusinessMethod();           
    }
    catch (Exception ex)
    {
         Logger.Enqueue("exception occurred");
         Logger.Print();
    }
}

public void BusinessMethod()
{
    try
    {
        DataAccessMethod();
    }
    catch (Exception ex)
    {
         Logger.Enqueue("Exception occurred in the business method")
    }
}

public void DataAccessMethod()
{
    try
    {
        // some code that executes an SQL command
        // Log the SQL Command 1
        // Log the SQL Command 2 and do on...
    }
    catch (Exception ex)
    {
         Logger.Enqueue("Error occurred, SQL executed is ...", sqlExecuted);
    }
}

EDIT: The reason I need this is that I need to log all the SQL's executed in the whole process. If an error occurs in any point of the whole process, the user cant be warned, I need to store as much as possible information because the support technician will need it later.

My question is if there is any design pattern to develop it or passing a Logger reference across the "layers" are acceptable?

Upvotes: 1

Views: 108

Answers (1)

T.S.
T.S.

Reputation: 19386

I would do something like this

public class Context
{
     [ThreadStatic]
     private static LogStore _store; 
     
     public static Log(....)
     {
         .....
     } 
}


public void ViewMethod()
{
    
    var response = BusinessMethod();        

    if (response.Status = ResponseStatus.Success)
        // do something with response.Data
    else
        // show message?
}

public BusinessMethodResponse BusinessMethod()
{
    
    var response = new BusinessMethodResponse() {Status = ResponseStatus.Failure};
    SomeData data;

    try
    {
        data = DataAccessMethod();
    }
    catch (Exception ex)
    {
        Context.Log(....);
        response.Message = "Data retrieval failed";
        return response;
    }
    try
    {
        // massage the data here
        response.Status = ResponseStatus.Success;
        response.Data = myMassagedData;
    }
    catch (Exception ex)
    {
         Context.Log(....);
         response.Message = "Something failed";
    }
    
    return response;
}

public void DataAccessMethod()
{
    // some code that executes an SQL command
}

What this do? Now you can call your business objects from MVC, WPF, WinForms, Web Forms, etc...

Upvotes: 1

Related Questions