1 /*******************************************************************************
2 * ============LICENSE_START==================================================
4 * * ===========================================================================
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * * ===========================================================================
7 * * Licensed under the Apache License, Version 2.0 (the "License");
8 * * you may not use this file except in compliance with the License.
9 * * You may obtain a copy of the License at
11 * * http://www.apache.org/licenses/LICENSE-2.0
13 * * Unless required by applicable law or agreed to in writing, software
14 * * distributed under the License is distributed on an "AS IS" BASIS,
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * * See the License for the specific language governing permissions and
17 * * limitations under the License.
18 * * ============LICENSE_END====================================================
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 ******************************************************************************/
24 package org.onap.dmaap.datarouter.node.log;
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import java.io.BufferedReader;
30 import java.io.FileReader;
31 import java.io.FileWriter;
32 import java.io.IOException;
33 import java.io.Writer;
34 import java.nio.file.Files;
35 import java.nio.file.Paths;
36 import java.util.Arrays;
37 import java.util.TimerTask;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40 import org.jetbrains.annotations.NotNull;
41 import org.onap.dmaap.datarouter.node.DestInfo;
42 import org.onap.dmaap.datarouter.node.DestInfoBuilder;
43 import org.onap.dmaap.datarouter.node.NodeConfigManager;
44 import org.onap.dmaap.datarouter.node.delivery.DeliveryQueue;
45 import org.onap.dmaap.datarouter.node.delivery.DeliveryQueueHelper;
48 * Cleanup of old log files.
50 * <p>Periodically scan the log directory for log files that are older than the log file retention interval, and delete
51 * them. In a future release, This class will also be responsible for uploading events logs to the log server to
52 * support the log query APIs.
55 public class LogManager extends TimerTask {
57 private static final String EXCEPTION = "Exception";
58 private EELFLogger logger = EELFManager.getInstance().getLogger(LogManager.class);
59 private NodeConfigManager config;
60 private Matcher isnodelog;
61 private Matcher iseventlog;
62 private Uploader worker;
63 private String uploaddir;
64 private String logdir;
67 * Construct a log manager
69 * <p>The log manager will check for expired log files every 5 minutes at 20 seconds after the 5 minute boundary.
70 * (Actually, the interval is the event log rollover interval, which defaults to 5 minutes).
72 public LogManager(NodeConfigManager config) {
75 isnodelog = Pattern.compile("node\\.log\\.\\d{8}").matcher("");
76 iseventlog = Pattern.compile("events-\\d{12}\\.log").matcher("");
77 } catch (Exception e) {
78 logger.error(EXCEPTION, e);
80 logdir = config.getLogDir();
81 uploaddir = logdir + "/.spool";
82 (new File(uploaddir)).mkdirs();
83 long now = System.currentTimeMillis();
84 long intvl = StatusLog.parseInterval(config.getEventLogInterval(), 30000);
85 long when = now - now % intvl + intvl + 20000L;
86 config.getTimer().scheduleAtFixedRate(this, when - now, intvl);
87 worker = new Uploader();
91 * Trigger check for expired log files and log files to upload.
97 public Uploader getWorker() {
101 public class Uploader extends Thread implements DeliveryQueueHelper {
103 private static final String META = "/.meta";
104 private EELFLogger logger = EELFManager.getInstance().getLogger(Uploader.class);
105 private DeliveryQueue dq;
108 dq = new DeliveryQueue(this,
109 new DestInfoBuilder().setName("LogUpload").setSpool(uploaddir).setSubid(null).setLogdata(null)
110 .setUrl(null).setAuthuser(config.getMyName()).setAuthentication(config.getMyAuth())
111 .setMetaonly(false).setUse100(false).setPrivilegedSubscriber(false)
112 .setFollowRedirects(false)
113 .setDecompress(false).createDestInfo());
115 setName("Log Uploader");
119 public long getInitFailureTimer() {
123 public long getWaitForFileProcessFailureTimer() {
127 public double getFailureBackoff() {
131 public long getMaxFailureTimer() {
135 public long getExpirationTimer() {
139 public int getFairFileLimit() {
143 public long getFairTimeLimit() {
147 public String getDestURL(DestInfo destinationInfo, String fileid) {
148 return (config.getEventLogUrl());
151 public void handleUnreachable(DestInfo destinationInfo) {
152 throw new UnsupportedOperationException();
155 public boolean handleRedirection(DestInfo destinationInfo, String location, String fileid) {
159 public boolean isFollowRedirects() {
163 public String getFeedId(String subid) {
167 private synchronized void snooze() {
170 } catch (Exception e) {
171 logger.error(EXCEPTION, e);
175 private synchronized void poke() {
188 private void scan() {
189 long threshold = System.currentTimeMillis() - config.getLogRetention();
190 File dir = new File(logdir);
191 String[] fns = dir.list();
193 String lastqueued = "events-000000000000.log";
194 String curlog = StatusLog.getCurLogFile();
195 curlog = curlog.substring(curlog.lastIndexOf('/') + 1);
197 Writer writer = new FileWriter(uploaddir + META);
198 writer.write("POST\tlogdata\nContent-Type\ttext/plain\n");
200 BufferedReader br = new BufferedReader(new FileReader(uploaddir + "/.lastqueued"));
201 lastqueued = br.readLine();
203 } catch (Exception e) {
204 logger.error(EXCEPTION, e);
206 for (String fn : fns) {
207 if (!isnodelog.reset(fn).matches()) {
208 if (!iseventlog.reset(fn).matches()) {
211 lastqueued = setLastQueued(lastqueued, curlog, fn);
213 File file = new File(dir, fn);
214 if (file.lastModified() < threshold) {
216 Files.deleteIfExists(file.toPath());
217 } catch (IOException e) {
218 logger.error("Failed to delete file: " + file.getPath(), e);
222 try (Writer w = new FileWriter(uploaddir + "/.lastqueued")) {
223 Files.deleteIfExists(new File(uploaddir + META).toPath());
224 w.write(lastqueued + "\n");
225 } catch (Exception e) {
226 logger.error(EXCEPTION, e);
231 private String setLastQueued(String lastqueued, String curlog, String fn) {
232 if (lastqueued.compareTo(fn) < 0 && curlog.compareTo(fn) > 0) {
235 String pid = config.getPublishId();
236 Files.createLink(Paths.get(uploaddir + "/" + pid), Paths.get(logdir + "/" + fn));
237 Files.createLink(Paths.get(uploaddir + "/" + pid + ".M"), Paths.get(uploaddir + META));
238 } catch (Exception e) {
239 logger.error(EXCEPTION, e);