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));
|
||||
}
|
||||
}
|
97
app/Service/JsonRpcResponse.php
Normal file
97
app/Service/JsonRpcResponse.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2024/6/3
|
||||
* Time: 22:45
|
||||
* Description:
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/1/3
|
||||
* Time: 下午8:33
|
||||
* Description: JsonRpc响应类.
|
||||
*
|
||||
* (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 JsonRpcResponse
|
||||
{
|
||||
/**
|
||||
* JsonRpc版本。
|
||||
*/
|
||||
private string $jsonRpcVersion = '2.0';
|
||||
|
||||
private mixed $id;
|
||||
|
||||
private mixed $result;
|
||||
|
||||
private mixed $error;
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
public function __construct(LoggerFactory $loggerFactory, $id = null, $result = null, $error = null)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->result = $result;
|
||||
$this->error = $error;
|
||||
|
||||
$this->logger = $loggerFactory->get('jsonrpc');
|
||||
}
|
||||
|
||||
public function withId($id): static
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withResult($result): static
|
||||
{
|
||||
$this->result = $result;
|
||||
|
||||
$this->logger->info(json_encode(['RPC result' => $result], JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withError($code, $message, $data = null): static
|
||||
{
|
||||
$this->error = [
|
||||
'code' => $code,
|
||||
'message' => $message,
|
||||
'data' => $data,
|
||||
];
|
||||
$this->logger->error(json_encode(['RPC error' => $message], JSON_UNESCAPED_UNICODE));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$response = [
|
||||
'jsonrpc' => $this->jsonRpcVersion,
|
||||
'id' => $this->id,
|
||||
];
|
||||
|
||||
if ($this->error) {
|
||||
$response['error'] = $this->error;
|
||||
} else {
|
||||
$response['result'] = $this->result;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function toJson(): bool|string
|
||||
{
|
||||
return json_encode($this->toArray());
|
||||
}
|
||||
}
|
44
app/Service/MigrateService.php
Normal file
44
app/Service/MigrateService.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/6/4
|
||||
* Time: 下午1:57
|
||||
* 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\Database\Schema\Blueprint;
|
||||
|
||||
class MigrateService
|
||||
{
|
||||
/***
|
||||
* 在创建的时候自动添加如下字段
|
||||
* @param Blueprint $blueprint
|
||||
* @return Blueprint
|
||||
*/
|
||||
public static function migrateCreateInfo(Blueprint $blueprint): Blueprint
|
||||
{
|
||||
$blueprint->integer('creator_id')->default(0)->unsigned()->comment('创建人ID');
|
||||
$blueprint->string('creator_name', 45)->default('')->comment('创建人姓名');
|
||||
$blueprint->integer('created_at')->default(0)->unsigned()->comment('创建时间');
|
||||
$blueprint->integer('updated_at')->default(0)->unsigned()->comment('更新时间');
|
||||
$blueprint->integer('deleted_at')->nullable()->unsigned()->comment('软删除时间');
|
||||
return $blueprint;
|
||||
}
|
||||
|
||||
public static function migrateTime(Blueprint $blueprint): Blueprint
|
||||
{
|
||||
$blueprint->integer('created_at')->default(0)->unsigned()->comment('创建时间');
|
||||
$blueprint->integer('updated_at')->default(0)->unsigned()->comment('更新时间');
|
||||
$blueprint->integer('deleted_at')->nullable()->unsigned()->comment('软删除时间');
|
||||
return $blueprint;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user