Search code examples
javalogging

Track object status by only logging tainted fields


When I am developing complex logic across multiple classes, I often log entities (often with toString() underneath) to check the status of the object, which field has what value. I always find logs unnecessarily verbose, printing all fields. It is hard to track:

  • what has been changed and
  • when it is changed

when an entity goes a long way through a bunch of classes.

I would like to see only "tainted" fields (the fields which are already changed/set before reaching the logging line of code). I imagine a solution like this:

  • set a value to a field
  • add this field to a map, for example taintedFields; key is field name and value is actual value. Ideally, do this in every setter. Better yet, an abstract class with such setter template as base class for all model classes/DTOs, so that every setter would do super.tainted(field, value) before setting the value
  • when printing, only print this map; other null/empty values are ignored

The idea is not hard to implement, but I wonder is this practical? Is it good practice? Is there any existing solution? I cannot be the first person ever to think about this. Any better way to do it?

Last edit:

I understand the reason why this question is closed and I am OK with that, it has no fact based answer but here is the only place I can think of to collect opinions about it.

At last I think this is valid idea but several difficulties may be encountered:

  • add a base class for all model/DTOs classes is much work in a big project; maybe create a super class and inherit when needed; or an annotation?
  • reflection is inevitable, as we want to make every existing and newly added fields in the future to be able to mark status of tainted or not; so a map with keys of fields name is needed
  • maybe furthermore, not only tainted or not, but also when and where(in which class, which method and on which line) it is changed is also desirable to include in some log lines; but this is beyond simple code change; interceptors may be needed(but aroundInvoke only works when entering and exiting method, still cannot detect what happens in between lines)

Solution

  • The idea of tracking changed fields can be practical especially in complex logic, and you are right your idea is easy to implement but it is important to test it for performance issues since you are going to add another layer of complexity to your codebase and would add more hard work to the maintenance of your application.

    I usually depend on debugging remotely and locally most of the time and i rarely use logs for testing.

    I know in the other hand that debugging work best on objects and logic layer and its difficult to use it in other layer such as persistence or with middleware when working on big complex projects.

    So what I propose is you can use your method on certain critical logic to get real time results but I recommend using unit testing with Mockito it is really helpful to mock your services and injecting directly your values without doing the business logic again and you can use DiffBuilder class to track differences between objects.