Skip to main content
edited title
Link
Robert Harvey
  • 200.1k
  • 55
  • 468
  • 679

Automatically Adding custom object-string transformers to a global static list field in my logging parameterslibrary. Is there a better way?

added 327 characters in body
Source Link
makhdumi
  • 145
  • 1
  • 6

I'm writing a central logging library. In it is an AutoLogAttribute method attribute that automatically logs entry/exit of methods and their parameters (automatically serialized) like this:

[AutoLog]
public void GenerateInvoice(string customerId)
{
    ...
}

// Outputs
// af8291: Entering GenerateInvoice with parameters: { customerId: 'GZilla' }
// af8291: Exited GenerateInvoice. Ellapsed time: 480.12 ms

My problem arises when parameters are POJOs that serialize to huge strings.

By default, I want to just ignore any non-primitives and allow users to specify how they'd like serialization to happen.

Importantly, since most objects are POJOs in my case, I can't start requiring extending an interface like ILoggable. Extending ToString() is also undesirable because ideally an object should be reconstruct-able from it.

I was thinking of allowing users to add custom object-string transformers to a global static list field in AutoLogAttribute (e.g. in some initializer code of their app). I know this is a very bad practice. My question is, is there a better way of solving my problem?

public class AutoLogAttribute
{
    // something like this
    public static Dictionary<Type,Func<object,string>> ParameterTransformers { get; private set; }
    ...
}


public class Program
{
    public static void Main(string[] args)
    {
        AutoLogAttribute.ParameterTransformers[Customer.Type] = (c) => c.Id;
        AutoLogAttribute.ParameterTransformers[Order.Type] = (o) => o.OrderNumber;
        ...
    }

    [AutoLog]
    public void ProcessOrder(Customer customer, Order order)
    {
        ...
    }
}

I'm writing a central logging library. In it is an AutoLogAttribute method attribute that automatically logs entry/exit of methods and their parameters (automatically serialized) like this:

[AutoLog]
public void GenerateInvoice(string customerId)
{
    ...
}

// Outputs
// af8291: Entering GenerateInvoice with parameters: { customerId: 'GZilla' }
// af8291: Exited GenerateInvoice. Ellapsed time: 480.12 ms

My problem arises when parameters are POJOs that serialize to huge strings.

By default, I want to just ignore any non-primitives and allow users to add custom object-string transformers to a static list field in AutoLogAttribute (e.g. in some initializer code of their app). I know this is a bad practice. My question is, is there a better way of solving my problem?

public class AutoLogAttribute
{
    // something like this
    public static Dictionary<Type,Func<object,string>> ParameterTransformers { get; private set; }
    ...
}


public class Program
{
    public static void Main(string[] args)
    {
        AutoLogAttribute.ParameterTransformers[Customer.Type] = (c) => c.Id;
        AutoLogAttribute.ParameterTransformers[Order.Type] = (o) => o.OrderNumber;
        ...
    }

    [AutoLog]
    public void ProcessOrder(Customer customer, Order order)
    {
        ...
    }
}

I'm writing a central logging library. In it is an AutoLogAttribute method attribute that automatically logs entry/exit of methods and their parameters (automatically serialized) like this:

[AutoLog]
public void GenerateInvoice(string customerId)
{
    ...
}

// Outputs
// af8291: Entering GenerateInvoice with parameters: { customerId: 'GZilla' }
// af8291: Exited GenerateInvoice. Ellapsed time: 480.12 ms

My problem arises when parameters are POJOs that serialize to huge strings.

By default, I want to just ignore any non-primitives and allow users to specify how they'd like serialization to happen.

Importantly, since most objects are POJOs in my case, I can't start requiring extending an interface like ILoggable. Extending ToString() is also undesirable because ideally an object should be reconstruct-able from it.

I was thinking of allowing users to add custom object-string transformers to a global static list field in AutoLogAttribute (e.g. in some initializer code of their app). I know this is a very bad practice. My question is, is there a better way of solving my problem?

public class AutoLogAttribute
{
    // something like this
    public static Dictionary<Type,Func<object,string>> ParameterTransformers { get; private set; }
    ...
}


public class Program
{
    public static void Main(string[] args)
    {
        AutoLogAttribute.ParameterTransformers[Customer.Type] = (c) => c.Id;
        AutoLogAttribute.ParameterTransformers[Order.Type] = (o) => o.OrderNumber;
        ...
    }

    [AutoLog]
    public void ProcessOrder(Customer customer, Order order)
    {
        ...
    }
}
deleted 3 characters in body
Source Link
makhdumi
  • 145
  • 1
  • 6

I'm writing a central logging library. In it is an AutoLogAttribute method attribute that automatically logs entry/exit of methods and their parameters (automatically serialized) like this:

[AutoLog]
public void GenerateInvoice(string customerId)
{
    // Execution...
}

// Outputs
// af8291: Entering GenerateInvoice with parameters: { customerId: 'GZilla' }
// af8291: Exited GenerateInvoice. Ellapsed time: 480.12 ms

My problem arises when parameters are POJOs that serialize to huge strings.

By default, I want to just ignore any non-primitives and allow users to add custom object-string transformers to a static list field in AutoLogAttribute (e.g. in some initializer code of their app). I know this is a bad practice. My question is, is there a better way of solving my problem?

public class AutoLogAttribute
{
    // something like this
    public static Dictionary<Type,Func<object,string>> ParameterTransformers { get; private set; }
    //...
}


public class Program
{
    public static void Main(string[] args)
    {
        AutoLogAttribute.ParameterTransformers[Customer.Type] = (c) => c.Id;
        AutoLogAttribute.ParameterTransformers[Order.Type] = (o) => o.OrderNumber;
        ...
    }

    [AutoLog]
    public void ProcessOrder(Customer customer, Order order)
    {
        // Execution...
    }
}

I'm writing a central logging library. In it is an AutoLogAttribute method attribute that automatically logs entry/exit of methods and their parameters (automatically serialized) like this:

[AutoLog]
public void GenerateInvoice(string customerId)
{
    // Execution
}

// Outputs
// af8291: Entering GenerateInvoice with parameters: { customerId: 'GZilla' }
// af8291: Exited GenerateInvoice. Ellapsed time: 480.12 ms

My problem arises when parameters are POJOs that serialize to huge strings.

By default, I want to just ignore any non-primitives and allow users to add custom object-string transformers to a static list field in AutoLogAttribute (e.g. in some initializer code of their app). I know this is a bad practice. My question is, is there a better way of solving my problem?

public class AutoLogAttribute
{
    // something like this
    public static Dictionary<Type,Func<object,string>> ParameterTransformers { get; private set; }
    //...
}


public class Program
{
    public static void Main(string[] args)
    {
        AutoLogAttribute.ParameterTransformers[Customer.Type] = (c) => c.Id;
        AutoLogAttribute.ParameterTransformers[Order.Type] = (o) => o.OrderNumber;
    }

    [AutoLog]
    public void ProcessOrder(Customer customer, Order order)
    {
        // Execution
    }
}

I'm writing a central logging library. In it is an AutoLogAttribute method attribute that automatically logs entry/exit of methods and their parameters (automatically serialized) like this:

[AutoLog]
public void GenerateInvoice(string customerId)
{
    ...
}

// Outputs
// af8291: Entering GenerateInvoice with parameters: { customerId: 'GZilla' }
// af8291: Exited GenerateInvoice. Ellapsed time: 480.12 ms

My problem arises when parameters are POJOs that serialize to huge strings.

By default, I want to just ignore any non-primitives and allow users to add custom object-string transformers to a static list field in AutoLogAttribute (e.g. in some initializer code of their app). I know this is a bad practice. My question is, is there a better way of solving my problem?

public class AutoLogAttribute
{
    // something like this
    public static Dictionary<Type,Func<object,string>> ParameterTransformers { get; private set; }
    ...
}


public class Program
{
    public static void Main(string[] args)
    {
        AutoLogAttribute.ParameterTransformers[Customer.Type] = (c) => c.Id;
        AutoLogAttribute.ParameterTransformers[Order.Type] = (o) => o.OrderNumber;
        ...
    }

    [AutoLog]
    public void ProcessOrder(Customer customer, Order order)
    {
        ...
    }
}
added 22 characters in body
Source Link
makhdumi
  • 145
  • 1
  • 6
Loading
Source Link
makhdumi
  • 145
  • 1
  • 6
Loading