【发布时间】:2011-01-30 02:29:30
【问题描述】:
我正在开发我的 CMS,我希望它记录用户和其他管理员的活动。 例如:当新用户注册或管理员发布新新闻时 -> 更新上次活动。
我想知道什么是最好和最简单的方法。
【问题讨论】:
-
您是只想更新数据库中的last_activity字段当一个动作发生还是你真的想记录什么这个动作是什么?
我正在开发我的 CMS,我希望它记录用户和其他管理员的活动。 例如:当新用户注册或管理员发布新新闻时 -> 更新上次活动。
我想知道什么是最好和最简单的方法。
【问题讨论】:
然后您可以编写一个报告工具,让您的管理员可以访问这些记录的活动,您可以按用户、时间和活动类型进行过滤。
在我的日志框架中,我特别标记了可能被视为恶意行为的活动,并为其分配不同的数字威胁值。如果用户的线程值总和达到某个阈值,我会注销该用户。
理想情况下,如果您编写一个应用程序,您首先编写基础架构代码,例如日志记录,然后在以后在所有业务逻辑代码中使用它。
编辑以进行清理:
随着时间的推移,您可能会在该表中收集大量记录。根据您的要求,您可以做不同的事情。
删除任何超过 x 天(可能是一年)的条目
删除某些类型超过 x 天的任何条目,但将其他类型的条目保留更长时间或永久保留。
将早于某个阈值的条目移动到存档日志表中。这样可以使您的主表变小,但如果您确实需要,您可以访问较旧的日志数据。我的评论日志页面上有一个复选框Use archive。
【讨论】:
不要自己做,从头开始,看看一些现有系统是如何做的,如果他们的许可允许,使用他们的设计和代码(确保你记录了你使用的代码,并在你的CMS 某处)。
我不确定 PHP CMS 会执行此操作,但我知道 Django's admin 应用程序会执行此操作。 Django 是用 Python 实现的,但是将这段代码移植到 PHP 上应该相当简单。即使代码不是直接移植,也可以移植设计。
包含日志记录的文件位于models.py 的admin 模块中。
一些关键方面:
日志表的数据模型:
class LogEntry(models.Model):
action_time = models.DateTimeField(_('action time'), auto_now=True)
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType, blank=True, null=True)
object_id = models.TextField(_('object id'), blank=True, null=True)
object_repr = models.CharField(_('object repr'), max_length=200)
action_flag = models.PositiveSmallIntegerField(_('action flag'))
change_message = models.TextField(_('change message'), blank=True)
objects = LogEntryManager()
还有保存实际日志条目的 LogEntryManager:
class LogEntryManager(models.Manager):
def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''):
e = self.model(None, None, user_id, content_type_id, smart_unicode(object_id), object_repr[:200], action_flag, change_message)
e.save()
【讨论】:
我为活动使用了两个表,一个为每个活动提供一个 ID,另一个只记录用户 ID、活动 ID 和时间戳。我这样做是因为 int 占用的空间比字符串少,那么为什么要一遍又一遍地记录相同的字符串呢?第二个不是必需的,您可以轻松地将操作代码保存在文本文件中以供您自己参考,但数据库似乎更容易记住。
过去我使用函数来处理实际的日志记录操作,但下次我将使用观察者模式。它似乎更加灵活,而且我已经不得不从我拥有的旧代码中编辑出日志函数调用,这些代码不会记录任何内容。我更喜欢无需编辑即可重用代码。
【讨论】:
使用 PHP/JAVA FUNCTION JQUERY 及其 AJAX 数据发布方法非常简单... 在发布解决方案之前——让我们阅读这两行
我们为什么要记录? --- 我们只知道在数据库中记录交易 -- 不是所有的点击和检查 -- 但可以使用这个解决方案......
这里是一步一步的解决方案:-
1. create a DB Table -- to record these things
a) Page Name.
b) logged in user name
c) session details (To record all the sessions).
d) POST/GET data details (To record all the post/get data for the
page)
e) Record Created Date.
或您想要记录的任何其他内容。 2. 创建一个 Jquery 函数或 PHP 函数——每个页面都会自动触发。 3. 该功能将收集该页面的所有会话、用户登录的详细信息以及传递到该页面的数据。 除此之外 - 您还可以记录 - 从哪个页面调用这个新页面 - 即使在已经运行的旧软件中,它也是实现日志记录功能的非常简单和最佳方式:)
如果你想使用我上面提到的所有代码——在 NET 上搜索它我定义的机制只是你需要功能代码——自动执行功能代码——简单
【讨论】:
PHP 和 MYSQL
CREATE TABLE `test_loq` (
id int(11) PRIMARY KEY AUTO_INCREMENT,
page varchar(255) NOT NULL,
username varchar(255) NOT NULL,
log_time datetime DEFAULT CURRENT_TIMESTAMP,
log_action longtext NOT NULL,
log_name varchar(255) NOT NULL,
user_id int(11) NOT NULL,
ip int(11) NOT NULL
)
解释:
class log
{
CONST ENVIRONMENT = 'developemnt';
private $id;
protected $log_action;
protected $username;
protected $page;
protected $ip;
protected $log_name;
private $user_id;
public function __construct(string $log_action, string $username, string $log_name)
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
if(!empty($_SESSION['id'])){
$id = $_SESSION['id'];
} else {
$id = 0;
}
$this->log_action = $log_action;
$this->username = $username;
$this->log_name = $log_name;
$this->user_id = $id;
$this->page = basename($_SERVER['PHP_SELF']);
$this->ip = $ip;
}
public function createAction()
{
global $conn;
if(!$conn) {
echo mysqli_error($conn); die;
}
$sql = "INSERT INTO test_log (`log_action`,`username`,`log_name`,`page`,`user_id`,`ip`) values ('".$this->log_action."','".$this->username."','".$this->log_name."','".$this->page."','".$this->user_id."','".$this->ip."')" ;
$sql_query = mysqli_query($conn,$sql);
if(!$sql_query){
echo mysqli_error($conn); die;
}
if(ENVIRONMENT == 'development'){
$_SESSION['msg'] = 'A new log was created ' . $this->log_name;
}
} }
<?php
session_start();
include("include/configurationadmin.php");
//include_once('../include/classes/config.inc.php');
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$sql = mysqli_query($conn,"select * from ".$sufix."admin where username='".$username."'") ;
// HERE HOW TO LOG ACTION
$log = new log("Logging in attempt from $username" , $username ,'Login Attempt' );
$log->createAction();
//SIMPLE AND COOL RIGHT?
if(mysqli_num_rows($sql) > 0)
{
$rows = mysqli_fetch_assoc($sql);
if(md5($password) == $rows['password']) {
$_SESSION['id'] = $rows['id'];
$_SESSION['username'] = $rows['username'];
$_SESSION['usertype'] = $rows['type'];
mysqli_query($conn,"update ".$sufix."admin set lastlogin='".date('Y-m-d')."' where id = '".$rows['id']."' and username='".$rows['username']."'") ;
$domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('rrdssrdda', $rows['id'], time()+120, '/', $domain, false);
header("Location: http://localhost/test/admin-new/dashboard");
exit();
} else {
$_SESSION['message']="<div class='alert alert-danger' role='alert'>Invalid userid/password!</div>";
header("Location: http://localhost/test/admin-new/");
exit();
}
} else {
$_SESSION['message']="<div class='alert alert-danger' role='alert'>Invalid userid/password!</div>";
header("Location: http://localhost/test/admin-new/");
exit();
} ?>
编码愉快!
【讨论】: