diff --git a/core/js/js.js b/core/js/js.js
index 6da9c29e69380fa52bc0d9fbc0ab494082cdddd3..076fbf04c783efbb82249aef1ae9aa5afd4985fe 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -444,4 +444,37 @@ $.fn.filterAttr = function(attr_name, attr_value) {
    return this.filter(function() { return $(this).attr(attr_name) === attr_value; });
 };
 
+function humanFileSize(bytes){
+	if( bytes < 1024 ){
+		return bytes+' B';
+	}
+	bytes = Math.round(bytes / 1024, 1 );
+	if( bytes < 1024 ){
+		return bytes+' kB';
+	}
+	bytes = Math.round( bytes / 1024, 1 );
+	if( bytes < 1024 ){
+		return bytes+' MB';
+	}
+	
+	// Wow, heavy duty for owncloud
+	bytes = Math.round( bytes / 1024, 1 );
+	return bytes+' GB';
+}
 
+function simpleFileSize(bytes) {
+	mbytes = Math.round(bytes/(1024*1024/10))/10;
+	if(bytes == 0) { return '0'; }
+	else if(mbytes < 0.1) { return '< 0.1'; }
+	else if(mbytes > 1000) { return '> 1000'; }
+	else { return mbytes.toFixed(1); }
+}
+
+function formatDate(date){
+	if(typeof date=='number'){
+		date=new Date(date);
+	}
+	var monthNames = [ t('files','January'), t('files','February'), t('files','March'), t('files','April'), t('files','May'), t('files','June'),
+	t('files','July'), t('files','August'), t('files','September'), t('files','October'), t('files','November'), t('files','December') ];
+	return monthNames[date.getMonth()]+' '+date.getDate()+', '+date.getFullYear()+', '+((date.getHours()<10)?'0':'')+date.getHours()+':'+date.getMinutes();
+}
diff --git a/files/js/files.js b/files/js/files.js
index 9f1f5368df05f449042285dc57ec1ee0a8ba5c17..f5dc40ad45d286808c4f1f2a5e9d2814522971e4 100644
--- a/files/js/files.js
+++ b/files/js/files.js
@@ -387,39 +387,6 @@ function updateBreadcrumb(breadcrumbHtml) {
 	$('p.nav').empty().html(breadcrumbHtml);
 }
 
-function humanFileSize(bytes){
-	if( bytes < 1024 ){
-		return bytes+' B';
-	}
-	bytes = Math.round(bytes / 1024, 1 );
-	if( bytes < 1024 ){
-		return bytes+' kB';
-	}
-	bytes = Math.round( bytes / 1024, 1 );
-	if( bytes < 1024 ){
-		return bytes+' MB';
-	}
-	
-	// Wow, heavy duty for owncloud
-	bytes = Math.round( bytes / 1024, 1 );
-	return bytes+' GB';
-}
-
-function simpleFileSize(bytes) {
-	mbytes = Math.round(bytes/(1024*1024/10))/10;
-	if(bytes == 0) { return '0'; }
-	else if(mbytes < 0.1) { return '< 0.1'; }
-	else if(mbytes > 1000) { return '> 1000'; }
-	else { return mbytes.toFixed(1); }
-}
-
-function formatDate(date){
-	var monthNames = [ t('files','January'), t('files','February'), t('files','March'), t('files','April'), t('files','May'), t('files','June'),
-	t('files','July'), t('files','August'), t('files','September'), t('files','October'), t('files','November'), t('files','December') ];
-	return monthNames[date.getMonth()]+' '+date.getDate()+', '+date.getFullYear()+', '+((date.getHours()<10)?'0':'')+date.getHours()+':'+date.getMinutes();
-}
-
-
 //options for file drag/dropp
 var dragOptions={
 	distance: 20, revert: 'invalid', opacity: 0.7,
diff --git a/lib/log.php b/lib/log.php
index 446ddd48848c3809485245f11f78fb51624e0566..4e450a027f5367289a2cc67697f3d9c7b00e4886 100644
--- a/lib/log.php
+++ b/lib/log.php
@@ -3,7 +3,7 @@
  * ownCloud
  *
  * @author Robin Appelman
- * @copyright 2011 Robin Appelman icewind1991@gmail.com
+ * @copyright 2012 Robin Appelman icewind1991@gmail.com
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -50,25 +50,29 @@ class OC_Log{
 			fclose($fh);
 		}
 	}
-	
-	public static function getEntries(){
+
+	/**
+	 * get entries from the log in reverse chronological order
+	 * @param int limit
+	 * @param int offset
+	 * @return array
+	 */
+	public static function getEntries($limit=50,$offset=0){
 		$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
 		$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
 		$entries=array();
 		if(!file_exists($logFile)){
 			return array();
 		}
-		$fh=fopen($logFile,'r');
-		if($fh === false){ // Unable to read log file!
+		$contents=file($logFile);
+		if(!$contents){//error while reading log
 			return array();
 		}
-		while(!feof($fh)){
-			$line=fgets($fh);
-			if($line){
-				$entries[]=json_decode($line);
-			}
+		$end=max(count($contents)-$offset-1,0);
+		$start=max($end-$limit,0);
+		for($i=$end;$i>$start;$i--){
+			$entries[]=json_decode($contents[$i]);
 		}
-		fclose($fh);
 		return $entries;
 	}
 }
diff --git a/settings/ajax/getlog.php b/settings/ajax/getlog.php
new file mode 100644
index 0000000000000000000000000000000000000000..600ebefcecef77d5f5ae8c9184ec964d4b60f9b1
--- /dev/null
+++ b/settings/ajax/getlog.php
@@ -0,0 +1,17 @@
+<?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.
+ */
+
+// Init owncloud
+require_once('../../lib/base.php');
+
+OC_JSON::checkAdminUser();
+
+$count=(isset($_GET['count']))?$_GET['count']:50;
+$offset=(isset($_GET['offset']))?$_GET['offset']:0;
+
+$entries=OC_Log::getEntries($count,$offset);
+OC_JSON::success(array("data" => $entries));
diff --git a/settings/ajax/setquota.php b/settings/ajax/setquota.php
index dc87625a05d2d6119ccff6515749233f8a9a2b88..f59017600ac5b991069a2b057ed63fcea14cb7e0 100644
--- a/settings/ajax/setquota.php
+++ b/settings/ajax/setquota.php
@@ -1,4 +1,9 @@
 <?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.
+ */
 
 // Init owncloud
 require_once('../../lib/base.php');
diff --git a/settings/css/settings.css b/settings/css/settings.css
index 7a5873bb4d22ed827fc8d12fb3b92e594a09bee9..e80de0f1ad23ab09007794b9d8b80c068df97dc5 100644
--- a/settings/css/settings.css
+++ b/settings/css/settings.css
@@ -40,3 +40,6 @@ select.quota.active { background: #fff; }
 li { color:#888; }
 li.active { color:#000; }
 span.version { margin-left:3em; color:#ddd; }
+
+/* LOF */
+#log { white-space:normal; }
\ No newline at end of file
diff --git a/settings/js/log.js b/settings/js/log.js
new file mode 100644
index 0000000000000000000000000000000000000000..3814d9c10bf449d2a53fa3aae4ff4f682932601a
--- /dev/null
+++ b/settings/js/log.js
@@ -0,0 +1,46 @@
+/**
+ * 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.Log={
+	levels:['Debug','Info','Warning','Error','Fatal'],
+	loaded:50,//are initially loaded
+	getMore:function(){
+		$.get(OC.filePath('settings','ajax','getlog.php'),{offset:OC.Log.loaded},function(result){
+			if(result.status=='success'){
+				OC.Log.addEntries(result.data);
+			}
+		});
+		OC.Log.loaded+=50;
+	},
+	addEntries:function(entries){
+		for(var i=0;i<entries.length;i++){
+			var entry=entries[i];
+			var row=$('<tr/>');
+			var levelTd=$('<td/>');
+			levelTd.text(OC.Log.levels[entry.level]);
+			row.append(levelTd);
+			
+			var appTd=$('<td/>');
+			appTd.text(entry.app);
+			row.append(appTd);
+			
+			var messageTd=$('<td/>');
+			messageTd.text(entry.message);
+			row.append(messageTd);
+			
+			var timeTd=$('<td/>');
+			timeTd.text(formatDate(entry.time));
+			row.append(timeTd);
+			$('#log').append(row);
+		}
+	}
+}
+
+$(document).ready(function(){
+	$('#moreLog').click(function(){
+		OC.Log.getMore();
+	})
+});
diff --git a/settings/log.php b/settings/log.php
index 21303c2170ffeb6dde86bf5151dd68a9cc83829d..946f2b6f8e5678b428b326cf021dcac1842c4b1a 100644
--- a/settings/log.php
+++ b/settings/log.php
@@ -3,7 +3,7 @@
  * ownCloud
  *
  * @author Robin Appelman
- * @copyright 2011 Robin Appelman icewind1991@gmail.com
+ * @copyright 2012 Robin Appelman icewind1991@gmail.com
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -30,6 +30,9 @@ OC_App::setActiveNavigationEntry( "core_log" );
 
 $entries=OC_Log::getEntries();
 
+OC_Util::addScript('settings','log');
+OC_Util::addStyle('settings','settings');
+
 function compareEntries($a,$b){
 	return $b->time - $a->time;
 }
diff --git a/settings/templates/log.php b/settings/templates/log.php
index bcf5258f5f5047632ad3324e6e8eca5885070ad4..da5defc320e8c3c6b1f439fcba38742bc5ed32c1 100644
--- a/settings/templates/log.php
+++ b/settings/templates/log.php
@@ -9,7 +9,7 @@ $levels=array('Debug','Info','Warning','Error','Fatal');
 <div id="controls">
 	
 </div>
-<table>
+<table id='log'>
 	<?php foreach($_['entries'] as $entry):?>
 		<tr>
 			<td>
@@ -26,4 +26,5 @@ $levels=array('Debug','Info','Warning','Error','Fatal');
 			</td>
 		</tr>
 	<?php endforeach;?>
-</table>
\ No newline at end of file
+</table>
+<input id='moreLog' type='button' value='<?php echo $l->t('More');?>...'></input>