Spring 統合で構成された Spring バッチ アプリケーションで、複数行のログ メッセージを単一のメッセージとして読み取る問題に直面しています。このアプリケーションは、複数行のログ メッセージ (例外スタック トレースの例) を単一のメッセージとして読み取る必要があり、後で処理する必要があります。さらにインデックスを作成するためにメッセージを分類します。各行はそのタイムスタンプ (上記のパターン、つまり DATE_PATTERN) によって識別され、複数の行が続く場合があります。2 行目が preProcess メソッドに到達したときに SimpleRecordSeparatorPolicy から isEndOfRecord メソッドをオーバーライドして、別のタイムスタンプが表示されるまでメッセージを読み続けようとしています。 isEndOfRecord は true ですが、これは期待どおりに機能していません。タイムスタンプ パターンを特定して、上記のログ ファイルを読み取るのを手伝ってくれる人はいますか?
org.springframework.batch.item.file.FlatFileItemReader と org.springframework.batch.item.file.mapping.PassThroughLineMapper をマッパーとして使用しています。
完全なメッセージについては、 を参照してください。
1) ログメッセージファイル:sample-message-test.log
2013-10-19 07:05:32.253 [My First Class..] LOG LEVEl first-message-line-1 first-message-line-1 first-message-line-1 first-message-line-1 first-message-line-1 first-message-line-1
first-message-line-2 first-message-line-2 first-message-line-2
first-message-line-3 first-message-line-3 first-message-line-3
first-message-line-4 first-message-line-4 first-message-line-4
first-message-line-5 first-message-line-5
first-message-line-6
2013-10-19 07:05:32.257 [My Second Class..] LOG LEVEl second-message-line-1 second-message-line-1 second-message-line-1 second-message-line-1 second-message-line-1 second-message-line-1
second-message-line-2 second-message-line-2 second-message-line-2
second-message-line-3 second-message-line-3 second-message-line-3
second-message-line-4 second-message-line-4 second-message-line-4
second-message-line-5 second-message-line-5
second-message-line-6
2013-10-19 07:05:32.259 [My Third Class..] LOG LEVEl third-message-line-1 third-message-line-1 third-message-line-1 third-message-line-1 third-message-line-1 third-message-line-1
third-message-line-2 third-message-line-2 third-message-line-2
third-message-line-3 third-message-line-3 third-message-line-3
third-message-line-4 third-message-line-4 third-message-line-4
third-message-line-5 third-message-line-5
third-message-line-6
2) バッチ設定ファイル
<batch:job id="fileReadingJob">
<batch:step id="flatFileReadingStep">
<batch:tasklet >
<batch:chunk reader="reader" writer="writer" commit-interval="10" />
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.PassThroughLineMapper"/>
</property>
<property name="bufferedReaderFactory">
<bean class="org.springframework.batch.item.file.DefaultBufferedReaderFactory"/>
</property>
<property name="recordSeparatorPolicy" >
<bean class="com.batchlog.explorer.batchio.FlatFileRecordSeperationPolicy"/>
</property>
<property name="resource" value="file:///#{systemProperties['logfolder']}/#{jobParameters['inputfile']}" />
</bean>
<bean id="writer" class="com.batchlog.explorer.batchio.FlatFileWriter" scope="step"/>
........
3)
public class FlatFileRecordSeperationPolicy extends SimpleRecordSeparatorPolicy {
public static final String STARTING_OF_THE_LINE = "-STARTING_OF_THE_LINE-";
public static final String CONTINUATION_OF_THE_FILE = "-CONTINUATION_OF_THE_FILE-";
public static final String END_OF_THE_LINE = "-END_OF_THE_LINE-";
public static final String END_OF_THE_LINE_CHARACER = " \n ";
public static final String DATE_PATTERN ="^(?>\\d\\d){1,2}-(?:0?[1-9]|1[0-2])-(\\s)?(?:2[0123]|[01][0-9]):? (?:[0-5][0-9])(?::?(?:(?:[0-5][0-9]|60)(?:[.,][0-9]+)?))?(?:Z|[+-](?:2[0123]|[01][0-9])(?::?(?:[0-5][0-9])))?.*?";
@Override
public boolean isEndOfRecord(String line) {
if(line.matches(DATE_PATTERN) || line.startsWith(STARTING_OF_THE_LINE)
|| line.contains(CONTINUATION_OF_THE_FILE) || line.startsWith(END_OF_THE_LINE)){
if(isNextLineStarts(line) || line.startsWith(END_OF_THE_LINE)){
return true;//to break line
}
}
return false; //to conitnue line
private boolean isNextLineStarts(String preProcessOfLine){
if(preProcessOfLine.contains(CONTINUATION_OF_THE_FILE) && !preProcessOfLine.endsWith(CONTINUATION_OF_THE_FILE)){
String[] lines = preProcessOfLine.split(CONTINUATION_OF_THE_FILE);
if(lines[1].trim().matches(DATE_PATTERN)){
return true;
}
}
return false;
}
@Override
public String preProcess(String line) {
if(line.matches(DATE_PATTERN) && !line.contains(CONTINUATION_OF_THE_FILE)){
line = new StringBuilder(STARTING_OF_THE_LINE).append(line).toString();
}else if(line.startsWith(STARTING_OF_THE_LINE) && !line.contains(CONTINUATION_OF_THE_FILE)){
line = new StringBuilder(line.substring(STARTING_OF_THE_LINE.length())).append(CONTINUATION_OF_THE_FILE).toString();
}else if(line.contains(CONTINUATION_OF_THE_FILE) && !line.endsWith(CONTINUATION_OF_THE_FILE)){
String[] lines = line.split(CONTINUATION_OF_THE_FILE);
if(lines[1].trim().matches(DATE_PATTERN)){
line = new StringBuilder(END_OF_THE_LINE).append(lines[0]).toString();//.append(lines[1]).toString();
}else{
line = new StringBuilder(lines[0]).append(lines[1]).append(CONTINUATION_OF_THE_FILE).toString();
}
}
return super.preProcess(line);
}
@Override
public String postProcess(String record) {
if(record.startsWith(END_OF_THE_LINE)){
record = new StringBuilder(record.substring(END_OF_THE_LINE.length())).toString();
}else if(record.contains(CONTINUATION_OF_THE_FILE) && !record.endsWith(CONTINUATION_OF_THE_FILE)){
String[] lines = record.split(CONTINUATION_OF_THE_FILE);
if(lines[1].trim().matches(DATE_PATTERN)){
record = new StringBuilder(END_OF_THE_LINE).append(lines[0]).toString();
}else{
record = new StringBuilder(lines[0]).append(lines[1]).toString();
}
}
return super.postProcess(record);
}