Merge pull request #12988 from owncloud/logfile_download

Logfile download
This commit is contained in:
Morris Jobke 2015-01-09 00:33:22 +01:00
commit 6a5f12beca
12 changed files with 297 additions and 51 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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());

View File

@ -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,
)
);

View File

@ -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';

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
} );
});

View File

@ -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) {

View File

@ -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')

View File

@ -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">

View File

@ -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);
}
}