1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import org.apache.logging.log4j.LogManager;
19 import org.apache.logging.log4j.Logger;
20 import org.codelibs.fess.app.service.FailureUrlService;
21 import org.codelibs.fess.crawler.CrawlerContext;
22 import org.codelibs.fess.crawler.entity.UrlQueue;
23 import org.codelibs.fess.crawler.exception.CrawlingAccessException;
24 import org.codelibs.fess.crawler.exception.MultipleCrawlingAccessException;
25 import org.codelibs.fess.crawler.helper.impl.LogHelperImpl;
26 import org.codelibs.fess.crawler.log.LogType;
27 import org.codelibs.fess.exception.ContainerNotAvailableException;
28 import org.codelibs.fess.helper.CrawlerStatsHelper.StatsAction;
29 import org.codelibs.fess.opensearch.config.exentity.CrawlingConfig;
30 import org.codelibs.fess.opensearch.config.exentity.FailureUrl;
31 import org.codelibs.fess.util.ComponentUtil;
32
33
34
35
36
37
38 public class CrawlerLogHelper extends LogHelperImpl {
39
40
41
42
43 public CrawlerLogHelper() {
44 super();
45 }
46
47 private static final Logger logger = LogManager.getLogger(CrawlerLogHelper.class);
48
49 @Override
50 public void log(final LogType key, final Object... objs) {
51 if (!ComponentUtil.available()) {
52 if (logger.isDebugEnabled()) {
53 logger.debug("container was destroyed.");
54 }
55 return;
56 }
57 super.log(key, objs);
58 }
59
60 @Override
61 protected void processStartCrawling(final Object... objs) {
62 super.processStartCrawling(objs);
63 if (objs.length > 1 && objs[1] instanceof final UrlQueue<?> urlQueue) {
64 ComponentUtil.getCrawlerStatsHelper().begin(urlQueue);
65 }
66 }
67
68 @Override
69 protected void processCleanupCrawling(final Object... objs) {
70 super.processCleanupCrawling(objs);
71 if (objs.length > 1 && objs[1] instanceof final UrlQueue<?> urlQueue) {
72 ComponentUtil.getCrawlerStatsHelper().done(urlQueue);
73 }
74 }
75
76 @Override
77 protected void processProcessChildUrlByException(final Object... objs) {
78 super.processProcessChildUrlByException(objs);
79 if (objs.length > 1 && objs[1] instanceof final UrlQueue<?> urlQueue) {
80 ComponentUtil.getCrawlerStatsHelper().record(urlQueue, StatsAction.CHILD_URL);
81 }
82 }
83
84 @Override
85 protected void processProcessChildUrlsByException(final Object... objs) {
86 super.processProcessChildUrlsByException(objs);
87 if (objs.length > 1 && objs[1] instanceof final UrlQueue<?> urlQueue) {
88 ComponentUtil.getCrawlerStatsHelper().record(urlQueue, StatsAction.CHILD_URLS);
89 }
90 }
91
92 @Override
93 protected void processFinishedCrawling(final Object... objs) {
94 super.processFinishedCrawling(objs);
95 if (objs.length > 1 && objs[1] instanceof final UrlQueue<?> urlQueue) {
96 ComponentUtil.getCrawlerStatsHelper().record(urlQueue, StatsAction.FINISHED);
97 }
98 }
99
100 @Override
101 protected void processCrawlingAccessException(final Object... objs) {
102 String failureUrlId = "?";
103 final CrawlerContext crawlerContext = (CrawlerContext) objs[0];
104 final UrlQueue<?> urlQueue = (UrlQueue<?>) objs[1];
105 final CrawlingAccessException cae = (CrawlingAccessException) objs[2];
106 try {
107 Throwable t = cae;
108 if (t instanceof final MultipleCrawlingAccessException mcae) {
109 final Throwable[] causes = mcae.getCauses();
110 if (causes.length > 0) {
111 t = causes[causes.length - 1];
112 }
113 }
114
115 String errorName;
116 final Throwable cause = t.getCause();
117 if (cause != null) {
118 errorName = cause.getClass().getCanonicalName();
119 } else {
120 errorName = t.getClass().getCanonicalName();
121 }
122 final FailureUrl failureUrl = storeFailureUrl(crawlerContext, urlQueue, errorName, t);
123 if (failureUrl != null) {
124 failureUrlId = failureUrl.getId();
125 }
126 } catch (final ContainerNotAvailableException e) {
127 if (logger.isDebugEnabled()) {
128 logger.debug("container was destroyed.");
129 }
130 return;
131 } catch (final Exception e) {
132 if (!ComponentUtil.available()) {
133 if (logger.isDebugEnabled()) {
134 logger.debug("container was destroyed.");
135 }
136 return;
137 }
138 logger.warn("Failed to store failure url: url={}", urlQueue.getUrl(), e);
139 }
140
141 if (cae.isDebugEnabled()) {
142 logger.debug("[{}] Crawling Access Exception: url={}", failureUrlId, urlQueue.getUrl(), cae);
143 } else if (cae.isInfoEnabled()) {
144 logger.info("[{}] {}", failureUrlId, cae.getMessage());
145 } else if (cae.isWarnEnabled()) {
146 logger.warn("[{}] Crawling Access Exception: url={}", failureUrlId, urlQueue.getUrl(), cae);
147 } else if (cae.isErrorEnabled()) {
148 logger.error("[{}] Crawling Access Exception: url={}", failureUrlId, urlQueue.getUrl(), cae);
149 }
150
151 ComponentUtil.getCrawlerStatsHelper().record(urlQueue, StatsAction.ACCESS_EXCEPTION);
152 }
153
154 @Override
155 protected void processCrawlingException(final Object... objs) {
156 final UrlQueue<?> urlQueue = objs.length > 1 && objs[1] instanceof UrlQueue<?> ? (UrlQueue<?>) objs[1] : null;
157 try {
158 final CrawlerContext crawlerContext = (CrawlerContext) objs[0];
159 final Throwable e = (Throwable) objs[2];
160
161 storeFailureUrl(crawlerContext, urlQueue, e.getClass().getCanonicalName(), e);
162 } catch (final ContainerNotAvailableException e) {
163 if (logger.isDebugEnabled()) {
164 logger.debug("container was destroyed.");
165 }
166 return;
167 } catch (final Exception e) {
168 if (!ComponentUtil.available()) {
169 if (logger.isDebugEnabled()) {
170 logger.debug("container was destroyed.");
171 }
172 return;
173 }
174 logger.warn("Failed to store failure url: url={}", urlQueue != null ? urlQueue.getUrl() : "unknown", e);
175 }
176
177 super.processCrawlingException(objs);
178 if (urlQueue != null) {
179 ComponentUtil.getCrawlerStatsHelper().record(urlQueue, StatsAction.ACCESS_EXCEPTION);
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192 protected FailureUrl storeFailureUrl(final CrawlerContext crawlerContext, final UrlQueue<?> urlQueue, final String errorName,
193 final Throwable e) {
194
195 final CrawlingConfig crawlingConfig = getCrawlingConfig(crawlerContext.getSessionId());
196 final String url = urlQueue.getUrl();
197
198 final FailureUrlService failureUrlService = ComponentUtil.getComponent(FailureUrlService.class);
199 return failureUrlService.store(crawlingConfig, errorName, url, e);
200 }
201
202
203
204
205
206
207
208 protected CrawlingConfig getCrawlingConfig(final String sessionCountId) {
209 return ComponentUtil.getCrawlingConfigHelper().get(sessionCountId);
210 }
211
212 }