${msg("log-settings.column.addLogger")}:
<#if statusMessage?? && statusMessage != "">
${.now?string("HH:mm:ss")} - ${statusMessage?html!""}
[X]
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get.properties b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get.properties
index 33c2769d..f2c05d87 100644
--- a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get.properties
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get.properties
@@ -9,6 +9,11 @@ log-settings.hideUnconfigured=Hide unconfigured Loggers
log-settings.showUnconfigured=Show unconfigured Loggers
log-settings.rootLogger=(Root Logger)
+log-settings.startLogSnapshot=Start log Snapshot
+log-settings.stopLogSnapshot=Stop log Snapshot
+log-settings.lapLogSnapshot=Add log entry
+log-settings.lapMessageLogSnapshot=If not set, lap number is logged
+
log-settings.column.add=Add
log-settings.column.addLogger=Add logger
log-settings.column.loggerName=Logger name
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_de.properties b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_de.properties
index 0d80391c..4944c5b0 100644
--- a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_de.properties
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_de.properties
@@ -9,6 +9,12 @@ log-settings.hideUnconfigured=Nicht konfigurierte Logger ausblenden
log-settings.showUnconfigured=Nicht konfigurierte Logger anzeigen
log-settings.rootLogger=(Root Logger)
+# Requires translation
+log-settings.startLogSnapshot=Start log Snapshot
+log-settings.stopLogSnapshot=Stop log Snapshot
+log-settings.lapLogSnapshot=Add log entry
+log-settings.lapMessageLogSnapshot=If not set, lap number is logged
+
log-settings.column.add=Hinzuf\u00fcgen
log-settings.column.addLogger=Logger hinzuf\u00fcgen
log-settings.column.loggerName=Name des Loggers
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_en.properties b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_en.properties
index c74aa34c..7c972ed4 100644
--- a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_en.properties
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_en.properties
@@ -9,6 +9,11 @@ log-settings.hideUnconfigured=Hide unconfigured Loggers
log-settings.showUnconfigured=Show unconfigured Loggers
log-settings.rootLogger=(Root Logger)
+log-settings.startLogSnapshot=Start log Snapshot
+log-settings.stopLogSnapshot=Stop log Snapshot
+log-settings.lapLogSnapshot=Add log entry
+log-settings.lapMessageLogSnapshot=If not set, lap number is logged
+
log-settings.column.add=Add
log-settings.column.addLogger=Add logger
log-settings.column.loggerName=Logger name
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_es.properties b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_es.properties
index ef12aa5d..0c92bf90 100644
--- a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_es.properties
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_es.properties
@@ -9,6 +9,12 @@ log-settings.hideUnconfigured=Ocultar Loggers no configurados
log-settings.showUnconfigured=Mostrar Loggers no configurados
log-settings.rootLogger=(Root Logger)
+# Requires translation
+log-settings.startLogSnapshot=Start log Snapshot
+log-settings.stopLogSnapshot=Stop log Snapshot
+log-settings.lapLogSnapshot=Add log entry
+log-settings.lapMessageLogSnapshot=If not set, lap number is logged
+
log-settings.column.add=A\u00f1adir
log-settings.column.addLogger=A\u00f1adir logger
log-settings.column.loggerName=Nombre del logger
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_pt.properties b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_pt.properties
index 07c1db78..bda46725 100644
--- a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_pt.properties
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-loggers.get_pt.properties
@@ -9,6 +9,12 @@ log-settings.hideUnconfigured=Ocultar Loggers n\u00e3o configurados
log-settings.showUnconfigured=Exibir Loggers n\u00e3o configurados
log-settings.rootLogger=(Logger Ra\u00edz)
+# Requires translation
+log-settings.startLogSnapshot=Start log Snapshot
+log-settings.stopLogSnapshot=Stop log Snapshot
+log-settings.lapLogSnapshot=Add log entry
+log-settings.lapMessageLogSnapshot=If not set, lap number is logged
+
log-settings.column.add=Adicionar
log-settings.column.addLogger=Adicionar logger
log-settings.column.loggerName=Nome do logger
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-complete.get.desc.xml b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-complete.get.desc.xml
new file mode 100644
index 00000000..5b8ae3fc
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-complete.get.desc.xml
@@ -0,0 +1,10 @@
+
+
+ Log4J Snapshot
+ Finish log snapshot and shows it
+ /ootbee/admin/log4j-snapshot-complete/{path}
+ admin
+ internal
+ none
+ OOTBee Support Tools
+
\ No newline at end of file
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.desc.xml b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.desc.xml
new file mode 100644
index 00000000..687786d9
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.desc.xml
@@ -0,0 +1,11 @@
+
+
+ Log4J Settings - Log File - Create Snapshot
+ Accesses a specific Log4J log file
+ /ootbee/admin/log4j-snapshot-create
+ admin
+
+ internal
+ none
+ OOTBee Support Tools
+
\ No newline at end of file
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.js b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.js
new file mode 100644
index 00000000..615481ae
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.js
@@ -0,0 +1,27 @@
+
+
+/**
+ * Copyright (C) 2017 Bindu Wavell
+ * Copyright (C) 2017 Order of the Bee
+ *
+ * This file is part of Community Support Tools
+ *
+ * Community Support Tools is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Community Support Tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Community Support Tools. If not, see .
+ */
+/*
+ * Linked to Alfresco
+ * Copyright (C) 2005-2017 Alfresco Software Limited.
+ */
+
+model.snapshotLogFile = createSnapshot();
\ No newline at end of file
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.json.ftl b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.json.ftl
new file mode 100644
index 00000000..03d121ad
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-create.get.json.ftl
@@ -0,0 +1,29 @@
+<#compress>
+<#--
+Copyright (C) 2017 Bindu Wavell
+Copyright (C) 2017 Order of the Bee
+
+This file is part of Community Support Tools
+
+Community Support Tools is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Community Support Tools is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Community Support Tools. If not, see .
+
+Linked to Alfresco
+Copyright (C) 2005-2017 Alfresco Software Limited.
+
+-->
+
+{
+ "snapshotLogFile": "${snapshotLogFile}"
+}
+#compress>
\ No newline at end of file
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.desc.xml b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.desc.xml
new file mode 100644
index 00000000..6871ece0
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.desc.xml
@@ -0,0 +1,11 @@
+
+
+ Log4J Snapshot Lap
+ Log4J Snapshot Log Lap Message
+ /ootbee/admin/log4j-snapshot-lap?message={message}
+
+ admin
+ internal
+ none
+ OOTBee Support Tools
+
\ No newline at end of file
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.js b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.js
new file mode 100644
index 00000000..c2cb6647
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.js
@@ -0,0 +1,27 @@
+
+
+/**
+ * Copyright (C) 2017 Bindu Wavell
+ * Copyright (C) 2017 Order of the Bee
+ *
+ * This file is part of Community Support Tools
+ *
+ * Community Support Tools is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Community Support Tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Community Support Tools. If not, see .
+ */
+/*
+ * Linked to Alfresco
+ * Copyright (C) 2005-2017 Alfresco Software Limited.
+ */
+
+logSnapshotLapMessage(args['message']);
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.json.ftl b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.json.ftl
new file mode 100644
index 00000000..07fb5b5e
--- /dev/null
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j-snapshot-lap.post.json.ftl
@@ -0,0 +1,26 @@
+<#compress>
+<#--
+Copyright (C) 2017 Bindu Wavell
+Copyright (C) 2017 Order of the Bee
+
+This file is part of Community Support Tools
+
+Community Support Tools is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Community Support Tools is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Community Support Tools. If not, see .
+
+Linked to Alfresco
+Copyright (C) 2005-2017 Alfresco Software Limited.
+
+ -->
+{}
+#compress>
\ No newline at end of file
diff --git a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j.lib.js b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j.lib.js
index 0cd62d85..03601163 100644
--- a/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j.lib.js
+++ b/repository/src/main/amp/config/alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j.lib.js
@@ -1,6 +1,6 @@
/**
- * Copyright (C) 2016 Axel Faust / Markus Joos
- * Copyright (C) 2016 Order of the Bee
+ * Copyright (C) 2017 Axel Faust / Markus Joos / Bindu Wavell
+ * Copyright (C) 2017 Order of the Bee
*
* This file is part of Community Support Tools
*
@@ -19,7 +19,7 @@
*/
/*
* Linked to Alfresco
- * Copyright (C) 2005-2016 Alfresco Software Limited.
+ * Copyright (C) 2005-2017 Alfresco Software Limited.
*/
/* global formdata: false, logSettingTracker: false */
@@ -420,3 +420,56 @@ function buildLogFilesModel(useAllLoggerAppenders)
model.logFiles = logFiles;
model.locale = Packages.org.springframework.extensions.surf.util.I18NUtil.getLocale().toString();
}
+
+function getLoggersToSnapshot()
+{
+ var logger, loggers, currentLoggers, loggerRepository;
+
+ logger = Packages.org.apache.log4j.Logger.getRootLogger();
+ loggers = [logger];
+
+ loggerRepository = Packages.org.apache.log4j.LogManager.getLoggerRepository();
+ currentLoggers = loggerRepository.currentLoggers;
+ while (currentLoggers.hasMoreElements())
+ {
+ logger = currentLoggers.nextElement();
+ if (!logger.additivity)
+ {
+ loggers.push(logger);
+ }
+ }
+ return loggers;
+}
+
+/* exported createSnapshot */
+function createSnapshot()
+{
+ var snapshotLogFile, logLayout, snapshotAppender, loggers;
+
+ snapshotLogFile = Packages.org.alfresco.util.TempFileProvider.createTempFile("ootbee-support-tools-snapshot", ".log");
+ logLayout = new Packages.org.apache.log4j.PatternLayout('%d{yyyy-MM-dd} %d{ABSOLUTE} %-5p [%c] [%t] %m%n');
+ snapshotAppender = new Packages.org.orderofthebee.addons.support.tools.repo.TemporaryFileAppender(logLayout, snapshotLogFile);
+ loggers = getLoggersToSnapshot();
+ loggers.forEach(
+ function createSnapshot_connectLoggerAndAppender(logger)
+ {
+ snapshotAppender.registerAsAppender(logger);
+ }
+ );
+
+ return snapshotLogFile;
+}
+
+/* exported logSnapshotLapMessage */
+function logSnapshotLapMessage(message) {
+ var root, clazz, level, lapLogger;
+
+ root = Packages.org.apache.log4j.Logger.getRootLogger();
+ level = Packages.org.apache.log4j.Level.INFO;
+ // Fake logger that produces a good log message with the Alfresco default log format
+ clazz = 'org.orderofthebee.addons.support.tools.repo.logSnapshotLap';
+ lapLogger = root.getLogger(clazz);
+ lapLogger.setLevel(level);
+
+ lapLogger.log(level, message);
+}
\ No newline at end of file
diff --git a/repository/src/main/amp/web/ootbee-support-tools/css/admin.css b/repository/src/main/amp/web/ootbee-support-tools/css/admin.css
index 3a421216..afd9784f 100644
--- a/repository/src/main/amp/web/ootbee-support-tools/css/admin.css
+++ b/repository/src/main/amp/web/ootbee-support-tools/css/admin.css
@@ -64,4 +64,11 @@ table.results.dataTable
table.data td.numericalCellValue
{
text-align: right;
+}
+
+input[type="text"]
+{
+ height: 24px;
+ padding-left: 5px;
+ padding-right: 5px;
}
\ No newline at end of file
diff --git a/repository/src/main/amp/web/ootbee-support-tools/js/log-settings.js b/repository/src/main/amp/web/ootbee-support-tools/js/log-settings.js
index 3318e85b..aeb433d4 100644
--- a/repository/src/main/amp/web/ootbee-support-tools/js/log-settings.js
+++ b/repository/src/main/amp/web/ootbee-support-tools/js/log-settings.js
@@ -1,6 +1,6 @@
/**
- * Copyright (C) 2016 Axel Faust / Markus Joos
- * Copyright (C) 2016 Order of the Bee
+ * Copyright (C) 2017 Axel Faust / Markus Joos / Michael Bui / Bindu Wavell
+ * Copyright (C) 2017 Order of the Bee
*
* This file is part of Community Support Tools
*
@@ -20,7 +20,7 @@
*/
/*
* Linked to Alfresco Copyright
- * (C) 2005-2016 Alfresco Software Limited.
+ * (C) 2005-2017 Alfresco Software Limited.
*/
/* global Admin: false */
@@ -32,8 +32,11 @@ var AdminLS = AdminLS || {};
(function()
{
- var serviceContext;
+ var KEYCODE_ENTER = 13;
+ var KEYCODE_ESC = 27;
+ var serviceContext, snapshotLogFile, snapshotLapNumber;
+
AdminLS.setServiceContext = function setServiceContext(context)
{
serviceContext = context;
@@ -51,5 +54,68 @@ var AdminLS = AdminLS || {};
}
});
};
+
+ AdminLS.startLogSnapshot = function startLogSnapshot()
+ {
+ Admin.request({
+ url : serviceContext + '/ootbee/admin/log4j-snapshot-create',
+ method : 'GET',
+ fnSuccess : function startLogSnapshot_success(res)
+ {
+ if (res.responseJSON)
+ {
+ snapshotLogFile = res.responseJSON.snapshotLogFile;
+ document.getElementById("startLogSnapshot").style.display = 'none';
+ document.getElementById("stopLogSnapshot").style.display = 'inline';
+ document.getElementById("lapLogSnapshot").style.display = 'inline';
+ document.getElementById("lapMessageLogSnapshot").style.display = 'inline';
+ document.getElementById("lapMessageLogSnapshot").focus();
+ snapshotLapNumber = 1;
+ }
+ }
+ });
+ };
+
+ AdminLS.stopLogSnapshot = function stopLogSnapshot()
+ {
+ window.open(serviceContext + '/ootbee/admin/log4j-snapshot-complete/'+snapshotLogFile+'?a=true','_blank');
+ document.getElementById("startLogSnapshot").style.display = 'inline';
+ document.getElementById("stopLogSnapshot").style.display = 'none';
+ document.getElementById("lapLogSnapshot").style.display = 'none';
+ document.getElementById("lapMessageLogSnapshot").style.display = 'none';
+ };
+ AdminLS.lapLogSnapshot = function lapLogSnapshot()
+ {
+ var inputEl = document.getElementById("lapMessageLogSnapshot");
+ var message = inputEl.value;
+ if (!message)
+ {
+ message = snapshotLapNumber++;
+ }
+ Admin.request({
+ url : serviceContext + '/ootbee/admin/log4j-snapshot-lap?message=' + message,
+ method : 'POST',
+ fnSuccess : function lapLogSnapshot_success()
+ {
+ inputEl.value = '';
+ inputEl.focus();
+ }
+ });
+ };
+
+ AdminLS.handleLogMessageLogSnapshotKeyUp = function handleLogMessageLogSnapshotKeyUp(event)
+ {
+ if (event.keyCode === KEYCODE_ENTER) {
+ event.preventDefault();
+ document.getElementById("lapLogSnapshot").click();
+ return false;
+ }
+ if (event.keyCode === KEYCODE_ESC) {
+ event.preventDefault();
+ document.getElementById("stopLogSnapshot").click();
+ return false;
+ }
+ return true;
+ };
}());
diff --git a/repository/src/main/java/org/orderofthebee/addons/support/tools/repo/TemporaryFileAppender.java b/repository/src/main/java/org/orderofthebee/addons/support/tools/repo/TemporaryFileAppender.java
new file mode 100644
index 00000000..685f5581
--- /dev/null
+++ b/repository/src/main/java/org/orderofthebee/addons/support/tools/repo/TemporaryFileAppender.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (C) 2017 Bindu Wavell
+ * Copyright (C) 2017 Order of the Bee
+ *
+ * This file is part of Community Support Tools
+ *
+ * Community Support Tools is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Community Support Tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Community Support Tools. If not, see
+ * .
+ */
+package org.orderofthebee.addons.support.tools.repo;
+
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.Logger;
+import org.apache.log4j.helpers.LogLog;
+import org.apache.log4j.spi.LoggingEvent;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * A FileAppender that will auto-close and unregister itself after 20 minutes.
+ *
+ * @author Bindu Wavell bindu@ziaconsulting.com
+ */
+public class TemporaryFileAppender extends FileAppender
+{
+ // 20 minutes after logger is created, we assume the UI lost access and automatically deregister this appender
+ private static final long AUTO_DEREGISTRATION_TIMEOUT = 1000 * 60 * 20;
+
+ protected final List appendedToLoggers = new ArrayList<>();
+
+ protected final Lock closingLock = new ReentrantLock();
+
+ protected final long creationTimestamp;
+
+ public
+ TemporaryFileAppender(Layout layout, String filename) throws IOException
+ {
+ super(layout, filename);
+ this.creationTimestamp = System.currentTimeMillis();
+ }
+
+ /**
+ * Assuming we have not timed out, does the usual. If we have timed out then deregisters
+ * appender from previously registered loggers and closes the appender. If the appender is
+ * closed then the append is simply ignored (parent would log a warning.)
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void append(final LoggingEvent event)
+ {
+ final boolean active = !this.closed && (System.currentTimeMillis() - this.creationTimestamp) < AUTO_DEREGISTRATION_TIMEOUT;
+ if (active)
+ {
+ super.append(event);
+ } else {
+ if (!this.closed)
+ {
+ if (closingLock.tryLock())
+ {
+ try
+ {
+ LogLog.warn("Automatically deregistering " + this.fileName + " appender after timeout exceeded.");
+ this.removeAppenderFromLoggers();
+ this.close();
+ } finally {
+ closingLock.unlock();
+ }
+ }
+ // If we can't grab the closing lock we can assume another thread is
+ // already closing stuff down and we can start ignoring append calls.
+ }
+ }
+ }
+
+ /**
+ * Add this appender to a logger and then remember the logger so we can remove ourselves from
+ * all registered loggers when we are done.
+ */
+ public void registerAsAppender(final Logger logger)
+ {
+ synchronized (this.appendedToLoggers)
+ {
+ logger.addAppender(this);
+ this.appendedToLoggers.add(logger);
+ }
+ }
+
+ /**
+ * Makes sure appender is removed from all loggers where it was previously registered.
+ */
+ public void removeAppenderFromLoggers()
+ {
+ synchronized (this.appendedToLoggers)
+ {
+ for (Logger logger : this.appendedToLoggers)
+ {
+ logger.removeAppender(this);
+ }
+ this.appendedToLoggers.clear();
+ }
+ }
+}
diff --git a/repository/src/main/java/org/orderofthebee/addons/support/tools/repo/web/scripts/LogSnapshotComplete.java b/repository/src/main/java/org/orderofthebee/addons/support/tools/repo/web/scripts/LogSnapshotComplete.java
new file mode 100644
index 00000000..c108c6e9
--- /dev/null
+++ b/repository/src/main/java/org/orderofthebee/addons/support/tools/repo/web/scripts/LogSnapshotComplete.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (C) 2017 Ana Gouveia / Bindu Wavell
+ * Copyright (C) 2017 Order of the Bee
+ *
+ * This file is part of Community Support Tools
+ *
+ * Community Support Tools is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Community Support Tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Community Support Tools. If not, see
+ * .
+ */
+package org.orderofthebee.addons.support.tools.repo.web.scripts;
+
+import org.alfresco.repo.web.scripts.content.ContentStreamer;
+import org.apache.log4j.Appender;
+import org.apache.log4j.Logger;
+import org.orderofthebee.addons.support.tools.repo.TemporaryFileAppender;
+import org.springframework.extensions.webscripts.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Given the path to a temporary log file created with the log4j-snapshot-create webscript, we
+ * attempt to locate an associated {@link TemporaryFileAppender}. If we find it, it is
+ * deregistered from all loggers it was added to and then closed. If the file at the provided
+ * path exists and is a valid log snapshot file, we stream the contents out otherwise we
+ * throw a WebScriptException.
+ *
+ * @author Ana Gouveia
+ * @author Bindu Wavell bindu@ziaconsulting.com
+ */
+public class LogSnapshotComplete extends AbstractLogFileWebScript
+{
+ protected ContentStreamer delegate;
+
+ public void setDelegate(final ContentStreamer delegate)
+ {
+ this.delegate = delegate;
+ }
+
+ /**
+ * Gets the appender, removes it from all the loggers and streams the content back.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
+ {
+ final String servicePath = req.getServicePath();
+ final String matchPath = req.getServiceMatch().getPath();
+ final String fileAppenderPathStr = servicePath.substring(servicePath.indexOf(matchPath) + matchPath.length());
+ final Path fileAppenderPath = Paths.get(fileAppenderPathStr);
+
+ final Map model = new HashMap();
+ final Status status = new Status();
+ final Cache cache = new Cache(this.getDescription().getRequiredCache());
+ model.put("status", status);
+ model.put("cache", cache);
+
+ final String attachParam = req.getParameter("a");
+ final boolean attach = attachParam != null && Boolean.parseBoolean(attachParam);
+
+ Enumeration appenders = Logger.getRootLogger().getAllAppenders();
+ TemporaryFileAppender snapshotAppender = null;
+
+ // Find the TemporaryFileAppender that writes to this file
+ while (appenders.hasMoreElements())
+ {
+ Appender appender = (Appender) appenders.nextElement();
+ if (appender instanceof TemporaryFileAppender)
+ {
+ TemporaryFileAppender fileAppender = (TemporaryFileAppender) appender;
+ if (fileAppender.getFile().equals(fileAppenderPathStr))
+ {
+ snapshotAppender = fileAppender;
+ }
+ }
+ }
+
+
+ // If found, remove the appender from all loggers and close it
+ if (snapshotAppender != null)
+ {
+ snapshotAppender.removeAppenderFromLoggers();
+ snapshotAppender.close();
+ }
+
+ // In any event, if the file is valid we can stream it out (if not, a WebScriptException will be thrown.)
+ final String fileName = fileAppenderPath.getFileName().toString();
+ if (!fileName.matches("^ootbee-support-tools-snapshot.*\\.log$"))
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "The path " + fileAppenderPathStr + " is invalid for a snapshot log file.");
+ }
+ final File file = fileAppenderPath.toFile();
+ if (!file.exists())
+ {
+ throw new WebScriptException(Status.STATUS_NOT_FOUND,
+ "There is no file at " + fileAppenderPathStr + ".");
+ }
+ // TODO(bwavell): Consider if we should create a temp file and validate the paths are the same.
+
+ this.delegate.streamContent(req, res, file, file.lastModified(), attach, file.getName(), model);
+ }
+}