Skip to content

Commit

Permalink
57 log snapshot (#81)
Browse files Browse the repository at this point in the history
Add start/lap/stop/auto-download log snapshotting feature to repo admin tool

Adds a Start log Snapshot button to the repo Log4J settings page. When clicked this dynamically creates an appender and adds it to the root logger and any other loggers that additivity disabled. This allows us to siphon off log messages into a temporary file.

The button changes to Stop log Snapshot and an Add log entry button is appended along with a text box and focus is moved to the text box.

If Add log entry is clicked without placing any text in the text box a number is logged to a fake logger supporttools.logsnapshot.Lap. Each time this button is pressed when the text box is empty the number is increased and logged. If there is any text in the text box when this button is pressed the text will be logged and the lap number is not increased.

When Stop log Snapshot is pressed the appender is removed from any loggers it was added to and it (and the underlying file) are closed. Then the contents of this file are streamed down to the user. Finally the button changes back to Start log Snapshot and the Add log entry and associated text box are removed.

If the page is reloaded during a snapshot the reference back to the temporary file is lost so there is no way to stop this instance of snapshotting. Similarly if the user starts a snapshot and then forgets to stop, we don't want an indefinite amount of log duplication. As such a customer appender is used. Each time a log entry is provided it checks if it has been open for more than 20 minutes. If so it will deregister from all loggers and close the appender.

If the user simply forgot to stop the snapshot and the appender is removed, when they click the Stop log Snapshot button, the first 20 minutes of log entries will be downloaded.

While focus is on the log entry (lap) text box if enter is pressed it will trigger the Add log entry button, similarly if the Escape key is pressed while this text box has focus, the Stop log Snapshot button is triggered.
  • Loading branch information
binduwavell authored May 14, 2017
1 parent 70557e8 commit b76a5c4
Show file tree
Hide file tree
Showing 19 changed files with 562 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@
<property name="delegate" ref="webscript.content.streamer" />
</bean>

<bean id="webscript.org.orderofthebee.support-tools.admin.ootbee-support-tools.log4j-snapshot-complete.get" class="org.orderofthebee.addons.support.tools.repo.web.scripts.LogSnapshotComplete"
parent="webscript" >
<property name="delegate" ref="webscript.content.streamer" />
</bean>

</beans>
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,7 +18,7 @@ You should have received a copy of the GNU Lesser General Public License
along with Community Support Tools. If not, see <http://www.gnu.org/licenses/>.
Linked to Alfresco
Copyright (C) 2005-2016 Alfresco Software Limited.
Copyright (C) 2005-2017 Alfresco Software Limited.
-->

Expand All @@ -39,7 +39,7 @@ Copyright (C) 2005-2016 Alfresco Software Limited.
<div class="column-full">
<div>${msg("log-settings.column.addLogger")}:
<form id="addPackageForm" action="${url.service}" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
<input name="logger" size="35" placeholder="logger-name"></input>
<input type="text" name="logger" size="35" placeholder="logger-name"></input>
<input type="hidden" name="showUnconfiguredLoggers" value="${(showUnconfiguredLoggers!false)?string}" />
<select name="level">
<option value="UNSET">${msg("log-settings.level.UNSET")?html}</option>
Expand All @@ -54,10 +54,18 @@ Copyright (C) 2005-2016 Alfresco Software Limited.
<input type="submit" value="${msg("log-settings.column.add")}" style="margin-right:1em;" />
</form>
<div class="buttons">
<@button id="tailRepoLog" label=msg("log-settings.tail") onclick=("Admin.showDialog('" + url.serviceContext + "/ootbee/admin/log4j-tail');")/>
<@button id="showLogFiles" label=msg("log-settings.logFiles") onclick=("Admin.showDialog('" + url.serviceContext + "/ootbee/admin/log4j-log-files');")/>
<@button id="resetLogSettings" label=msg("log-settings.resetAll") onclick=("AdminLS.resetLogLevel();")/>
<@button id="toggleView" label=msg(showUnconfiguredLoggers?string('log-settings.hideUnconfigured', 'log-settings.showUnconfigured')) onclick=("window.location.href = '" + url.serviceContext + "/ootbee/admin/log4j-loggers?showUnconfiguredLoggers="+ (showUnconfiguredLoggers!false)?string('false','true') + "';")/>
<div class="column-left">
<@button id="tailRepoLog" label=msg("log-settings.tail") onclick=("Admin.showDialog('" + url.serviceContext + "/ootbee/admin/log4j-tail');")/>
<@button id="showLogFiles" label=msg("log-settings.logFiles") onclick=("Admin.showDialog('" + url.serviceContext + "/ootbee/admin/log4j-log-files');")/>
<@button id="resetLogSettings" label=msg("log-settings.resetAll") onclick=("AdminLS.resetLogLevel();")/>
<@button id="toggleView" label=msg(showUnconfiguredLoggers?string('log-settings.hideUnconfigured', 'log-settings.showUnconfigured')) onclick=("window.location.href = '" + url.serviceContext + "/ootbee/admin/log4j-loggers?showUnconfiguredLoggers="+ (showUnconfiguredLoggers!false)?string('false','true') + "';")/>
</div>
<div class="column-right">
<@button id="startLogSnapshot" label=msg("log-settings.startLogSnapshot") onclick=("AdminLS.startLogSnapshot();")/>
<@button id="stopLogSnapshot" style="display:none" label=msg("log-settings.stopLogSnapshot") onclick=("AdminLS.stopLogSnapshot();")/>
<@button id="lapLogSnapshot" style="display:none" label=msg("log-settings.lapLogSnapshot") onclick=("AdminLS.lapLogSnapshot();")/>
<input id="lapMessageLogSnapshot" type="text" size="35" style="display:none" placeholder="${msg("log-settings.lapMessageLogSnapshot")}" onkeyup="return AdminLS.handleLogMessageLogSnapshotKeyUp(event);"></input>
</div>
</div>
<#if statusMessage?? && statusMessage != "">
<div id="statusmessage" class="message ${messageStatus!""}">${.now?string("HH:mm:ss")} - ${statusMessage?html!""} <a href="#" onclick="this.parentElement.style.display='none';" title="${msg("admin-console.close")}">[X]</a></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<webscript>
<shortname>Log4J Snapshot</shortname>
<description>Finish log snapshot and shows it</description>
<url>/ootbee/admin/log4j-snapshot-complete/{path}</url>
<authentication>admin</authentication>
<lifecycle>internal</lifecycle>
<transaction>none</transaction>
<family>OOTBee Support Tools</family>
</webscript>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<webscript>
<shortname>Log4J Settings - Log File - Create Snapshot</shortname>
<description>Accesses a specific Log4J log file</description>
<url>/ootbee/admin/log4j-snapshot-create</url>
<authentication>admin</authentication>
<format default="json"/>
<lifecycle>internal</lifecycle>
<transaction>none</transaction>
<family>OOTBee Support Tools</family>
</webscript>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<import resource="classpath:alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j.lib.js">

/**
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* Linked to Alfresco
* Copyright (C) 2005-2017 Alfresco Software Limited.
*/

model.snapshotLogFile = createSnapshot();
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
Linked to Alfresco
Copyright (C) 2005-2017 Alfresco Software Limited.
-->

{
"snapshotLogFile": "${snapshotLogFile}"
}
</#compress>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<webscript>
<shortname>Log4J Snapshot Lap</shortname>
<description>Log4J Snapshot Log Lap Message</description>
<url>/ootbee/admin/log4j-snapshot-lap?message={message}</url>
<format default="json" />
<authentication>admin</authentication>
<lifecycle>internal</lifecycle>
<transaction>none</transaction>
<family>OOTBee Support Tools</family>
</webscript>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<import resource="classpath:alfresco/templates/webscripts/org/orderofthebee/support-tools/admin/ootbee-support-tools/log4j.lib.js">

/**
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* Linked to Alfresco
* Copyright (C) 2005-2017 Alfresco Software Limited.
*/

logSnapshotLapMessage(args['message']);
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
Linked to Alfresco
Copyright (C) 2005-2017 Alfresco Software Limited.
-->
{}
</#compress>
Original file line number Diff line number Diff line change
@@ -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
*
Expand All @@ -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 */
Expand Down Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Loading

1 comment on commit b76a5c4

@binduwavell
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did not occur to me that when I squashed the commits from the development branch we'd lose the history of contribution that happened during the hackathon at BeeCon.

In addition to myself, Ana Gouveia and Michael Bui also worked on this effort. And of course Axel Faust provided invaluable guidance and insights.

Please sign in to comment.