Ron McLeod wrote:Are you asking how you update your source code?
If you are using an IDE for your development work, it most likely has a search/replace capability to do what you want.
Kundan Dee wrote:I can't do search and replace for 1000s of unique strings in my ide that's why I turn to regex
The secret of how to be miserable is to constantly expect things are going to happen the way that they are "supposed" to happen.
You can have faith, which carries the understanding that you may be disappointed. Then there's being a willfully-blind idiot, which virtually guarantees it.
Tim Holloway wrote:Welcome to the Ranch, Kundan!
You didn't actually say which of the several popular loggers you're using, but it's a general question, so I'll answer it in general form.
First of all, the "className" part of the Logger.info() isn't actually a class name, it's a logger name. Typically the name of the logger for that class is its fully-qualified class name, but as an example, Hibernate also uses logger names that cover a particular function over multiple classes, so the logger might be named something like "org.hibernate.sql".
Secondly, I think some loggers at least can print the thread ID automatically if you set up the appropriate options in their log output channels ("appenders" in log4j). So check. You might not need to alter statements. They will also report the line number of the log statement, again, if you have the proper log format string set up.
Thirdly, if you absolutely positively MUST do a global search-and-replace over a source code subtree, the Eclipse IDE can do that.
Although there are times when I just brute-force it using a quick-and-dirty Perl script or something like that.
The secret of how to be miserable is to constantly expect things are going to happen the way that they are "supposed" to happen.
You can have faith, which carries the understanding that you may be disappointed. Then there's being a willfully-blind idiot, which virtually guarantees it.
Ron McLeod wrote:With Eclipse you can search and replace (using regex) in files doing something like this.
![]()
![]()
Regular expression: Logger.info\(className, (.*) \+ "(.*)" \);
Replacement: Logger.info(className, $1 + "$2" + " [" + Thread.currentThread().getStackTrace()[1].getLineNumber() + "]");
The secret of how to be miserable is to constantly expect things are going to happen the way that they are "supposed" to happen.
You can have faith, which carries the understanding that you may be disappointed. Then there's being a willfully-blind idiot, which virtually guarantees it.
Kundan Dee wrote:Can you club all that into a single group? A single group would be better.
Ron McLeod wrote:
Kundan Dee wrote:Can you club all that into a single group? A single group would be better.
It might be possible, but without any specifics its impossible to answer.
Tim Holloway wrote:You can do all sorts of things with regexes. The question is whether you should.
I've used this Eclipse feature, and I find it better to make several small regex changes rather than one does-everything change. Regexes can be treacherous and it allows me to limit damage and roll it back while keeping the earlier changes that worked OK.
Carey Brown wrote:The "((.*)+)" probably should be just "(.+)"
Kundan Dee wrote:I think i got it to work ... Please feel free to suggest any improvements!
Ron McLeod wrote:
Kundan Dee wrote:I think i got it to work ... Please feel free to suggest any improvements!
Well, you haven't provided any real data to work with, so that makes it difficult to offer much of an opinion.
I did take your regular expression: Logger.([a-z]+)\(([a-z]+),((.*)+)\);
and tested it against the only sample data you have shared: Logger.info(className, dasd + "sadsd" );
and it failed to match.
I used the RegexPlanet online tool to check:
![]()
Ron McLeod wrote:
Thread.currentThread().getStackTrace()[1].getLineNumber() will be called regardless of what level you have the logging set to
Ron McLeod wrote:Something else to consider — when you call the logger like this:
Thread.currentThread().getStackTrace()[1].getLineNumber() will be called regardless of what level you have the logging set to (including higher levels like: warn, error, fatal), and that kind of call will be fairly expensive performance-wise.
One way to deal with that would be to check if logging at the wanted level is enabled before trying to get the line number:
Another, if the Logger supports it, would be to provide a Supplier:
Carey Brown wrote:
Ron McLeod wrote:Something else to consider — when you call the logger like this:
Thread.currentThread().getStackTrace()[1].getLineNumber() will be called regardless of what level you have the logging set to (including higher levels like: warn, error, fatal), and that kind of call will be fairly expensive performance-wise.
One way to deal with that would be to check if logging at the wanted level is enabled before trying to get the line number:
Another, if the Logger supports it, would be to provide a Supplier:
WARNING! DANGER WILL ROBINSON!
If you do a global replace and don't address this issue you'll bring your whole app to its knees.
Kundan Dee wrote:Why is that?
Ron McLeod wrote:
Another, if the Logger supports it, would be to provide a Supplier:
Ron McLeod wrote:
Kundan Dee wrote:Why is that?
Because the Logger.info method will be called regardless of the current logging level AND the argument expressions will evaluated (which includes calling Thread.currentThread().getStackTrace()[1].getLineNumber()) before calling the Logger.info method.
Carey Brown wrote:If you use Supplier, exactly what line number will you get?
Kundan Dee wrote:
Carey Brown wrote:If you use Supplier, exactly what line number will you get?
I don't understand the question.
I'll get the same line as before from where I'm calling the logger.
That's what I thought but running my code snippet showed that the line number was correctly generated at the ()->... and NOT inside the logInfo method. I even traced it with a debugger and was surprised to see the logInfo() execution jump briefly back to the ()->... before returning to logInfo() to print the message. Knock me over with a feather. Learned something new.Ron McLeod wrote:Calling getStackTrace() is a special case and you would need to be aware that using a supplier would add 2 more stack trace elements to the the stack dump.
So: Thread.currentThread().getStackTrace()[3].getLineNumber() instead of Thread.currentThread().getStackTrace()[1].getLineNumber().
Ron McLeod wrote:Calling getStackTrace() is a special case and you would need to be aware that using a supplier would add 2 more stack trace elements to the the stack dump.
So: Thread.currentThread().getStackTrace()[3].getLineNumber() instead of Thread.currentThread().getStackTrace()[1].getLineNumber().
Here's a quick (so-so) example showing how the expensive call would be made whether logging was enabled or not:
Note that I added another element to the stack because I called a method named getLineNumber and not getStackTrace directly. I did this so that I could show that a call to getStackTrace was actually made.
Ron McLeod wrote:Calling getStackTrace() is a special case and you would need to be aware that using a supplier would add 2 more stack trace elements to the the stack dump.
So: Thread.currentThread().getStackTrace()[3].getLineNumber() instead of Thread.currentThread().getStackTrace()[1].getLineNumber().
Kundan Dee wrote:Sadly, I didnt really get the point you were trying to make ...
Which works perfectly well but makes the global replace very tedious.Ron McLeod wrote:This example:
Ron McLeod wrote:
Kundan Dee wrote:Sadly, I didnt really get the point you were trying to make ...
The point is that if you evaluate the line number in the call to Logger.info, then getStackTrace will be always be called, whether tracing is enabled or not.
If the logger doesn't support providing a supplier, then just wrap you calls to the logger with a check to see if logged is enabled. This example:
I consider "milliseconds" to be expensive, but if that's ok with you.Kundan Dee wrote:I tried running Thread.currentThread().getStackTrace()[1].getLineNumber() in a loop to check timings for 5000 runs and its in milli seconds which is currently acceptable.
Carey Brown wrote:
I consider "milliseconds" to be expensive, but if that's ok with you.Kundan Dee wrote:I tried running Thread.currentThread().getStackTrace()[1].getLineNumber() in a loop to check timings for 5000 runs and its in milli seconds which is currently acceptable.
Evil is afoot. But this tiny ad is just an ad:
Low Tech Laboratory
https://www.kickstarter.com/projects/paulwheaton/low-tech-0
|