[DMAAP-DR] Remove cadi/aaf from dr-node
[dmaap/datarouter.git] / datarouter-node / src / main / java / org / onap / dmaap / datarouter / node / log / LogManager.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
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
10  * *
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * *
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====================================================
19  * *
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24 package org.onap.dmaap.datarouter.node.log;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import java.io.BufferedReader;
29 import java.io.File;
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;
46
47 /**
48  * Cleanup of old log files.
49  *
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.
53  */
54
55 public class LogManager extends TimerTask {
56
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;
65
66     /**
67      * Construct a log manager
68      *
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).
71      */
72     public LogManager(NodeConfigManager config) {
73         this.config = config;
74         try {
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);
79         }
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();
88     }
89
90     /**
91      * Trigger check for expired log files and log files to upload.
92      */
93     public void run() {
94         worker.poke();
95     }
96
97     public Uploader getWorker() {
98         return worker;
99     }
100
101     public class Uploader extends Thread implements DeliveryQueueHelper {
102
103         private static final String META = "/.meta";
104         private EELFLogger logger = EELFManager.getInstance().getLogger(Uploader.class);
105         private DeliveryQueue dq;
106
107         Uploader() {
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());
114             setDaemon(true);
115             setName("Log Uploader");
116             start();
117         }
118
119         public long getInitFailureTimer() {
120             return (10000L);
121         }
122
123         public long getWaitForFileProcessFailureTimer() {
124             return (600000L);
125         }
126
127         public double getFailureBackoff() {
128             return (2.0);
129         }
130
131         public long getMaxFailureTimer() {
132             return (150000L);
133         }
134
135         public long getExpirationTimer() {
136             return (604800000L);
137         }
138
139         public int getFairFileLimit() {
140             return (10000);
141         }
142
143         public long getFairTimeLimit() {
144             return (86400000);
145         }
146
147         public String getDestURL(DestInfo destinationInfo, String fileid) {
148             return (config.getEventLogUrl());
149         }
150
151         public void handleUnreachable(DestInfo destinationInfo) {
152             throw new UnsupportedOperationException();
153         }
154
155         public boolean handleRedirection(DestInfo destinationInfo, String location, String fileid) {
156             return (false);
157         }
158
159         public boolean isFollowRedirects() {
160             return (false);
161         }
162
163         public String getFeedId(String subid) {
164             return (null);
165         }
166
167         private synchronized void snooze() {
168             try {
169                 wait(10000);
170             } catch (Exception e) {
171                 logger.error(EXCEPTION, e);
172             }
173         }
174
175         private synchronized void poke() {
176             notifyAll();
177         }
178
179         @Override
180         public void run() {
181             while (true) {
182                 scan();
183                 dq.run();
184                 snooze();
185             }
186         }
187
188         private void scan() {
189             long threshold = System.currentTimeMillis() - config.getLogRetention();
190             File dir = new File(logdir);
191             String[] fns = dir.list();
192             Arrays.sort(fns);
193             String lastqueued = "events-000000000000.log";
194             String curlog = StatusLog.getCurLogFile();
195             curlog = curlog.substring(curlog.lastIndexOf('/') + 1);
196             try {
197                 Writer writer = new FileWriter(uploaddir + META);
198                 writer.write("POST\tlogdata\nContent-Type\ttext/plain\n");
199                 writer.close();
200                 BufferedReader br = new BufferedReader(new FileReader(uploaddir + "/.lastqueued"));
201                 lastqueued = br.readLine();
202                 br.close();
203             } catch (Exception e) {
204                 logger.error(EXCEPTION, e);
205             }
206             for (String fn : fns) {
207                 if (!isnodelog.reset(fn).matches()) {
208                     if (!iseventlog.reset(fn).matches()) {
209                         continue;
210                     }
211                     lastqueued = setLastQueued(lastqueued, curlog, fn);
212                 }
213                 File file = new File(dir, fn);
214                 if (file.lastModified() < threshold) {
215                     try {
216                         Files.deleteIfExists(file.toPath());
217                     } catch (IOException e) {
218                         logger.error("Failed to delete file: " + file.getPath(), e);
219                     }
220                 }
221             }
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);
227             }
228         }
229
230         @NotNull
231         private String setLastQueued(String lastqueued, String curlog, String fn) {
232             if (lastqueued.compareTo(fn) < 0 && curlog.compareTo(fn) > 0) {
233                 lastqueued = fn;
234                 try {
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);
240                 }
241             }
242             return lastqueued;
243         }
244     }
245 }