Java FileHandler and rolling log files - java

I understand how the Java FileHandler rolls to the next log file when a particular size is reached. What I want is a little different. I want to use the FileHandler to use the log file with the oldest last written time in the sequence when the program starts.
For example if I have specified to use 5 log files:
mylog.0.log, mylog.1.log...mylog.4.log
If the program last updated mylog.2.log then the next time I start the program I want it to start logging to mylog.3.log.
The problem I am trying to solve is when a user executes the program and something happens they typically restart the program and if mylog.0.log is available it will always use it and not go to mylog.1.log. I lose the information from the previous execution of the program.

Per the documentation for the java.util.logging.FileHandler:
Successively older files are named by adding "0", "1", "2", etc. into the base filename.
Seems to imply that the order will always be the opposite of what you want.
Looks like your only option is to implement a config class to generate the file name you want and pass it to the FileHandler.
You can manually rollover a log file but not in the order your want.

Related

Retrieving previous n lines of log4j specific to one logger class

We implemented a small routine that in case of specific errors we get an email to let us know something happened. It's pretty easy to include some error information in the email but we would like to include what was the previous logged informations when it happened.
At first I tried to retrieve the last lines from the file where the log4j are saved. The problem is that many other threads are working at the same time and I never get relevant informations. Either the buffer doesn't have time to write the logs or something else is faster at writing something else.
Is it possible to add an appender to a specific log4j at runtime to be able to retrieve only those specific logs and only if needed ?
I would like to be able to still log with the usual commands log.error, log.warn... but I want to be able to retrieve the log content in a try/catch situation. something like a memory only buffer appender?
Would that work for all the children loggers ?
Class 1 - call Class 2
Class 2 - call Class 3
Class 3 try/catch an error
log.getLogs returns all logged informations from Class 1..3
Or am I dreaming here ?
We are using Jira and in logs in files, so I guess no query would work.

Detect file changes in Spring Integration

Use case: I want to listen to a file directory, and every time someone makes a change on the file, I want it to start a process.
This is my configuration so far:
<int-file:inbound-channel-adapter directory="${dir}" auto-startup="${auto.startup}" prevent-duplicates="true" filter="inputfilefilter" channel=rulesChannel">
<int:poller fixed-delay="${delay}" />
</int-file:inbound-channel-adapter>
where inputFileFilteris a custom bean and rulesChannel is the processing later.
The inputFileFilter takes an array of files and returns a list of files, sorted on file ending. This seems to be pulling endlessly, and the "prevent-duplicates"-check is done after the filter (i.e. the file is added, but it seems like it's not sent to the rulesChannel).
Anyway, my problem is that I need this whole thing to pick up file changes, not new files. Mainly, it's a configuration file that is being changed every now and then, and I need to update it to keep it in sync.
Yes, this is a horrible solution all over, but it's not really my call, and it seems I have no choice.
Any good ideas?
edit: I've played a bit around with http://docs.spring.io/spring-integration/reference/html/files.html#_watchservicedirectoryscanner to see if I could perhaps copy the class and use it with StandardWatchEventKinds.ENTRY_MODIFY but it doesnt seem to help.
Basically, If I had a good way to just "start a thread and keep it running", I would be fine as well.
What I had to do was implement my own DefaultDirectoryScanner.
It registers a watcher at startup, and checks the watcher when it receives a request from the inbound-channel-adapter through listEligibleItems(..)
To be able to handle two separate file directories, I simply added two different watchers and two different file pollers. This is mainly to ensure readability in the code and to avoid hacking my way around the "directory"-part of the inbound-channel-adapter.

Is it possible to roll over a log fie, without creating a backup?

I would like to create a rolling metrics log file, where metrics data its written to it every few minutes. As a result, the file will get big very fast, but the actually relevant information in it, is just a small 1-hour time window. I want no backups of it.
Using log4j, is there a way to create a rolling appender, without creating backup files every hour?
From docs here you can set MaxBackupIndex is equal to zero
log4j.appender.R.MaxBackupIndex=0
rollOver
public void rollOver()
Implements the usual roll over behaviour.
If MaxBackupIndex is positive, then files {File.1, ..., File.MaxBackupIndex -1} are renamed to {File.2, ..., File.MaxBackupIndex}. Moreover, File is renamed File.1 and closed. A new File is created to receive further log output.
If MaxBackupIndex is equal to zero, then the File is truncated with no backup files created.

Java FileHandler Adding Unnecessary Digit to File Name

I'm working with JUL for my logging (no I can't change that). I've developed a simple wrapper that I pass in the parameters and it creates the FileHandler with the correct format every time so that I don't have to recreate the logging in every project.
My test app functions exactly as intended, but when I import the library into other projects I seem to be getting one (only one so far) unique error: Every single time, it adds a ".0" to the end of the log file.
It does this even when there is no conflicts and the Filehandler has been configured to append to the end an existing file (which it does fine). I've played with various file names, most recently I've been using the simple "mylog.log" and the log file still gets output as "mylog.log.0". I've checked and the fileHandler is being passed the correct file ("mylog.log"), but it isn't logging there.
This does not happen in my logging test, only in the project I actually want to use it in. Even when using the exact same parameters, I get different file names.
Is there some quirk about JUL that I'm missing? Code is very simple. Relevent code:
String logFilePath = directory+name; // directory and name are method arguments
Handler newFileHandler;
File dirFile = new File(directory);
if(!dirFile.exists())
{
dirFile.mkdirs();
}
newFileHandler = new FileHandler(logFilePath, true);
newFileHandler.setFormatter(myformatter);
//... etc
It does this even when there is no conflicts ....
Is that proven with evidence or an assumption? According to the FileHandler documentation:
If no "%g" field has been specified and the file count is greater than one, then the generation number will be added to the end of the generated filename, after a dot.
If there is a conflict and no "%u" field has been specified, it will be added at the end of the filename after a dot. (This will be after any automatically added generation number.)
Note that the use of unique ids to avoid conflicts is only guaranteed to work reliably when using a local disk file system.
A conflict can include opening more than one FileHandler to the same location. You need to verify each of these points. What helps is adding code to grab the RuntimeMXBean and then add a single log statement to record the calling ClassLoader, current thread, runtime name and the start time. The runtime name usually maps to a process id and a host name. Run the program and verify the contents of the file.
The code you have included helps but, you need to include details on how the application is launched and what is included in the logging.properties.
I eventually figured this out and forgot to post the cause.
Two things were at work:
Due to the environment I was in, the "rolling" logging was being activated by some back ground variables I wasn't aware of, hence why the ".0" was being added when it shouldn't have been, but I only saw it once I moved it out of testing and into the actual implementing project.
JUL is ridiculously inflexible in how it works. Really I can't speak poorly enough about it. Anyway, long story short, if rolling logging is enabled it will always append a file number such that the active log ends in ".0". Typically I've used APIs that only had the number on the secondary logs, while the current log would maintain the exact name you gave it - this caused me some trouble as JUL also has no "get current log file" method to get the name of active file, so I needed to create an ugly method that predicted what the name should be based on the parameters, and hope nothing went wrong. As an aside, you cannot change the format of the generation numbers (which also caused me some issue as it was preferred to have the files number 01, 02, ... 10, 11 rather than 0,1,2,...10).

which log4j appender should be considered

I have batch java program. It will run every 1 hour.
I want to know what is the correct log4j appender for following cases:
1) creating a fresh log file every time when the job runs. meaning that log contains for that particular run only and should not contain old run data.
2) maintain same log file for that day. if next day , then create fresh file
Any help please.
RollingFileAppender allows you to define how often you want a fresh log to be created, if you add the append=false parameter, the log will get truncated every time it's opened,
log4j.appender.LOG=org.apache.log4j.RollingFileAppender
log4j.appender.LOG.File=/path/to/your/file
log4j.appender.LOG.layout=org.apache.log4j.PatternLayout
log4j.appender.LOG.MaxFileSize=10MB
log4j.appender.LOG.MaxBackupIndex=5
log4j.appender.LOG.append=false
You can try DailyRollingFileAppender too, which rolls every day by default, if none of those quite fit your needs you can always write your own Appender implementation by extending one of the standard implementations.

Categories

Resources