Including log file name in log entry in Log4j - java

I have a requirement to include the name of the log file in the log entry itself.
For example say final name of the log file is something like trx_log.2014-09-22-12-42 the log entries I'm printing that log should have that same name. Following is a example log entry.
123456|test value|xyz|trx_log.2014-09-22-12-42
I'm using Log4j DailyRollingFileAppender to print the log at the moment. Is there a way which I can get this requirement implemented using some log4j/logback configuration.

Not that I'm aware of.
But a solution does exist nevertheless: write your own custom extension of the DailyRollingFileAppender.
Please note though the filename will be available to your custom appender only: in case you want to use such information in another appender (the only use case I can think of this might be of any use) then you need a more convoluted solution using a shared data storage (shared memory, file system, database, whatever) with the simplest solution being a static member of your just made appender. In this case the other appender (lat's say Console) need to be extended as well in order to append the new information to the log statement.

Use this method logger.getName()
logger.log(Level.SEVERE,"Exception in "+e.getMessage()+logger.getName());

Related

Log all program console output to file on demand

I have a task to implement a logging method that will take all program content up to logging method call and save it to file. The method should not overwrite already present info in file, but rather add new content to it.
What I need to write:
all program messages and output;
all user inputs in the way they appear on console (the program inquires it several times);
My thought on it is to create a StringBuilder object and start appending everything to it. Once logging method is invoked, ask for a file to save log to and save contents of StringBuilder to it. Then flush StringBuilder and continue to gather information. On second invocation, if the same filename is provided, just append new info gathered by StringBuilder.
However, this means that I will need to place gathering invocations all over the place where program output and user input are. Seems like not very optimal to me.
Are there any ideas on how to reach my goal differently and more optimally?
Thank you in advance.
Best regards,
Vadim
UPDATE: I actually was able to redirect system.out to gather everything to ByteArrayStream and then write to file on demand. But I still don't understand how to do it for inputstream. I don't need to redirect it, I still have to input eveyrthing from keyboard, it's just values that have to make it to logs in correct places. Am still searching for a solution.
Do not reinvent the wheel. Go for a logging framework. There is one integrated into java anyway.
Alternatively you can use log4j, and there are other such frameworks out there.

slf4j logger info format

I'm trying to generate a 'nice' log message with using escaping characters or an xml pattern etc.
What I'd like to output is something along the lines of:
ABAS : value
B : value
Cse : value
I've achieved this using \t but I figure there must be a cleaner way. I've looked at .info which takes an argument and using the {} as a way of inserting the values but I can't seem to find out how to add the line breaks or tabbing.
so far I have
logger.info(A : {} \nBasdas : {} \nC : asds ) and so on.
thanks for any help.
slf4j is the log frontend and only intended to provide log level, message etc. to the backend, most likely logback in your case. You shouldn't format your messages in the frontend expecting any special format in the actual log output, because exactly that can be somewhat freely configured by the backend one uses. Especially indentation over some independent lines doesn't work, because you can't know how lines start, if your logger names are part of lines, where the msg is printed within a line and all that stuff. Just look at the logback configuration and what is possible, how do you want to tell as the log message issuing programmer which of those possibilities are used during runtime in any environment of your software? You simply can't and therefore shouldn't assume too much.
So what you want is simply not possible, besides embedding tabs or newlines there's nothing to format log messages in slf4j for a good reason. And you can't count on your tabs as well, because how those are presented to a user looking at your log file depends totally on the text editor or whatever one uses. It may even convert tabs to spaces, show them with a width of 1 or 10 or whatever.
Log statements spanning multiple lines may be considered bad practice at all.

Multiple logs files with muptiples levels automatically

I've searched online for a solution and haven't found anything.
My problem is:
Have a game with lot of rooms. There's a chatroom inside of every room. I need to create a LOG of those rooms in different files with LOG4J.
I don't want to create an appender for every room that have been created. I need a automatically way to create a log file per room.
Is there any way to do that?
Log4J can create different log files for different classes using nothing but the log4j configuration file. If the rooms are instances of one or more classes, you'll have to handle it through your code. One possibility is to create a logger in the constructor and point it to a unique temp file so that each room that is constructed gets its own log file. I do not know how you make it easy to identify a room with a file other than forcing output as the first line. That might work but would still make it hard to identify the correct file just by the name. If the rooms have something unique about them you could try to use that as the log file name but without code from you I'd be guessing how you could do that.

Obtain last 500 logged messages

We are using SLF4J/Logback combination to perform our logging. One of the requirement we have is if anything fails, send an email to support/dev group with last 500 logged messages.
I was trying to go through the documentation, but haven't found anything relevant.
One of the approach, I can think is obtain the current log file name, read the file and send last 500 records. But I dont know how to get the current log file name. anyone knows how to? or any other better option to retrieve the log tail?
Thanks
It sounds like Log4j's SMTPAppender has the features you require. You could look at its source code as model to guide your own implementation if Logback lacks a similar appender (which would be somewhat surprising).
Essentially, this email appender has a ring buffer of log events. When a triggering event occurs (by default, an event at ERROR level or worse), the buffer is flushed to an email and sent.
Create a custom Appender that would cache the last 500 log messages. You may extend the SMTPAppender to shoot the email by reading the contents from this cache.
start here

Mask Passwords with Logback?

We currently generically log all XML documents coming in and going out of our system, and some of them contain passwords in the clear. We would like to be able to configure the logback logger/appender that is doing this to do some pattern matching or similar and if it detects a password is present to replace it (with asterisks most likely). Note we don't want to filter out the log entry, we want to mask a portion of it. I would appreciate advice on how this would be done with logback. Thanks.
The logback version 0.9.27 introduced replacement capability. Replacements support regular expressions. For example, if the logged message was "userid=alice, pswd='my secret'", and the output pattern was
"%d [%t] $logger - %msg%n",
you just modify the pattern to
"%d [%t] $logger - %replace(%msg){"pswd='.*'", "pswd='xxx'"}%n"
Note that the above makes use of option quoting.
The previous log message would be output as "userid=alice, pswd='xxx'"
For blazing performance, you could also mark the log statement as CONFIDENTIAL and instruct %replace to perform replacement only for log statements marked as CONFIDENTIAL. Example,
Marker confidential = MarkerFactory.getMarker("CONFIDENTIAL");
logger.info(confidential, "userid={}, password='{}'", userid, password);
Unfortunately, the current version of logback does not yet support conditional replacements (based on markers or otherwise). However, you could easily write your own replacement code by extending ReplacingCompositeConverter. Shout on the logback-user mailing list if you need further assistance.
I believe Masking is an aspect of your business, not the aspect of any technology or logging system. There are situations where the passwords, national identities etc should be masked while storing them in the DB as well due to legal reasons. You should be able to mask the xml before giving it to the logger.
One way to do it is to run the XML through XSLT that does that making and then give it to logger for logging.
If you doesn't want to do this then LogBack has Filters support that is one of the option (not the right one though).
But understand that any generic out of the box solution you are trying to find at the logging infrastructure level is going to be suboptimal as every log message is going to be checked for masking.

Categories