从 EC2 实例记录到 CloudWatch


Logging to CloudWatch from EC2 instances

我的EC2服务器当前托管一个网站,该网站在本地EC2实例上将每个注册用户的活动记录在他们自己的单独日志文件下,例如用户名.log。我正在尝试找出一种方法,使用 PHP SDK 将这些日志事件推送到 CloudWatch,而不会减慢应用程序的速度,同时仍然能够为我网站的每个注册成员维护一个单独的日志文件。

我一辈子都想不通:

选项 1:如何使用 CloudWatch 开发工具包异步登录到 CloudWatch?我的PHP应用程序运行非常缓慢,因为每个日志行大约需要100毫秒才能直接推送到CloudWatch。下面是代码示例。

选项 2:或者,如何在 EC2 上配置已安装的 CloudWatch 代理,以简单地观察我的所有日志文件,这基本上会在单独的进程中将它们异步上传到 CloudWatch?CloudWatch EC2 日志记录代理需要您的服务器上有一个静态"配置文件"(AWS 文档),据我所知,该文件需要提前列出您的所有日志文件("日志流"),我在服务器启动时无法预测。有没有办法解决这个问题(即,简单地观察目录中的所有日志文件)?配置文件示例如下。

这里欢迎所有想法,但我不希望我的解决方案只是"将所有日志放入一个文件中,以便您的日志名称始终可预测"。

提前谢谢!!


选项 1:通过 SDK 进行日志记录(需要 ~100 毫秒/日志事件):

// Configuration to use for the CloudWatch client
$sharedConfig = [
    'region'  => 'us-east-1',
    'version' => 'latest',
    'http'    => [
        'verify' => false
    ]
];
// Create a CloudWatch client
$cwClient = new Aws'CloudWatchLogs'CloudWatchLogsClient($sharedConfig);
// DESCRIBE ANY EXISTING LOG STREAMS / FILES
$create_new_stream = true;
$next_sequence_id = "0";
$result = $cwClient->describeLogStreams([
        'Descending' => true,
        'logGroupName' => 'user_logs',
        'LogStreamNamePrefix' => $stream,
]);
// Iterate through the results, looking for a stream that already exists with the intended name
// This is so that we can get the next sequence id ('uploadSequenceToken'), so we can add a line to an existing log file
foreach ($result->get("logStreams") as $stream_temp) {
    if ($stream_temp['logStreamName'] == $stream) {
        $create_new_stream = false;
        if (array_key_exists('uploadSequenceToken', $stream_temp)) {
            $next_sequence_id = $stream_temp['uploadSequenceToken'];
        }
        break;
    }
}   
// CREATE A NEW LOG STREAM / FILE IF NECESSARY
if ($create_new_stream) { 
    $result = $cwClient->createLogStream([
        'logGroupName' => 'user_logs',
        'logStreamName' => $stream,
    ]);
}
// PUSH A LINE TO THE LOG *** This step ALONE takes 70-100ms!!! ***
$result = $cwClient->putLogEvents([
    'logGroupName' => 'user_logs',
    'logStreamName' => $stream,
    'logEvents' => [
        [
            'timestamp' => round(microtime(true) * 1000),
            'message' => $msg,
        ],
    ],
    'sequenceToken' => $next_sequence_id
]);

选项 2:通过 CloudWatch 安装代理进行日志记录(请注意,据我所知,下面的配置文件仅允许硬编码的预建模日志名称):

[general]
state_file = /var/awslogs/state/agent-state  
[applog]
file = /var/www/html/logs/applog.log
log_group_name = PP
log_stream_name = applog.log
datetime_format = %Y-%m-%d %H:%M:%S

看起来我们现在有一些好消息...不知道是不是太晚了!

云观察日志配置

所以为了回答疑问,

有没有办法解决这个问题(即,简单地观察目录中的所有日志文件)?

是的,我们可以使用通配符提及日志文件和文件路径,这可以帮助您灵活地配置从何处获取日志并将其推送到日志流。