Merge pull request #1315 from sidheshenator/python_module_reload_and_logging

Python module reload and logging
This commit is contained in:
Brian Carrier 2015-06-05 13:16:16 -04:00
commit fd70adfc55
4 changed files with 47 additions and 36 deletions

View File

@ -70,6 +70,7 @@ public final class JythonModuleLoader {
private static <T> List<T> getInterfaceImplementations(LineFilter filter, Class<T> interfaceClass) {
List<T> objects = new ArrayList<>();
Set<File> pythonModuleDirs = new HashSet<>();
PythonInterpreter interpreter = new PythonInterpreter();
// add python modules from 'autospy/build/cluster/InternalPythonModules' folder
// which are copied from 'autopsy/*/release/InternalPythonModules' folders.
@ -90,7 +91,7 @@ public final class JythonModuleLoader {
if (line.startsWith("class ") && filter.accept(line)) { //NON-NLS
String className = line.substring(6, line.indexOf("("));
try {
objects.add( createObjectFromScript(script, className, interfaceClass));
objects.add( createObjectFromScript(interpreter, script, className, interfaceClass));
} catch (Exception ex) {
logger.log(Level.SEVERE, String.format("Failed to load %s from %s", className, script.getAbsolutePath()), ex); //NON-NLS
// NOTE: using ex.toString() because the current version is always returning null for ex.getMessage().
@ -112,21 +113,21 @@ public final class JythonModuleLoader {
return objects;
}
private static <T> T createObjectFromScript(File script, String className, Class<T> interfaceClass) {
// Make a "fresh" interpreter every time to avoid name collisions, etc.
PythonInterpreter interpreter = new PythonInterpreter();
private static <T> T createObjectFromScript(PythonInterpreter interpreter, File script, String className, Class<T> interfaceClass) {
// Add the directory where the Python script resides to the Python
// module search path to allow the script to use other scripts bundled
// with it.
interpreter.exec("import sys"); //NON-NLS
String path = Matcher.quoteReplacement(script.getParent());
interpreter.exec("sys.path.append('" + path + "')"); //NON-NLS
String moduleName = script.getName().replaceAll(".py", ""); //NON-NLS
// reload the module so that the changes made to it can be loaded.
interpreter.exec("import " + moduleName); //NON-NLS
interpreter.exec("reload(" + moduleName + ")"); //NON-NLS
// Execute the script and create an instance of the desired class.
interpreter.execfile(script.getAbsolutePath());
// Importing the appropriate class from the Py Script which contains multiple classes.
interpreter.exec("from " + script.getName().replaceAll(".py", "") + " import " + className);
interpreter.exec("from " + moduleName + " import " + className);
interpreter.exec("obj = " + className + "()"); //NON-NLS
T obj = interpreter.get("obj", interfaceClass); //NON-NLS

View File

@ -32,6 +32,7 @@
# See http://sleuthkit.org/autopsy/docs/api-docs/3.1/index.html for documentation
import jarray
import inspect
from java.lang import System
from java.util.logging import Level
from org.sleuthkit.datamodel import SleuthkitCase
@ -82,6 +83,11 @@ class SampleJythonDataSourceIngestModuleFactory(IngestModuleFactoryAdapter):
# TODO: Rename this to something more specific. Could just remove "Factory" from above name.
class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
_logger = Logger.getLogger(SampleJythonDataSourceIngestModuleFactory.moduleName)
def log(self, level, msg):
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
def __init__(self):
self.context = None
@ -94,7 +100,6 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
# raise IngestModuleException(IngestModule(), "Oh No!")
# Where the analysis is done.
# The 'dataSource' object being passed in is of type org.sleuthkit.datamodel.Content.
# See: http://www.sleuthkit.org/sleuthkit/docs/jni-docs/interfaceorg_1_1sleuthkit_1_1datamodel_1_1_content.html
@ -105,8 +110,6 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
if self.context.isJobCancelled():
return IngestModule.ProcessResult.OK
logger = Logger.getLogger(SampleJythonDataSourceIngestModuleFactory.moduleName)
# we don't know how much work there is yet
progressBar.switchToIndeterminate()
@ -121,7 +124,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
files = fileManager.findFiles(dataSource, "%test%")
numFiles = len(files)
logger.logp(Level.INFO, SampleJythonDataSourceIngestModule.__name__, "process", "found " + str(numFiles) + " files")
self.log(Level.INFO, "found " + str(numFiles) + " files")
progressBar.switchToDeterminate(numFiles)
fileCount = 0;
for file in files:
@ -130,7 +133,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
if self.context.isJobCancelled():
return IngestModule.ProcessResult.OK
logger.logp(Level.INFO, SampleJythonDataSourceIngestModule.__name__, "process", "Processing file: " + file.getName())
self.log(Level.INFO, "Processing file: " + file.getName())
fileCount += 1
# Make an artifact on the blackboard. TSK_INTERESTING_FILE_HIT is a generic type of

View File

@ -32,6 +32,7 @@
# See http://sleuthkit.org/autopsy/docs/api-docs/3.1/index.html for documentation
import jarray
import inspect
from java.lang import System
from java.util.logging import Level
from org.sleuthkit.datamodel import SleuthkitCase
@ -84,12 +85,16 @@ class SampleJythonFileIngestModuleFactory(IngestModuleFactoryAdapter):
# Looks at the attributes of the passed in file.
class SampleJythonFileIngestModule(FileIngestModule):
_logger = Logger.getLogger(SampleJythonFileIngestModuleFactory.moduleName)
def log(self, level, msg):
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
# Where any setup and configuration is done
# 'context' is an instance of org.sleuthkit.autopsy.ingest.IngestJobContext.
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_ingest_job_context.html
# TODO: Add any setup code that you need here.
def startUp(self, context):
self.logger = Logger.getLogger(SampleJythonFileIngestModuleFactory.moduleName)
self.filesFound = 0
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
@ -101,7 +106,6 @@ class SampleJythonFileIngestModule(FileIngestModule):
# See: http://www.sleuthkit.org/sleuthkit/docs/jni-docs/classorg_1_1sleuthkit_1_1datamodel_1_1_abstract_file.html
# TODO: Add your analysis code in here.
def process(self, file):
# Skip non-files
if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) or (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) or (file.isFile() == False)):
return IngestModule.ProcessResult.OK
@ -109,7 +113,7 @@ class SampleJythonFileIngestModule(FileIngestModule):
# For an example, we will flag files with .txt in the name and make a blackboard artifact.
if file.getName().find(".txt") != -1:
self.logger.logp(Level.INFO, SampleJythonFileIngestModule.__name__, "process", "Found a text file: " + file.getName())
self.log(Level.INFO, "Found a text file: " + file.getName())
self.filesFound+=1
# Make an artifact on the blackboard. TSK_INTERESTING_FILE_HIT is a generic type of
@ -125,7 +129,7 @@ class SampleJythonFileIngestModule(FileIngestModule):
for artifact in artifactList:
attributeList = artifact.getAttributes();
for attrib in attributeList:
self.logger.logp(Level.INFO, SampleJythonFileIngestModule.__name__, "process", attrib.toString())
self.log(Level.INFO, attrib.toString())
# To further the example, this code will read the contents of the file and count the number of bytes
inputStream = ReadContentInputStream(file)

View File

@ -39,6 +39,7 @@
import jarray
import inspect
from java.lang import System
from java.util.logging import Level
from javax.swing import JCheckBox
@ -109,6 +110,11 @@ class SampleFileIngestModuleWithUIFactory(IngestModuleFactoryAdapter):
# Looks at the attributes of the passed in file.
class SampleFileIngestModuleWithUI(FileIngestModule):
_logger = Logger.getLogger(SampleFileIngestModuleWithUIFactory.moduleName)
def log(self, level, msg):
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
# Autopsy will pass in the settings from the UI panel
def __init__(self, settings):
self.local_settings = settings
@ -117,13 +123,11 @@ class SampleFileIngestModuleWithUI(FileIngestModule):
# Where any setup and configuration is done
# TODO: Add any setup code that you need here.
def startUp(self, context):
self.logger = Logger.getLogger(SampleFileIngestModuleWithUIFactory.moduleName)
# As an example, determine if user configured a flag in UI
if self.local_settings.getFlag():
self.logger.logp(Level.INFO, SampleFileIngestModuleWithUI.__name__, "startUp", "flag is set")
self.log(Level.INFO, "flag is set")
else:
self.logger.logp(Level.INFO, SampleFileIngestModuleWithUI.__name__, "startUp", "flag is not set")
self.log(Level.INFO, "flag is not set")
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
# raise IngestModuleException(IngestModule(), "Oh No!")
@ -201,4 +205,3 @@ class SampleFileIngestModuleWithUISettingsPanel(IngestModuleIngestJobSettingsPan
def getSettings(self):
return self.local_settings