158 lines
4.6 KiB
PHP
158 lines
4.6 KiB
PHP
<?php
|
|
/**
|
|
* Author: ykxiao
|
|
* Date: 2025/6/3
|
|
* Time: 下午7:13
|
|
* Description:
|
|
*
|
|
* (c) ykxiao <yk_9001@hotmail.com>
|
|
*
|
|
* This source file is subject to the MIT license that is bundled
|
|
* with this source code in the file LICENSE.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use Hyperf\Config\Annotation\Value;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
use Hyperf\Guzzle\ClientFactory;
|
|
use function Hyperf\Coroutine\co;
|
|
|
|
/**
|
|
* Author: ykxiao
|
|
* Date: 2025/6/3
|
|
* Time: 下午7:18
|
|
* Description: 阿里云日志服务.
|
|
*
|
|
* (c) ykxiao <yk_9001@hotmail.com>
|
|
*
|
|
* This source file is subject to the MIT license that is bundled
|
|
* with this source code in the file LICENSE.
|
|
*/
|
|
class AliLogsSignService
|
|
{
|
|
protected const string LOG_SIGNATURE_METHOD = 'hmac-sha1';
|
|
|
|
protected const string LOG_API_VERSION = '0.6.0';
|
|
|
|
#[Value('alibaba.accessKeyId')]
|
|
protected string $accessKeyId;
|
|
|
|
#[Value('alibaba.accessKeySecret')]
|
|
protected string $accessKeySecret;
|
|
|
|
#[Value('alibaba.logs')]
|
|
protected array $logs;
|
|
|
|
#[Inject]
|
|
protected ClientFactory $clientFactory;
|
|
|
|
/**
|
|
* 签名及请求头拼接.
|
|
* @param mixed $method
|
|
* @param mixed $uri
|
|
* @param mixed $params
|
|
* @param mixed $body
|
|
* @param mixed $logProject
|
|
* @param mixed $logEndpoint
|
|
*/
|
|
public function buildHeaders(
|
|
string $method,
|
|
string $uri,
|
|
array $params,
|
|
string $body,
|
|
string|object $logProject,
|
|
string $logEndpoint
|
|
): array
|
|
{
|
|
$headers = [
|
|
'x-log-signaturemethod' => self::LOG_SIGNATURE_METHOD,
|
|
'x-log-apiversion' => self::LOG_API_VERSION,
|
|
'Host' => sprintf('%s.%s', $logProject, $logEndpoint),
|
|
'Content-Type' => 'application/json',
|
|
];
|
|
$contentLength = 0;
|
|
$contentMd5 = '';
|
|
if (!empty($body) && strlen($body) > 0) {
|
|
$contentLength = strlen($body);
|
|
$contentMd5 = strtoupper(md5($body));
|
|
$headers['Content-MD5'] = $contentMd5;
|
|
}
|
|
// date
|
|
setlocale(LC_TIME, 'en_US');
|
|
$date = gmdate('D, d M Y H:i:s \G\M\T', time());
|
|
$headers['Date'] = $date;
|
|
$headers['Content-Length'] = (string)$contentLength;
|
|
$contentType = $headers['Content-Type'];
|
|
$message = $method . "\n" . $contentMd5 . "\n" . $contentType . "\n" . $date . "\n";
|
|
// header
|
|
$filterHeaders = [];
|
|
foreach ($headers as $key => $val) {
|
|
if (str_starts_with($key, 'x-log-') || str_starts_with($key, 'x-acs-')) {
|
|
$filterHeaders[$key] = $val;
|
|
}
|
|
}
|
|
ksort($filterHeaders);
|
|
foreach ($filterHeaders as $key => $val) {
|
|
$message .= $key . ':' . $val . "\n";
|
|
}
|
|
// uri and params
|
|
$message .= $uri;
|
|
if (sizeof($params) > 0) {
|
|
$message .= '?';
|
|
}
|
|
ksort($params);
|
|
$sep = '';
|
|
foreach ($params as $key => $val) {
|
|
$message .= $sep . $key . '=' . $val;
|
|
$sep = '&';
|
|
}
|
|
// signature & authorization
|
|
$signature = $this->generateSignature($message);
|
|
$auth = 'LOG ' . $this->accessKeyId . ':' . $signature;
|
|
$headers['Authorization'] = $auth;
|
|
return $headers;
|
|
}
|
|
|
|
/**
|
|
* 实现调用PutWebTracking接口将多条日志合并进行采集.
|
|
*/
|
|
public function putWebTracking(array $record): void
|
|
{
|
|
$logEndpoint = $this->logs['log_endpoint'];
|
|
$logProject = $this->logs['log_project'];
|
|
$logStores = $this->logs['log_store'];
|
|
$params = [];
|
|
$body = [
|
|
'__topic__' => 'mes api logs',
|
|
'__source__' => 'admin api',
|
|
'__logs__' => [
|
|
['Logs' => $record['formatted']],
|
|
],
|
|
'__tags__' => [
|
|
'mes' => $record['channel'],
|
|
],
|
|
];
|
|
$body = json_encode($body);
|
|
|
|
$sign_url = sprintf('/logstores/%s/track', $logStores);
|
|
$headers = $this->buildHeaders('POST', $sign_url, $params, $body, $logProject, $logEndpoint);
|
|
$options = [
|
|
'headers' => $headers,
|
|
'body' => $body,
|
|
'query' => $params,
|
|
];
|
|
$url = sprintf('https://%s.%s/logstores/%s/track', $logProject, $logEndpoint, $logStores);
|
|
$client = $this->clientFactory->create();
|
|
co(function () use ($client, $url, $options) {
|
|
$client->request('POST', $url, $options);
|
|
});
|
|
}
|
|
|
|
protected function generateSignature(string $message): string
|
|
{
|
|
return base64_encode(hash_hmac('sha1', $message, $this->accessKeySecret, true));
|
|
}
|
|
} |