This commit is contained in:
158
app/Service/AliLogsSignService.php
Normal file
158
app/Service/AliLogsSignService.php
Normal file
@ -0,0 +1,158 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user