Autopsy  4.4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
IngestMonitor.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2015 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
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  */
19 package org.sleuthkit.autopsy.ingest;
20 
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.beans.PropertyChangeEvent;
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.EnumSet;
27 import java.util.logging.FileHandler;
28 import java.util.logging.Level;
29 import java.util.logging.SimpleFormatter;
30 import org.openide.util.NbBundle;
32 import javax.swing.Timer;
36 
43 public final class IngestMonitor {
44 
45  public static final int DISK_FREE_SPACE_UNKNOWN = -1;
46  private static final int INITIAL_INTERVAL_MS = 60000; //1 min.
47  private static final int MAX_LOG_FILES = 3;
48  private static final java.util.logging.Logger MONITOR_LOGGER = java.util.logging.Logger.getLogger("monitor"); //NON-NLS
49  private final Logger logger = Logger.getLogger(IngestMonitor.class.getName());
50  private Timer timer;
52 
57  IngestMonitor() {
58  /*
59  * Setup a separate memory usage logger.
60  */
61  try {
62  FileHandler monitorLogHandler = new FileHandler(PlatformUtil.getUserDirectory().getAbsolutePath() + "/var/log/monitor.log", 0, MAX_LOG_FILES); //NON-NLS
63  monitorLogHandler.setFormatter(new SimpleFormatter());
64  monitorLogHandler.setEncoding(PlatformUtil.getLogFileEncoding());
65  MONITOR_LOGGER.setUseParentHandlers(false);
66  MONITOR_LOGGER.addHandler(monitorLogHandler);
67  } catch (IOException | SecurityException ex) {
68  logger.log(Level.SEVERE, "Failed to create memory usage logger", ex); //NON-NLS
69  }
70  }
71 
75  void start() {
76  timerAction = new MonitorTimerAction();
77  timer = new Timer(INITIAL_INTERVAL_MS, timerAction);
78  timer.start();
79  }
80 
84  void stop() {
85  if (null != timer) {
86  timer.stop();
87  }
88  }
89 
95  boolean isRunning() {
96  return (null != timer && timer.isRunning());
97  }
98 
105  long getFreeSpace() {
106  try {
107  return timerAction.getFreeSpace();
108  } catch (SecurityException e) {
109  logger.log(Level.WARNING, "Error checking for free disk space on ingest data drive", e); //NON-NLS
111  }
112  }
113 
118  private class MonitorTimerAction implements ActionListener {
119 
120  private final static long MIN_FREE_DISK_SPACE = 100L * 1024 * 1024; // 100MB
121  private File root;
122 
125  Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
126  if (evt instanceof AutopsyEvent) {
127  AutopsyEvent event = (AutopsyEvent) evt;
128  if (AutopsyEvent.SourceType.LOCAL == event.getSourceType() && event.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
129  /*
130  * The new value of the event will be non-null if a new
131  * case has been opened.
132  */
133  if (null != evt.getNewValue()) {
134  findRootDirectoryForCurrentCase((Case) evt.getNewValue());
135  }
136  }
137  }
138  });
139  }
140 
146  try {
147  Case currentCase = Case.getCurrentCase();
148  findRootDirectoryForCurrentCase(currentCase);
149  } catch (IllegalStateException unused) {
150  /*
151  * Case.getCurrentCase() throws IllegalStateException when there
152  * is no case.
153  */
154  root = new File(File.separator);
156  }
157  }
158 
165  private void findRootDirectoryForCurrentCase(Case currentCase) {
166  File curDir = new File(currentCase.getCaseDirectory());
167  File parentDir = curDir.getParentFile();
168  while (null != parentDir) {
169  curDir = parentDir;
170  parentDir = curDir.getParentFile();
171  }
172  root = curDir;
174  }
175 
180  private void logMonitoredRootDirectory() {
181  logger.log(Level.INFO, "Monitoring disk space of {0}", root.getAbsolutePath()); //NON-NLS
182  }
183 
184  @Override
185  public void actionPerformed(ActionEvent e) {
186  /*
187  * Skip monitoring if ingest is not running.
188  */
189  final IngestManager manager = IngestManager.getInstance();
190  if (manager.isIngestRunning() == false) {
191  return;
192  }
193 
194  logMemoryUsage();
196 
197  if (!enoughDiskSpace()) {
198  /*
199  * Shut down ingest by cancelling all ingest jobs.
200  */
202  String diskPath = root.getAbsolutePath();
203  IngestServices.getInstance().postMessage(IngestMessage.createManagerErrorMessage(
204  NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.title", diskPath),
205  NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.msg", diskPath)));
206  MONITOR_LOGGER.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS
207  logger.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS
208  }
209  }
210 
214  private void logMemoryUsage() {
216  }
217 
221  private void logDiskSpaceUsage() {
222  final long freeSpace = root.getFreeSpace();
223  logger.log(Level.INFO, "Available disk space on drive where case dir resides is {0} (bytes)", freeSpace); //NON-NLS
224  }
225 
232  private boolean enoughDiskSpace() {
233  long freeSpace;
234  try {
235  freeSpace = getFreeSpace();
236  } catch (SecurityException e) {
237  logger.log(Level.WARNING, "Unable to check for free disk space (permission issue)", e); //NON-NLS
238  return true; //OK
239  }
240 
241  if (freeSpace == DISK_FREE_SPACE_UNKNOWN) {
242  return true;
243  } else {
244  return freeSpace > MIN_FREE_DISK_SPACE;
245  }
246  }
247 
254  private long getFreeSpace() throws SecurityException {
255  // always return "UNKNOWN", see note below
257 
258  /* NOTE: use and accuracy of this code for network drives needs to be investigated and validated
259  final long freeSpace = root.getFreeSpace();
260  if (0 == freeSpace) {
261  // Check for a network drive, some network filesystems always
262  // return zero.
263  final String monitoredPath = root.getAbsolutePath();
264  if (monitoredPath.startsWith("\\\\") || monitoredPath.startsWith("//")) {
265  return DISK_FREE_SPACE_UNKNOWN;
266  }
267  }
268  return freeSpace;*/
269  }
270  }
271 
272 }
static synchronized IngestManager getInstance()
Logger(String name, String resourceBundleName)
Definition: Logger.java:198
void postMessage(final IngestMessage message)
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:395
void cancelAllIngestJobs(IngestJob.CancellationReason reason)
static final java.util.logging.Logger MONITOR_LOGGER
static synchronized IngestServices getInstance()

Copyright © 2012-2016 Basis Technology. Generated on: Fri Sep 29 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.