How to enable logging for a single user in a Java Service at runtime
Preamble -
I am running an online Java Application(Tomcat->Java->Mysql) as SAAS (Software As A Service). This is basically a mobile utility service where a user connects to our service/server using his mobile phone and the data transfer happens once the user is authenticated. The service is run on a Data Center with app s开发者_Python百科ervers being served the requests by a load-balancer and so on. Live updates of our application happen by adding and removing servers, diverting the requests by the load-balancer, without actually taking the service fully down.
Scenario -
From the logs, I can understand that there are at least ten thousand users connected to the service all the time. So taking the service down for an upgrade is not practical. I do use a lot of in memory cache using Java's APIs(like HashMap, ArrayList etc). I am yet to use Caching frameworks like memcache or so. Also people connect to this service using a plethora of Mobile Phones and we are finding it very difficult to support all of them.
Use case
When a user complaints that the service is not working for them, we need to enable logging for him(AND HIM ALONE AND NOT FOR OTHERS) to find what goes wrong at his end. Remember that his client is a cellphone, and as this is an online service, we cannot just enable logs in our server and it will be enabled for all the users and our logs will roll-over in no time or the user's data will not be easily traceable in the gamut of text churned out by the logger. Also I cannot request for a screen shot(though a few cellphones have this feature, majority lacks it and they are the ones that makes trouble) for client side errors, I am not able to see what happens on their mobile client. So things need to be done on a live server, while other users continue unaffected.
What are the different ways where I can enable logging for only one user by supplying some parameter at run-time which enables logging for them at will (when they are actually connected to the server)
Simple things I tried hastily
1) Keep a single column table, which is initially empty and when some user says that the service is not working for him, add his username in the table. A thread which scans the table at a specific interval will get the username and starts printing the user specific logs. Remove the entry once the logs are printed. But I need to wait till the thread comes and does the action. Also as a policy, we are not supposed to spawn/run other threads than the request-response thread.
2) Keep an empty file and add entry in it and follow the same way as in db table mentioned in point 1
3) Issue a request to a admin authenticated private Servlet(users cannot access this, only internal IPs are allowed) and pass the username which is to be logged as a param-value and later invoke it again to remove the user
any other/better ways?
PS. Using java.util.logging.Logger as logger
High level overview
- start of request detect if belongs to users who needs to be logged
- set thread local to true.
- logger should check thread local for current level.
- process request...
- end of request clear thread local.
精彩评论