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