Merge pull request #12988 from owncloud/logfile_download
Logfile download
This commit is contained in:
commit
6a5f12beca
|
@ -111,7 +111,7 @@ class OC_Log_Owncloud {
|
|||
$entriesCount = 0;
|
||||
$lines = 0;
|
||||
// Loop through each character of the file looking for new lines
|
||||
while ($pos >= 0 && $entriesCount < $limit) {
|
||||
while ($pos >= 0 && ($limit === null ||$entriesCount < $limit)) {
|
||||
fseek($handle, $pos);
|
||||
$ch = fgetc($handle);
|
||||
if ($ch == "\n" || $pos == 0) {
|
||||
|
@ -141,4 +141,11 @@ class OC_Log_Owncloud {
|
|||
}
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getLogFilePath() {
|
||||
return self::$logFile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Georg Ehrke
|
||||
* @copyright 2014 Georg Ehrke <georg@ownCloud.com>
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCP\AppFramework\Http;
|
||||
|
||||
class DataDownloadResponse extends DownloadResponse {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* Creates a response that prompts the user to download the text
|
||||
* @param string $data text to be downloaded
|
||||
* @param string $filename the name that the downloaded file should have
|
||||
* @param string $contentType the mimetype that the downloaded file should have
|
||||
*/
|
||||
public function __construct($data, $filename, $contentType) {
|
||||
$this->data = $data;
|
||||
parent::__construct($filename, $contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*/
|
||||
public function setData($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,14 @@ OC_App::setActiveNavigationEntry("admin");
|
|||
|
||||
$template = new OC_Template('settings', 'admin', 'user');
|
||||
|
||||
$entries = OC_Log_Owncloud::getEntries(3);
|
||||
$entriesRemaining = count(OC_Log_Owncloud::getEntries(4)) > 3;
|
||||
$showLog = (\OC::$server->getConfig()->getSystemValue('log_type', 'owncloud') === 'owncloud');
|
||||
$numEntriesToLoad = 3;
|
||||
$entries = OC_Log_Owncloud::getEntries($numEntriesToLoad + 1);
|
||||
$entriesRemaining = count($entries) > $numEntriesToLoad;
|
||||
$entries = array_slice($entries, 0, $numEntriesToLoad);
|
||||
$logFilePath = OC_Log_Owncloud::getLogFilePath();
|
||||
$doesLogFileExist = file_exists($logFilePath);
|
||||
$logFileSize = filesize($logFilePath);
|
||||
$config = \OC::$server->getConfig();
|
||||
$appConfig = \OC::$server->getAppConfig();
|
||||
|
||||
|
@ -31,6 +37,9 @@ $template->assign('mail_smtpname', $config->getSystemValue("mail_smtpname", ''))
|
|||
$template->assign('mail_smtppassword', $config->getSystemValue("mail_smtppassword", ''));
|
||||
$template->assign('entries', $entries);
|
||||
$template->assign('entriesremain', $entriesRemaining);
|
||||
$template->assign('logFileSize', $logFileSize);
|
||||
$template->assign('doesLogFileExist', $doesLogFileExist);
|
||||
$template->assign('showLog', $showLog);
|
||||
$template->assign('readOnlyConfigEnabled', OC_Helper::isReadOnlyConfigEnabled());
|
||||
$template->assign('isLocaleWorking', OC_Util::isSetLocaleWorking());
|
||||
$template->assign('isPhpCharSetUtf8', OC_Util::isPhpCharSetUtf8());
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012, Robin Appelman <icewind1991@gmail.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
OC_JSON::checkAdminUser();
|
||||
|
||||
$count=(isset($_GET['count']))?$_GET['count']:50;
|
||||
$offset=(isset($_GET['offset']))?$_GET['offset']:0;
|
||||
|
||||
$entries=OC_Log_Owncloud::getEntries($count, $offset);
|
||||
$data = array();
|
||||
|
||||
OC_JSON::success(
|
||||
array(
|
||||
"data" => $entries,
|
||||
"remain" => count(OC_Log_Owncloud::getEntries(1, $offset + $count)) !== 0,
|
||||
)
|
||||
);
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
OC_Util::checkAdminUser();
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
OC_Config::setValue( 'loglevel', $_POST['level'] );
|
||||
|
||||
echo 'true';
|
|
@ -12,6 +12,7 @@ namespace OC\Settings;
|
|||
|
||||
use OC\Settings\Controller\AppSettingsController;
|
||||
use OC\Settings\Controller\GroupsController;
|
||||
use OC\Settings\Controller\LogSettingsController;
|
||||
use OC\Settings\Controller\MailSettingsController;
|
||||
use OC\Settings\Controller\SecuritySettingsController;
|
||||
use OC\Settings\Controller\UsersController;
|
||||
|
@ -91,6 +92,15 @@ class Application extends App {
|
|||
$c->query('URLGenerator')
|
||||
);
|
||||
});
|
||||
$container->registerService('LogSettingsController', function(IContainer $c) {
|
||||
return new LogSettingsController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('Config'),
|
||||
$c->query('L10N'),
|
||||
$c->query('TimeFactory')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Georg Ehrke
|
||||
* @copyright 2014 Georg Ehrke <georg@ownCloud.com>
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Settings\Controller;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\DataDownloadResponse;
|
||||
use OCP\IL10N;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IRequest;
|
||||
use OCP\IConfig;
|
||||
|
||||
/**
|
||||
* Class LogSettingsController
|
||||
*
|
||||
* @package OC\Settings\Controller
|
||||
*/
|
||||
class LogSettingsController extends Controller {
|
||||
/**
|
||||
* @var \OCP\IConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \OCP\IL10N
|
||||
*/
|
||||
private $l10n;
|
||||
|
||||
/**
|
||||
* @var \OCP\ITimeFactory
|
||||
*/
|
||||
private $timefactory;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param IConfig $config
|
||||
*/
|
||||
public function __construct($appName,
|
||||
IRequest $request,
|
||||
IConfig $config,
|
||||
IL10N $l10n,
|
||||
ITimeFactory $timeFactory) {
|
||||
|
||||
parent::__construct($appName, $request);
|
||||
$this->config = $config;
|
||||
$this->l10n = $l10n;
|
||||
$this->timefactory = $timeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* set log level for logger
|
||||
*
|
||||
* @param int $level
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function setLogLevel($level) {
|
||||
if ($level < 0 || $level > 4) {
|
||||
return new JSONResponse([
|
||||
'message' => (string) $this->l10n->t('log-level out of allowed range'),
|
||||
], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$this->config->setSystemValue('loglevel', $level);
|
||||
return new JSONResponse([
|
||||
'level' => $level,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* get log entries from logfile
|
||||
*
|
||||
* @param int $count
|
||||
* @param int $offset
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function getEntries($count=50, $offset=0) {
|
||||
return new JSONResponse([
|
||||
'data' => \OC_Log_Owncloud::getEntries($count, $offset),
|
||||
'remain' => count(\OC_Log_Owncloud::getEntries(1, $offset + $count)) !== 0,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* download logfile
|
||||
*
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return DataDownloadResponse
|
||||
*/
|
||||
public function download() {
|
||||
return new DataDownloadResponse(
|
||||
json_encode(\OC_Log_Owncloud::getEntries(null, null)),
|
||||
$this->getFilenameForDownload(),
|
||||
'application/json'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get filename for the logfile that's being downloaded
|
||||
*
|
||||
* @param int $timestamp (defaults to time())
|
||||
* @return string
|
||||
*/
|
||||
private function getFilenameForDownload($timestamp=null) {
|
||||
$instanceId = $this->config->getSystemValue('instanceid');
|
||||
|
||||
$filename = implode([
|
||||
'ownCloud',
|
||||
$instanceId,
|
||||
(!is_null($timestamp)) ? $timestamp : $this->timefactory->getTime()
|
||||
], '-');
|
||||
$filename .= '.log';
|
||||
|
||||
return $filename;
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ $(document).ready(function(){
|
|||
|
||||
|
||||
$('#loglevel').change(function(){
|
||||
$.post(OC.filePath('settings','ajax','setloglevel.php'), { level: $(this).val() },function(){
|
||||
$.post(OC.generateUrl('/settings/admin/log/level'), {level: $(this).val()},function(){
|
||||
OC.Log.reload();
|
||||
} );
|
||||
});
|
||||
|
|
|
@ -20,14 +20,12 @@ OC.Log = {
|
|||
loaded: 3,//are initially loaded
|
||||
getMore: function (count) {
|
||||
count = count || 10;
|
||||
$.get(OC.filePath('settings', 'ajax', 'getlog.php'), {offset: OC.Log.loaded, count: count}, function (result) {
|
||||
if (result.status === 'success') {
|
||||
OC.Log.addEntries(result.data);
|
||||
if (!result.remain) {
|
||||
$('#moreLog').hide();
|
||||
}
|
||||
$('#lessLog').show();
|
||||
$.get(OC.generateUrl('/settings/admin/log/entries'), {offset: OC.Log.loaded, count: count}, function (result) {
|
||||
OC.Log.addEntries(result.data);
|
||||
if (!result.remain) {
|
||||
$('#moreLog').hide();
|
||||
}
|
||||
$('#lessLog').show();
|
||||
});
|
||||
},
|
||||
showLess: function (count) {
|
||||
|
|
|
@ -14,7 +14,7 @@ $application->registerRoutes($this, array(
|
|||
'groups' => array('url' => '/settings/users/groups'),
|
||||
'users' => array('url' => '/settings/users/users')
|
||||
),
|
||||
'routes' =>array(
|
||||
'routes' => array(
|
||||
array('name' => 'MailSettings#setMailSettings', 'url' => '/settings/admin/mailsettings', 'verb' => 'POST'),
|
||||
array('name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'),
|
||||
array('name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'),
|
||||
|
@ -24,6 +24,9 @@ $application->registerRoutes($this, array(
|
|||
array('name' => 'SecuritySettings#enforceSSLForSubdomains', 'url' => '/settings/admin/security/ssl/subdomains', 'verb' => 'POST'),
|
||||
array('name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'),
|
||||
array('name' => 'Users#setMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'),
|
||||
array('name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'),
|
||||
array('name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'),
|
||||
array('name' => 'LogSettings#download', 'url' => '/settings/admin/log/download', 'verb' => 'GET'),
|
||||
)
|
||||
));
|
||||
|
||||
|
@ -87,10 +90,6 @@ $this->create('settings_ajax_uninstallapp', '/settings/ajax/uninstallapp.php')
|
|||
$this->create('settings_ajax_navigationdetect', '/settings/ajax/navigationdetect.php')
|
||||
->actionInclude('settings/ajax/navigationdetect.php');
|
||||
// admin
|
||||
$this->create('settings_ajax_getlog', '/settings/ajax/getlog.php')
|
||||
->actionInclude('settings/ajax/getlog.php');
|
||||
$this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php')
|
||||
->actionInclude('settings/ajax/setloglevel.php');
|
||||
$this->create('settings_ajax_excludegroups', '/settings/ajax/excludegroups.php')
|
||||
->actionInclude('settings/ajax/excludegroups.php');
|
||||
$this->create('settings_ajax_checksetup', '/settings/ajax/checksetup')
|
||||
|
|
|
@ -462,6 +462,7 @@ if ($_['suggestedOverwriteCliUrl']) {
|
|||
<option value='<?php p($i)?>' <?php p($selected) ?>><?php p($levelLabels[$i])?></option>
|
||||
<?php endfor;?>
|
||||
</select>
|
||||
<?php if ($_['showLog'] && $_['doesLogFileExist']): ?>
|
||||
<table id="log" class="grid">
|
||||
<?php foreach ($_['entries'] as $entry): ?>
|
||||
<tr>
|
||||
|
@ -484,11 +485,20 @@ if ($_['suggestedOverwriteCliUrl']) {
|
|||
</tr>
|
||||
<?php endforeach;?>
|
||||
</table>
|
||||
<?php if ($_['logFileSize'] > 0): ?>
|
||||
<a href="<?php print_unescaped(OC::$server->getURLGenerator()->linkToRoute('settings.LogSettings.download')); ?>" class="button" id="downloadLog"><?php p($l->t('Download logfile'));?></a>
|
||||
<?php endif; ?>
|
||||
<?php if ($_['entriesremain']): ?>
|
||||
<input id="moreLog" type="button" value="<?php p($l->t('More'));?>...">
|
||||
<input id="lessLog" type="button" value="<?php p($l->t('Less'));?>...">
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($_['logFileSize'] > (100 * 1024 * 1024)): ?>
|
||||
<br>
|
||||
<em>
|
||||
<?php p($l->t('The logfile is bigger than 100MB. Downloading it may take some time!')); ?>
|
||||
</em>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Georg Ehrke
|
||||
* @copyright 2014 Georg Ehrke <georg@ownCloud.com>
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace Test\Settings\Controller;
|
||||
|
||||
use \OC\Settings\Application;
|
||||
|
||||
/**
|
||||
* @package OC\Settings\Controller
|
||||
*/
|
||||
class LogSettingsControllerTest extends \Test\TestCase {
|
||||
|
||||
/** @var \OCP\AppFramework\IAppContainer */
|
||||
private $container;
|
||||
|
||||
/** @var LogSettingsController */
|
||||
private $logSettingsController;
|
||||
|
||||
protected function setUp() {
|
||||
$app = new Application();
|
||||
$this->container = $app->getContainer();
|
||||
$this->container['Config'] = $this->getMockBuilder('\OCP\IConfig')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->container['AppName'] = 'settings';
|
||||
$this->logSettingsController = $this->container['LogSettingsController'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider logLevelData
|
||||
*/
|
||||
public function testSetLogLevel($level, $inRange) {
|
||||
if ($inRange) {
|
||||
$this->container['Config']
|
||||
->expects($this->once())
|
||||
->method('setSystemValue')
|
||||
->with('loglevel', $level);
|
||||
}
|
||||
|
||||
$response = $this->logSettingsController->setLogLevel($level)->getData();
|
||||
|
||||
if ($inRange) {
|
||||
$expectedResponse = ['level' => $level];
|
||||
} else {
|
||||
$expectedResponse = ['message' => 'log-level out of allowed range'];
|
||||
}
|
||||
|
||||
$this->assertSame($expectedResponse, $response);
|
||||
}
|
||||
|
||||
public function logLevelData() {
|
||||
return [
|
||||
[-1, false],
|
||||
[0, true],
|
||||
[1, true],
|
||||
[2, true],
|
||||
[3, true],
|
||||
[4, true],
|
||||
[5, false],
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetFilenameForDownload() {
|
||||
$timestamp = 42;
|
||||
$this->container['Config']
|
||||
->expects($this->once())
|
||||
->method('getSystemValue')
|
||||
->with('instanceid')
|
||||
->will($this->returnValue('0xF'));
|
||||
$filename = \Test_Helper::invokePrivate($this->logSettingsController, 'getFilenameForDownload', [$timestamp]);
|
||||
|
||||
$this->assertSame('ownCloud-0xF-42.log', $filename);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue