【问题标题】:Best Practises for (error-) logging(错误)日志记录的最佳实践
【发布时间】:2018-03-27 00:51:49
【问题描述】:

所以我正在尝试为我的网络应用创建日志记录。它是用 HTML/CSS/JS 编写的前端和 PHP 的后端,使用 MariaDB 数据库。我正在尝试在我的所有代码中为错误/警告等创建日志记录。这意味着,不仅适用于 PHP 代码,也适用于 JS(未来可能还会有更多的语言)。 PHP 和 JS 中的大部分处理已经完成,并且 JS 错误通过 AJAX 发送到服务器。现在我坚持的是,将这些错误保存到数据库的最佳方法是什么。

现在我在数据库中有 1 个表存在错误,如下所示:

id         BIGINT  (10)  -- Primary Key
message    TEXT          -- The error message
type       VARCHAR (255) -- warning/error/notice/deprication etc...
origin     VARCHAR (255) -- JS/PHP etc...
account_id BIGINT  (10)  -- Foreign Key to an account table

c_dt DATETIME            -- Creation datetime
u_dt DATETIME            -- Update datetime
d_dt DATETIME            -- Delete datetime (implementation of soft delete)

注意:这与审计日志不同,后者在不同的表中实现。

澄清; message 只是一个格式化的字符串,它是从抛出的事件中创建的。这个字符串的几个真实例子是:

  • phpHandler 捕捉到以下事件: 2: mysqli::real_escape_string() 期望参数 1 为字符串,给定数组。文件:\path\to\the\databaseManager.php,行:206。
  • ReferenceError:myfunc 未定义。文件:myFile.js 行:22 列:70
  • phpHandler 捕捉到以下事件:8:未定义索引:例程。文件:\path\to\the\Entrance.php,行:7。

但是,例如,我不能(轻松)从字符串中获取行号。或者按文件名分组,看看哪些文件最麻烦。当然,添加文件名或行号之类的列可以解决此问题。但并非所有语言在发生错误时都会给出相同的信息。例如,JS 中的错误对象有列号、文件名、行号、浏览器名称等……但 PHP 对这一切的信息要少得多。而如果我以后想实现更多的(后端)语言,只会有更多的信息差异。

所以我的问题是,将错误保存到数据库的最佳做法是什么?每种(相似组)语言都有自己的表格和各自的信息? 1 有很多列的表?只保存基本信息,例如文件/行号严重性?

另外,我可能忽略了上述解决方案的一些优点和缺点?

【问题讨论】:

  • 看看help center
  • 在我看来就像某种 yagni ...谁会在什么用例中使用(阅读)这张表。其他选项可用,尽量不要自己滚动。
  • 我会查看 Sentry 的 PHP 客户端,它会抓取相邻的源代码和堆栈本地变量:github.com/getsentry/sentry-php。对于 JS,您可能需要考虑不同的浏览器如何具有细微的不同堆栈跟踪。 Sentry 的 JS 客户端也可以在这里提供帮助 github.com/getsentry/raven-js

标签: javascript php error-handling error-logging


【解决方案1】:

这不是为数据库中的每个字段创建许多列的好方法, 如果在特定文件中记录错误不能满足您(在大多数情况下是最好的方法),或者如果您想将其保存在数据库中以防演示或简单,您应该以可移植格式保存数据, 如果您不想查询该数据,您可以将整个消息编码为 json (TEXT MESSAGE)(如果您有任何其他数据,您可以将其序列化)。例如

/**
 * @param $exception
 * @throws Exception
 */
public function failed(Exception $exception)
{
    YOUR_MODEL::save(
        [
            'error' => json_encode([
                "file" => $exception->getFile(),
                "line" => $exception->getLine(),
                "message" => $exception->getMessage()
            ])
        ]);

    throw $exception;
}

【讨论】:

    【解决方案2】:

    我建议在您的数据库中使用 JSON 类型字段。 For more information about JSON type

    您可以记录有关警告、错误等的详细信息。请注意将可查询字段作为字段存储在表中。

    【讨论】:

    • 好建议!如果我错了,请纠正我,但实现如下?:发生错误时,我将相关信息(由它发生的位置/语言定义)存储在 JSON 中,并将该 JSON + 类型存储到 DB .然后为了检索我从数据库中获取 JSON 并由类型确定,我以某种方式对其进行格式化。
    • 不客气。是的,您可以反序列化其内容。但如您所见,您可以根据需要在 Json 内容中搜索。 (SELECT JSON_SET('"x"', '$[0]', 'a');)。如果你真的需要在 JSON 中搜索。顺便说一句,日志记录使用归档类型的数据库引擎。
    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 2021-08-05
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    相关资源
    最近更新 更多