I am aware that MDC is provided by Log4j and is used for the purpose of grouping the related log messages together aiming easier debugging.
But, should MDC only used for that purpose? Is it considered to be a bad practice if I use MDC for keeping small business information in the executing thread. ?
I don't know your scenario. It sounds like you're using MDC for something it is not made for. Except you want to use those business information for log purposes.
There are many ways to keep data in you application. Making a custom ThreadLocal / custom context.
Take a look at Baeldung - ThreadLocal.
Related
how do you go about structuring logging in your java projects?
I have used log4j2, logback etc, however this is not a question about libraries but about setup and best practices.
I have tried:
in filter
but it does not have enough detail. For example i cannot log method calls, input/output values in methods etc. Also it does not feel good when i need detailed logs of user activities.
in each class
In each class, a static field for the logger, then in methods where needed i log what i need to. This way i have all the detail i want, but it's a lot pf work and it feels like the code is littered with log stuff.
What do you use in your projects?
Thanks
I generally go with a similar approach to that of using static loggers in Class, but with a twist. Generally, I use only one static logger and a collection of Aspects. When a method requires to be logged, and usually it's input/output that needs to be logged, I simply use an #Around aspect. This keeps your code clean and separates the concerns of business logic with the concerns of the programmer (logging).
Here's a great place to start: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
In my application, I am using Log4j2 in Async mode (Async logger using Disruptor), can some one pls tell me how to handle an exception that happens in the logging process. Logging is very critical for my application, I don't want to miss a single log statement. If something goes wrong with logging, that needs to be alerted immediately.
As per Apache Log4j page, suggests to use ExceptionHandler, but I couldn't find a helping topic on how to use this.
Error handling. If a problem happens during the logging process and an
exception is thrown, it is less easy for an asynchronous logger or
appender to signal this problem to the application. This can partly be
alleviated by configuring an ExceptionHandler, but this may still not
cover all cases. For this reason, if logging is part of your business
logic, for example if you are using Log4j as an audit logging
framework, we would recommend to synchronously log those audit
messages. (Note that you can still combine them and use asynchronous
logging for debug/trace logging in addition to synchronous logging for
the audit trail.)
Waiting for suggestions.
I suggest first trying to implement a simple class that implements the ExceptionHandler interface and confirm that it gets called when a problem occurs. Once this is confirmed you can move on to implementing your custom fallback mechanism.
Secondly, it may be difficult to develop a robust fallback: your fallback may not be able to write to disk if the reason why log4j failed was that the disk is full or damaged. Similarly you may not be able to make a network connection... I suggest that your fallback incorporates multiple options to increase the probability of one of these options succeeding.
Hardware is cheap, so consider adding a separate network card or a separate hard disk for your fallback mechanism. Don't forget to send notifications if the fallback mechanism is used so you can address the original problem.
Depending on how mission-critical this is you may want to investigate vendor products that give high availability - this usually covers more than just logging, not sure what your needs are here.
I am having a fairly large legacy (swing) application and currently brainstorming and evaluating the strategies to add logging in it.
Key point is that it's fairly large (like I said above) and thinking what could be the strategy to do it quickly and completely (100% coverage for argument sake) (let's say logging is no customer facing core business functionality, so let's say not getting paid for it)
So the two strategies as such are -
Do use log4j2 add the debug statements, add appenders, file rolling rules, add dynamic on/off and change of log levels etc and thus do it the way it ideally should be done.
Use AOP to define endpoints and advices declaratively/programmaticly. Device such elaborate rules, add in the rest of the part (appenders, rolling rules etc.) and thus wont be touching each and every file and adding a revision just for that.
The second strategy is what I want to explore if someone has experience with, if somebody has gone that route.
The cons I can think of -
No standard / convention in apps, would be 99% impossible to define endpoints completely
Sphagetti and unmaintainable code in AOP module above, largely a result of the above problem
Adding same and matching set to logging to future classes.
Can you guys suggest me wither ways
While I am a big proponent of refactoring and clean code, I suggest you use AspectJ to add logging and see how far you get. Probably you will be surprised by how much logging you get with a little aspect.
IMHO logging is a cross-cutting concern and not core functionality. I would try to avoid logging in my core code. My expecience with AspectJ is only positive, I warmly recommend it. You should take some time to get acquainted with its power, though.
If you need something like a call trace (maybe neatly indented) or just plain method call logging with parameters and maybe return values, you will get quick results with AspectJ without cluttering your application code. The aspect can always be improved and maintained in a single spot, which is very clean. No need to be afraid of spaghetti aspect code. It will not happen if you don't totally abuse AspectJ.
You will only run into problems if your core code is already spaghetti code and you have very long methods which need log statements inside those methods and not around them. Then you might need to refactor and break down monster methods into smaller ones. But that is a problem no matter which logging approach you choose. My own experience with ugly legacy code and AspectJ-based logging tells me that it helps a lot because even spaghetti code calls other methods and that can be nicely traced in AspectJ.
I m in a project which my co-workers want to use log4cpp, log4php or log4j for flow control, ie: they want to log things, parse it and then flow control based on that information.
I told them that log4X should only be used to log, report errors and run time information.
How can I convince them not to use log4cpp or log4php or any log4x for flow control?
or do you think there is nothing wrong with this?
Sounds like a classic case of using the wrong tool for the job. There are many ways to do flow control and even whole servers for that purpose. Mule, IBM Message Broker to name a couple. As you say, LogX is for logging. The concept of trying to base the flow of messages, execution or whatever on the parsed output of a logger is so far wrong I cannot even begin to figure out why anyone would suggest such as bad idea, never mind adopt it. And there are so many ways to screw it up too. Never mind the fact of how do they intend to do real logging if their logging framework is not being used for it.
It never ceases to amaze me how often people in IT manage to make such decisions.
After reviewing the AOP pattern, I'm overwhelmed with the ways of how and what to use it for in my spring project.
I'd like to use it as audit log system of all the financial business logic. It just seems to be easy to integrate. But I'd like to hear your take on this.
The question is - what other uses should I consider that are common for this pattern? I would not mind refactoring my current logic to be used with AOP as long as there is benefits to it.
The most common usage is where your application has cross cutting concerns i.e. a piece of logic or code that is going to be written in multiple classes/layers.
And this could vary based on your needs. Some very common examples of these could be:
Transaction Management
Logging
Exception Handling (especially when you may want to have detailed traces or have some plan of recovering from exceptions)
Security aspects
Instrumentation
Hope that helps.
Besides logging/auditing and declarative transaction handling as mentioned by Axel, I would say another usage of AOP is as a request interceptor. For example, let's say you need all requests coming of a server to be intercepted so that you can do something with it (may be to keep track of which app is sending what request to what other app or what database, etc).
The most common use is probably the declarative transaction handling using #Transactional.
Using AOP for audit logging is a perfectly valid use of AOP. You can turn it off for testing and change it as requirements change in production.
The only downside in this case is if you were planning on doing the audit log via SQL. It may be more performant to implement this kind of auditing as triggers directly in the DB.
You can use AOP for your security concerns, for example allow/disallow method access. Another usage of aop is to test your application performance.
It can be used to expose custom metrics (Instrumentation of service) for Alerting and Monitoring of service using client libraries like dropwizard, prometheus.
It helped us, to
Keep this instrumentation code (Not a business logic) outside of actual business logic
Keep these cross-cutting concerns at one single place.
Declaratively apply them wherever required.
For example,
To expose
Total bytes returned by REST AIP - (Can be done in after advice)
Total time taken by REST API i.e server-in and server-out rime- (Can be done using around advice).
As an answer slightly different from what #Axel said, using it to automatically intercept all of your data access calls and apply transactions appropriately is phenomenal. I have mine set up to implement all calls to my dao package that don't start with "get" in a transaction and then anything performed in a method starting with "get" is treated as read only. It's fantastic because aside from the initial setup, I don't have to worry about it, just follow the naming convention.