1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.rolling;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.nio.file.DirectoryStream;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.SortedMap;
30 import java.util.TreeMap;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34 import org.apache.logging.log4j.Logger;
35 import org.apache.logging.log4j.LoggingException;
36 import org.apache.logging.log4j.core.appender.rolling.action.Action;
37 import org.apache.logging.log4j.core.appender.rolling.action.CommonsCompressAction;
38 import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction;
39 import org.apache.logging.log4j.core.appender.rolling.action.GzCompressAction;
40 import org.apache.logging.log4j.core.appender.rolling.action.ZipCompressAction;
41 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
42 import org.apache.logging.log4j.core.pattern.NotANumber;
43 import org.apache.logging.log4j.status.StatusLogger;
44
45
46
47
48 public abstract class AbstractRolloverStrategy implements RolloverStrategy {
49
50
51
52
53 protected static final Logger LOGGER = StatusLogger.getLogger();
54
55 protected final StrSubstitutor strSubstitutor;
56
57 protected AbstractRolloverStrategy(final StrSubstitutor strSubstitutor) {
58 this.strSubstitutor = strSubstitutor;
59 }
60
61
62 public StrSubstitutor getStrSubstitutor() {
63 return strSubstitutor;
64 }
65
66 protected Action merge(final Action compressAction, final List<Action> custom, final boolean stopOnError) {
67 if (custom.isEmpty()) {
68 return compressAction;
69 }
70 if (compressAction == null) {
71 return new CompositeAction(custom, stopOnError);
72 }
73 final List<Action> all = new ArrayList<>();
74 all.add(compressAction);
75 all.addAll(custom);
76 return new CompositeAction(all, stopOnError);
77 }
78
79 protected int suffixLength(final String lowFilename) {
80 for (final FileExtension extension : FileExtension.values()) {
81 if (extension.isExtensionFor(lowFilename)) {
82 return extension.length();
83 }
84 }
85 return 0;
86 }
87
88
89 protected SortedMap<Integer, Path> getEligibleFiles(final RollingFileManager manager) {
90 return getEligibleFiles(manager, true);
91 }
92
93 protected SortedMap<Integer, Path> getEligibleFiles(final RollingFileManager manager,
94 final boolean isAscending) {
95 final StringBuilder buf = new StringBuilder();
96 String pattern = manager.getPatternProcessor().getPattern();
97 manager.getPatternProcessor().formatFileName(strSubstitutor, buf, NotANumber.NAN);
98 return getEligibleFiles(buf.toString(), pattern, isAscending);
99 }
100
101 protected SortedMap<Integer, Path> getEligibleFiles(String path, String pattern) {
102 return getEligibleFiles(path, pattern, true);
103 }
104
105 protected SortedMap<Integer, Path> getEligibleFiles(String path, String logfilePattern, boolean isAscending) {
106 TreeMap<Integer, Path> eligibleFiles = new TreeMap<>();
107 File file = new File(path);
108 File parent = file.getParentFile();
109 if (parent == null) {
110 parent = new File(".");
111 } else {
112 parent.mkdirs();
113 }
114 if (!logfilePattern.contains("%i")) {
115 return eligibleFiles;
116 }
117 Path dir = parent.toPath();
118 String fileName = file.getName();
119 int suffixLength = suffixLength(fileName);
120 if (suffixLength > 0) {
121 fileName = fileName.substring(0, fileName.length() - suffixLength) + ".*";
122 }
123 String filePattern = fileName.replace(NotANumber.VALUE, "(\\d+)");
124 Pattern pattern = Pattern.compile(filePattern);
125
126 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
127 for (Path entry: stream) {
128 Matcher matcher = pattern.matcher(entry.toFile().getName());
129 if (matcher.matches()) {
130 Integer index = Integer.parseInt(matcher.group(1));
131 eligibleFiles.put(index, entry);
132 }
133 }
134 } catch (IOException ioe) {
135 throw new LoggingException("Error reading folder " + dir + " " + ioe.getMessage(), ioe);
136 }
137 return isAscending? eligibleFiles : eligibleFiles.descendingMap();
138 }
139 }