1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.varia;
19
20 import java.io.BufferedReader;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.Reader;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.Hashtable;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.StringTokenizer;
35 import java.util.regex.MatchResult;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 import java.util.regex.PatternSyntaxException;
39
40 import org.apache.log4j.Level;
41 import org.apache.log4j.Logger;
42 import org.apache.log4j.helpers.Constants;
43 import org.apache.log4j.plugins.Receiver;
44 import org.apache.log4j.rule.ExpressionRule;
45 import org.apache.log4j.rule.Rule;
46 import org.apache.log4j.spi.LocationInfo;
47 import org.apache.log4j.spi.LoggingEvent;
48 import org.apache.log4j.spi.ThrowableInformation;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public class LogFilePatternReceiver extends Receiver {
141 private final List keywords = new ArrayList();
142
143 private static final String PROP_START = "PROP(";
144 private static final String PROP_END = ")";
145
146 private static final String LOGGER = "LOGGER";
147 private static final String MESSAGE = "MESSAGE";
148 private static final String TIMESTAMP = "TIMESTAMP";
149 private static final String NDC = "NDC";
150 private static final String LEVEL = "LEVEL";
151 private static final String THREAD = "THREAD";
152 private static final String CLASS = "CLASS";
153 private static final String FILE = "FILE";
154 private static final String LINE = "LINE";
155 private static final String METHOD = "METHOD";
156 private static final String NEWLINE = "(NL)";
157
158 private static final String DEFAULT_HOST = "file";
159
160
161 private static final String EXCEPTION_PATTERN = "^\\s+at.*";
162 private static final String REGEXP_DEFAULT_WILDCARD = ".*?";
163 private static final String REGEXP_GREEDY_WILDCARD = ".*";
164 private static final String PATTERN_WILDCARD = "*";
165
166 private static final String NOSPACE_GROUP = "(\\s*?\\S*?\\s*?)";
167 private static final String DEFAULT_GROUP = "(" + REGEXP_DEFAULT_WILDCARD + ")";
168 private static final String GREEDY_GROUP = "(" + REGEXP_GREEDY_WILDCARD + ")";
169 private static final String MULTIPLE_SPACES_REGEXP = "[ ]+";
170 private static final String NEWLINE_REGEXP = "\n";
171 private final String newLine = System.getProperty("line.separator");
172
173 private final String[] emptyException = new String[] { "" };
174
175 private SimpleDateFormat dateFormat;
176 private String timestampFormat;
177 private String logFormat;
178 private String customLevelDefinitions;
179 private String fileURL;
180 private String host;
181 private String path;
182 private boolean tailing;
183 private String filterExpression;
184 private long waitMillis = 2000;
185 private String group;
186
187 private static final String VALID_DATEFORMAT_CHARS = "GyYMwWDdFEuaHkKhmsSzZX";
188 private static final String VALID_DATEFORMAT_CHAR_PATTERN = "[" + VALID_DATEFORMAT_CHARS + "]";
189
190 private Rule expressionRule;
191
192 private Map currentMap;
193 private List additionalLines;
194 private List matchingKeywords;
195
196 private String regexp;
197 private Reader reader;
198 private Pattern regexpPattern;
199 private Pattern exceptionPattern;
200 private String timestampPatternText;
201
202 private boolean useCurrentThread;
203 public static final int MISSING_FILE_RETRY_MILLIS = 10000;
204 private boolean appendNonMatches;
205 private final Map customLevelDefinitionMap = new HashMap();
206
207
208 private int lineCount = 1;
209
210 public LogFilePatternReceiver() {
211 keywords.add(TIMESTAMP);
212 keywords.add(LOGGER);
213 keywords.add(LEVEL);
214 keywords.add(THREAD);
215 keywords.add(CLASS);
216 keywords.add(FILE);
217 keywords.add(LINE);
218 keywords.add(METHOD);
219 keywords.add(MESSAGE);
220 keywords.add(NDC);
221 try {
222 exceptionPattern = Pattern.compile(EXCEPTION_PATTERN);
223 } catch (PatternSyntaxException pse) {
224
225 }
226 }
227
228
229
230
231
232
233 public String getFileURL() {
234 return fileURL;
235 }
236
237
238
239
240
241
242 public void setFileURL(String fileURL) {
243 this.fileURL = fileURL;
244 }
245
246
247
248
249
250
251
252 public void setCustomLevelDefinitions(String customLevelDefinitions) {
253 this.customLevelDefinitions = customLevelDefinitions;
254 }
255
256 public String getCustomLevelDefinitions() {
257 return customLevelDefinitions;
258 }
259
260
261
262
263
264 public boolean isAppendNonMatches() {
265 return appendNonMatches;
266 }
267
268
269
270
271
272 public void setAppendNonMatches(boolean appendNonMatches) {
273 this.appendNonMatches = appendNonMatches;
274 }
275
276
277
278
279
280
281 public String getFilterExpression() {
282 return filterExpression;
283 }
284
285
286
287
288
289
290 public void setFilterExpression(String filterExpression) {
291 this.filterExpression = filterExpression;
292 }
293
294
295
296
297
298
299 public boolean isTailing() {
300 return tailing;
301 }
302
303
304
305
306
307
308 public void setTailing(boolean tailing) {
309 this.tailing = tailing;
310 }
311
312
313
314
315
316
317
318 public final boolean isUseCurrentThread() {
319 return useCurrentThread;
320 }
321
322
323
324
325
326
327
328 public final void setUseCurrentThread(boolean useCurrentThread) {
329 this.useCurrentThread = useCurrentThread;
330 }
331
332
333
334
335
336
337 public String getLogFormat() {
338 return logFormat;
339 }
340
341
342
343
344
345
346
347 public void setLogFormat(String logFormat) {
348 this.logFormat = logFormat;
349 }
350
351
352
353
354 public void setGroup(String group) { this.group = group; }
355
356
357
358
359
360
361
362 public String getGroup() { return group; }
363
364
365
366
367
368
369 public void setTimestampFormat(String timestampFormat) {
370 this.timestampFormat = timestampFormat;
371 }
372
373
374
375
376
377
378 public String getTimestampFormat() {
379 return timestampFormat;
380 }
381
382
383
384
385
386 public long getWaitMillis() {
387 return waitMillis;
388 }
389
390
391
392
393
394 public void setWaitMillis(long waitMillis) {
395 this.waitMillis = waitMillis;
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412 private int getExceptionLine() {
413 for (int i = 0; i < additionalLines.size(); i++) {
414 Matcher exceptionMatcher = exceptionPattern.matcher((String)additionalLines.get(i));
415 if (exceptionMatcher.matches()) {
416 return i;
417 }
418 }
419 return -1;
420 }
421
422
423
424
425
426
427
428
429
430
431
432
433
434 private String buildMessage(String firstMessageLine, int exceptionLine) {
435 if (additionalLines.size() == 0) {
436 return firstMessageLine;
437 }
438 StringBuffer message = new StringBuffer();
439 if (firstMessageLine != null) {
440 message.append(firstMessageLine);
441 }
442
443 int linesToProcess = (exceptionLine == -1?additionalLines.size(): exceptionLine);
444
445 for (int i = 0; i < linesToProcess; i++) {
446 message.append(newLine);
447 message.append(additionalLines.get(i));
448 }
449 return message.toString();
450 }
451
452
453
454
455
456
457
458
459
460
461 private String[] buildException(int exceptionLine) {
462 if (exceptionLine == -1) {
463 return emptyException;
464 }
465 String[] exception = new String[additionalLines.size() - exceptionLine - 1];
466 for (int i = 0; i < exception.length; i++) {
467 exception[i] = (String) additionalLines.get(i + exceptionLine);
468 }
469 return exception;
470 }
471
472
473
474
475
476
477
478
479
480 private LoggingEvent buildEvent() {
481 if (currentMap.size() == 0) {
482 if (additionalLines.size() > 0) {
483 for (Iterator iter = additionalLines.iterator();iter.hasNext();) {
484 getLogger().debug("found non-matching line: " + iter.next());
485 }
486 }
487 additionalLines.clear();
488 return null;
489 }
490
491 int exceptionLine = getExceptionLine();
492 String[] exception = buildException(exceptionLine);
493
494
495 if (additionalLines.size() > 0 && exception.length > 0) {
496 currentMap.put(MESSAGE, buildMessage((String) currentMap.get(MESSAGE),
497 exceptionLine));
498 }
499 LoggingEvent event = convertToEvent(currentMap, exception);
500 currentMap.clear();
501 additionalLines.clear();
502 return event;
503 }
504
505
506
507
508
509
510
511
512
513 protected void process(BufferedReader bufferedReader) throws IOException {
514 Matcher eventMatcher;
515 Matcher exceptionMatcher;
516 String line;
517
518 while ((line = bufferedReader.readLine()) != null) {
519
520 for (int i=1;i<lineCount;i++)
521 {
522 String thisLine = bufferedReader.readLine();
523 if (thisLine != null)
524 {
525 line = line + newLine + thisLine;
526 }
527 }
528 eventMatcher = regexpPattern.matcher(line);
529
530 if (line.trim().equals("")) {continue;}
531 exceptionMatcher = exceptionPattern.matcher(line);
532 if (eventMatcher.matches()) {
533
534 LoggingEvent event = buildEvent();
535 if (event != null) {
536 if (passesExpression(event)) {
537 doPost(event);
538 }
539 }
540 currentMap.putAll(processEvent(eventMatcher.toMatchResult()));
541 } else if (exceptionMatcher.matches()) {
542
543 additionalLines.add(line);
544 } else {
545
546
547
548
549 if (appendNonMatches) {
550
551 String lastTime = (String)currentMap.get(TIMESTAMP);
552
553 if (currentMap.size() > 0) {
554 LoggingEvent event = buildEvent();
555 if (event != null) {
556 if (passesExpression(event)) {
557 doPost(event);
558 }
559 }
560 }
561 if (lastTime != null) {
562 currentMap.put(TIMESTAMP, lastTime);
563 }
564 currentMap.put(MESSAGE, line);
565 } else {
566 additionalLines.add(line);
567 }
568 }
569 }
570
571
572 LoggingEvent event = buildEvent();
573 if (event != null) {
574 if (passesExpression(event)) {
575 doPost(event);
576 }
577 }
578 }
579
580 protected void createPattern() {
581 regexpPattern = Pattern.compile(regexp);
582 }
583
584
585
586
587
588
589
590 private boolean passesExpression(LoggingEvent event) {
591 if (event != null) {
592 if (expressionRule != null) {
593 return (expressionRule.evaluate(event, null));
594 }
595 }
596 return true;
597 }
598
599
600
601
602
603
604
605
606
607
608 private Map processEvent(MatchResult result) {
609 Map map = new HashMap();
610
611 for (int i = 1; i < result.groupCount() + 1; i++) {
612 Object key = matchingKeywords.get(i - 1);
613 Object value = result.group(i);
614 map.put(key, value);
615
616 }
617 return map;
618 }
619
620
621
622
623
624
625
626 private String convertTimestamp() {
627
628
629 String result = "";
630 if (timestampFormat != null) {
631 result = timestampFormat.replaceAll(Pattern.quote("+"), "[+]");
632 result = result.replaceAll(VALID_DATEFORMAT_CHAR_PATTERN, "\\\\S+");
633
634 result = result.replaceAll(Pattern.quote("."), "\\\\.");
635 }
636 return result;
637 }
638
639 protected void setHost(String host) {
640 this.host = host;
641 }
642
643 protected void setPath(String path) {
644 this.path = path;
645 }
646
647 public String getPath() {
648 return path;
649 }
650
651
652
653
654
655 protected void initialize() {
656 if (host == null && path == null) {
657 try {
658 URL url = new URL(fileURL);
659 host = url.getHost();
660 path = url.getPath();
661 } catch (MalformedURLException e1) {
662
663 e1.printStackTrace();
664 }
665 }
666 if (host == null || host.trim().equals("")) {
667 host = DEFAULT_HOST;
668 }
669 if (path == null || path.trim().equals("")) {
670 path = fileURL;
671 }
672
673 currentMap = new HashMap();
674 additionalLines = new ArrayList();
675 matchingKeywords = new ArrayList();
676
677 if (timestampFormat != null) {
678 dateFormat = new SimpleDateFormat(quoteTimeStampChars(timestampFormat));
679 timestampPatternText = convertTimestamp();
680 }
681
682 updateCustomLevelDefinitionMap();
683 try {
684 if (filterExpression != null) {
685 expressionRule = ExpressionRule.getRule(filterExpression);
686 }
687 } catch (Exception e) {
688 getLogger().warn("Invalid filter expression: " + filterExpression, e);
689 }
690
691 List buildingKeywords = new ArrayList();
692
693 String newPattern = logFormat;
694
695
696 int index = 0;
697 while (index > -1) {
698 index = newPattern.indexOf(NEWLINE);
699 if (index > -1) {
700
701 lineCount++;
702 newPattern = singleReplace(newPattern, NEWLINE, NEWLINE_REGEXP);
703 }
704 }
705
706 String current = newPattern;
707
708
709 List propertyNames = new ArrayList();
710 index = 0;
711 while (index > -1) {
712 if (current.indexOf(PROP_START) > -1 && current.indexOf(PROP_END) > -1) {
713 index = current.indexOf(PROP_START);
714 String longPropertyName = current.substring(current.indexOf(PROP_START), current.indexOf(PROP_END) + 1);
715 String shortProp = getShortPropertyName(longPropertyName);
716 buildingKeywords.add(shortProp);
717 propertyNames.add(longPropertyName);
718 current = current.substring(longPropertyName.length() + 1 + index);
719 newPattern = singleReplace(newPattern, longPropertyName, new Integer(buildingKeywords.size() -1).toString());
720 } else {
721
722 index = -1;
723 }
724 }
725
726
727
728
729
730
731
732
733
734 Iterator iter = keywords.iterator();
735 while (iter.hasNext()) {
736 String keyword = (String) iter.next();
737 int index2 = newPattern.indexOf(keyword);
738 if (index2 > -1) {
739 buildingKeywords.add(keyword);
740 newPattern = singleReplace(newPattern, keyword, new Integer(buildingKeywords.size() -1).toString());
741 }
742 }
743
744 String buildingInt = "";
745
746 for (int i=0;i<newPattern.length();i++) {
747 String thisValue = String.valueOf(newPattern.substring(i, i+1));
748 if (isInteger(thisValue)) {
749 buildingInt = buildingInt + thisValue;
750 } else {
751 if (isInteger(buildingInt)) {
752 matchingKeywords.add(buildingKeywords.get(Integer.parseInt(buildingInt)));
753 }
754
755 buildingInt = "";
756 }
757 }
758
759
760 if (isInteger(buildingInt)) {
761 matchingKeywords.add(buildingKeywords.get(Integer.parseInt(buildingInt)));
762 }
763
764 newPattern = replaceMetaChars(newPattern);
765
766
767
768 newPattern = newPattern.replaceAll(MULTIPLE_SPACES_REGEXP, MULTIPLE_SPACES_REGEXP);
769 newPattern = newPattern.replaceAll(Pattern.quote(PATTERN_WILDCARD), REGEXP_DEFAULT_WILDCARD);
770
771 for (int i = 0;i<buildingKeywords.size();i++) {
772 String keyword = (String) buildingKeywords.get(i);
773
774 if (i == (buildingKeywords.size() - 1)) {
775 newPattern = singleReplace(newPattern, String.valueOf(i), GREEDY_GROUP);
776 } else if (TIMESTAMP.equals(keyword)) {
777 newPattern = singleReplace(newPattern, String.valueOf(i), "(" + timestampPatternText + ")");
778 } else if (LOGGER.equals(keyword) || LEVEL.equals(keyword)) {
779 newPattern = singleReplace(newPattern, String.valueOf(i), NOSPACE_GROUP);
780 } else {
781 newPattern = singleReplace(newPattern, String.valueOf(i), DEFAULT_GROUP);
782 }
783 }
784
785 regexp = newPattern;
786 getLogger().debug("regexp is " + regexp);
787 }
788
789 private void updateCustomLevelDefinitionMap() {
790 if (customLevelDefinitions != null) {
791 StringTokenizer entryTokenizer = new StringTokenizer(customLevelDefinitions, ",");
792
793 customLevelDefinitionMap.clear();
794 while (entryTokenizer.hasMoreTokens()) {
795 StringTokenizer innerTokenizer = new StringTokenizer(entryTokenizer.nextToken(), "=");
796 customLevelDefinitionMap.put(innerTokenizer.nextToken(), Level.toLevel(innerTokenizer.nextToken()));
797 }
798 }
799 }
800
801 private boolean isInteger(String value) {
802 try {
803 Integer.parseInt(value);
804 return true;
805 } catch (NumberFormatException nfe) {
806 return false;
807 }
808 }
809
810 private String quoteTimeStampChars(String input) {
811
812 StringBuffer result = new StringBuffer();
813
814 boolean lastCharIsDateFormat = false;
815 for (int i = 0;i<input.length();i++) {
816 String thisVal = input.substring(i, i + 1);
817 boolean thisCharIsDateFormat = VALID_DATEFORMAT_CHARS.contains(thisVal);
818
819 if (!thisCharIsDateFormat && (i == 0 || lastCharIsDateFormat)) {
820 result.append("'");
821 }
822
823 if (thisCharIsDateFormat && i > 0 && !lastCharIsDateFormat) {
824 result.append("'");
825 }
826 lastCharIsDateFormat = thisCharIsDateFormat;
827 result.append(thisVal);
828 }
829
830 if (!lastCharIsDateFormat) {
831 result.append("'");
832 }
833 return result.toString();
834 }
835
836 private String singleReplace(String inputString, String oldString, String newString)
837 {
838 int propLength = oldString.length();
839 int startPos = inputString.indexOf(oldString);
840 if (startPos == -1)
841 {
842 getLogger().info("string: " + oldString + " not found in input: " + inputString + " - returning input");
843 return inputString;
844 }
845 if (startPos == 0)
846 {
847 inputString = inputString.substring(propLength);
848 inputString = newString + inputString;
849 } else {
850 inputString = inputString.substring(0, startPos) + newString + inputString.substring(startPos + propLength);
851 }
852 return inputString;
853 }
854
855 private String getShortPropertyName(String longPropertyName)
856 {
857 String currentProp = longPropertyName.substring(longPropertyName.indexOf(PROP_START));
858 String prop = currentProp.substring(0, currentProp.indexOf(PROP_END) + 1);
859 String shortProp = prop.substring(PROP_START.length(), prop.length() - 1);
860 return shortProp;
861 }
862
863
864
865
866
867
868
869
870 private String replaceMetaChars(String input) {
871
872 input = input.replaceAll("\\\\", "\\\\\\");
873
874
875 input = input.replaceAll(Pattern.quote("]"), "\\\\]");
876 input = input.replaceAll(Pattern.quote("["), "\\\\[");
877 input = input.replaceAll(Pattern.quote("^"), "\\\\^");
878 input = input.replaceAll(Pattern.quote("$"), "\\\\$");
879 input = input.replaceAll(Pattern.quote("."), "\\\\.");
880 input = input.replaceAll(Pattern.quote("|"), "\\\\|");
881 input = input.replaceAll(Pattern.quote("?"), "\\\\?");
882 input = input.replaceAll(Pattern.quote("+"), "\\\\+");
883 input = input.replaceAll(Pattern.quote("("), "\\\\(");
884 input = input.replaceAll(Pattern.quote(")"), "\\\\)");
885 input = input.replaceAll(Pattern.quote("-"), "\\\\-");
886 input = input.replaceAll(Pattern.quote("{"), "\\\\{");
887 input = input.replaceAll(Pattern.quote("}"), "\\\\}");
888 input = input.replaceAll(Pattern.quote("#"), "\\\\#");
889 return input;
890 }
891
892
893
894
895
896
897
898
899
900 private LoggingEvent convertToEvent(Map fieldMap, String[] exception) {
901 if (fieldMap == null) {
902 return null;
903 }
904
905
906 if (!fieldMap.containsKey(LOGGER)) {
907 fieldMap.put(LOGGER, "Unknown");
908 }
909 if (exception == null) {
910 exception = emptyException;
911 }
912
913 Logger logger = null;
914 long timeStamp = 0L;
915 String level = null;
916 String threadName = null;
917 Object message = null;
918 String ndc = null;
919 String className = null;
920 String methodName = null;
921 String eventFileName = null;
922 String lineNumber = null;
923 Hashtable properties = new Hashtable();
924
925 logger = Logger.getLogger((String) fieldMap.remove(LOGGER));
926
927 if ((dateFormat != null) && fieldMap.containsKey(TIMESTAMP)) {
928 try {
929 timeStamp = dateFormat.parse((String) fieldMap.remove(TIMESTAMP))
930 .getTime();
931 } catch (Exception e) {
932 e.printStackTrace();
933 }
934 }
935
936 if (timeStamp == 0L) {
937 timeStamp = System.currentTimeMillis();
938 }
939
940 message = fieldMap.remove(MESSAGE);
941 if (message == null) {
942 message = "";
943 }
944
945 level = (String) fieldMap.remove(LEVEL);
946 Level levelImpl;
947 if (level == null) {
948 levelImpl = Level.DEBUG;
949 } else {
950
951 levelImpl = (Level) customLevelDefinitionMap.get(level);
952 if (levelImpl == null) {
953 levelImpl = Level.toLevel(level.trim());
954 if (!level.equals(levelImpl.toString())) {
955
956 if (levelImpl == null) {
957 levelImpl = Level.DEBUG;
958 getLogger().debug("found unexpected level: " + level + ", logger: " + logger.getName() + ", msg: " + message);
959
960 message = level + " " + message;
961 }
962 }
963 }
964 }
965
966 threadName = (String) fieldMap.remove(THREAD);
967
968 ndc = (String) fieldMap.remove(NDC);
969
970 className = (String) fieldMap.remove(CLASS);
971
972 methodName = (String) fieldMap.remove(METHOD);
973
974 eventFileName = (String) fieldMap.remove(FILE);
975
976 lineNumber = (String) fieldMap.remove(LINE);
977
978 properties.put(Constants.HOSTNAME_KEY, host);
979 properties.put(Constants.APPLICATION_KEY, path);
980 properties.put(Constants.RECEIVER_NAME_KEY, getName());
981 if (group != null) {
982 properties.put(Constants.GROUP_KEY, group);
983 }
984
985
986 properties.putAll(fieldMap);
987
988 LocationInfo info = null;
989
990 if ((eventFileName != null) || (className != null) || (methodName != null)
991 || (lineNumber != null)) {
992 info = new LocationInfo(eventFileName, className, methodName, lineNumber);
993 } else {
994 info = LocationInfo.NA_LOCATION_INFO;
995 }
996
997 LoggingEvent event = new LoggingEvent(null,
998 logger, timeStamp, levelImpl, message,
999 threadName,
1000 new ThrowableInformation(exception),
1001 ndc,
1002 info,
1003 properties);
1004
1005 return event;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027 public void shutdown() {
1028 getLogger().info(getPath() + " shutdown");
1029 active = false;
1030 try {
1031 if (reader != null) {
1032 reader.close();
1033 reader = null;
1034 }
1035 } catch (IOException ioe) {
1036 ioe.printStackTrace();
1037 }
1038 }
1039
1040
1041
1042
1043 public void activateOptions() {
1044 getLogger().info("activateOptions");
1045 active = true;
1046 Runnable runnable = new Runnable() {
1047 public void run() {
1048 initialize();
1049 while (reader == null) {
1050 getLogger().info("attempting to load file: " + getFileURL());
1051 try {
1052 reader = new InputStreamReader(new URL(getFileURL()).openStream(), "UTF-8");
1053 } catch (FileNotFoundException fnfe) {
1054 getLogger().info("file not available - will try again");
1055 synchronized (this) {
1056 try {
1057 wait(MISSING_FILE_RETRY_MILLIS);
1058 } catch (InterruptedException ie) {}
1059 }
1060 } catch (IOException ioe) {
1061 getLogger().warn("unable to load file", ioe);
1062 return;
1063 }
1064 }
1065 try {
1066 BufferedReader bufferedReader = new BufferedReader(reader);
1067 createPattern();
1068 do {
1069 process(bufferedReader);
1070 try {
1071 synchronized (this) {
1072 wait(waitMillis);
1073 }
1074 } catch (InterruptedException ie) {}
1075 if (tailing) {
1076 getLogger().debug("tailing file");
1077 }
1078 } while (tailing);
1079
1080 } catch (IOException ioe) {
1081
1082 getLogger().info("stream closed");
1083 }
1084 getLogger().debug("processing " + path + " complete");
1085 shutdown();
1086 }
1087 };
1088 if(useCurrentThread) {
1089 runnable.run();
1090 }else {
1091 new Thread(runnable, "LogFilePatternReceiver-"+getName()).start();
1092 }
1093 }
1094 }