| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- <?php
- namespace App\Module\ThirdParty\Models;
- use UCore\ModelCore;
- use App\Module\ThirdParty\Enums\LOG_LEVEL;
- use Illuminate\Database\Eloquent\Relations\BelongsTo;
- /**
- * 第三方服务调用日志模型
- *
- * field start
- * @property int $id 主键ID
- * @property int $service_id 服务ID
- * @property int $credential_id 凭证ID
- * @property string $request_id 请求ID(用于追踪)
- * @property string $method
- * @property string $url 请求URL
- * @property array $headers 请求头
- * @property array $params 请求参数
- * @property string $body 请求体
- * @property int $response_status 响应状态码
- * @property array $response_headers 响应头
- * @property string $response_body 响应体
- * @property int $response_time 响应时间(毫秒)
- * @property string $error_message 错误信息
- * @property string $level 日志级别
- * @property int $user_id 用户ID
- * @property string $ip_address IP地址
- * @property string $user_agent User Agent
- * @property \Carbon\Carbon $created_at 创建时间
- * field end
- */
- class ThirdPartyLog extends ModelCore
- {
- /**
- * 数据表名
- *
- * @var string
- */
- protected $table = 'thirdparty_logs';
- /**
- * 禁用updated_at字段
- *
- * @var bool
- */
- public $timestamps = false;
- /**
- * 可批量赋值的属性
- *
- * @var array
- */
- protected $fillable = [
- 'service_id',
- 'credential_id',
- 'request_id',
- 'method',
- 'url',
- 'headers',
- 'params',
- 'body',
- 'response_status',
- 'response_headers',
- 'response_body',
- 'response_time',
- 'error_message',
- 'level',
- 'user_id',
- 'ip_address',
- 'user_agent',
- 'created_at',
- ];
- /**
- * 属性类型转换
- *
- * @var array
- */
- protected $casts = [
- 'service_id' => 'integer',
- 'credential_id' => 'integer',
- 'headers' => 'array',
- 'params' => 'array',
- 'response_status' => 'integer',
- 'response_headers' => 'array',
- 'response_time' => 'integer',
- 'user_id' => 'integer',
- 'created_at' => 'datetime',
- ];
- /**
- * 获取日志级别枚举
- *
- * @return LOG_LEVEL
- */
- public function getLogLevelEnum(): LOG_LEVEL
- {
- return LOG_LEVEL::from($this->level);
- }
- /**
- * 获取日志级别标签
- *
- * @return string
- */
- public function getLevelLabel(): string
- {
- return $this->getLogLevelEnum()->getLabel();
- }
- /**
- * 检查是否为成功请求
- *
- * @return bool
- */
- public function isSuccessful(): bool
- {
- return $this->response_status >= 200 && $this->response_status < 300;
- }
- /**
- * 检查是否为错误请求
- *
- * @return bool
- */
- public function isError(): bool
- {
- return $this->getLogLevelEnum()->isError() || $this->response_status >= 400;
- }
- /**
- * 检查是否需要告警
- *
- * @return bool
- */
- public function needsAlert(): bool
- {
- return $this->getLogLevelEnum()->needsAlert();
- }
- /**
- * 获取响应时间(秒)
- *
- * @return float
- */
- public function getResponseTimeInSeconds(): float
- {
- return $this->response_time ? $this->response_time / 1000 : 0;
- }
- /**
- * 获取格式化的响应时间
- *
- * @return string
- */
- public function getFormattedResponseTime(): string
- {
- if (!$this->response_time) {
- return '-';
- }
- if ($this->response_time < 1000) {
- return $this->response_time . 'ms';
- }
- return number_format($this->getResponseTimeInSeconds(), 2) . 's';
- }
- /**
- * 获取状态码描述
- *
- * @return string
- */
- public function getStatusDescription(): string
- {
- if (!$this->response_status) {
- return '无响应';
- }
- $statusTexts = [
- 200 => 'OK',
- 201 => 'Created',
- 204 => 'No Content',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 429 => 'Too Many Requests',
- 500 => 'Internal Server Error',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- ];
- return $statusTexts[$this->response_status] ?? 'Unknown';
- }
- /**
- * 获取状态码颜色
- *
- * @return string
- */
- public function getStatusColor(): string
- {
- if (!$this->response_status) {
- return 'secondary';
- }
- if ($this->response_status >= 200 && $this->response_status < 300) {
- return 'success';
- }
- if ($this->response_status >= 300 && $this->response_status < 400) {
- return 'info';
- }
- if ($this->response_status >= 400 && $this->response_status < 500) {
- return 'warning';
- }
- return 'danger';
- }
- /**
- * 获取简化的请求体
- *
- * @param int $maxLength
- * @return string
- */
- public function getTruncatedBody(int $maxLength = 200): string
- {
- if (!$this->body) {
- return '';
- }
- if (strlen($this->body) <= $maxLength) {
- return $this->body;
- }
- return substr($this->body, 0, $maxLength) . '...';
- }
- /**
- * 获取简化的响应体
- *
- * @param int $maxLength
- * @return string
- */
- public function getTruncatedResponseBody(int $maxLength = 200): string
- {
- if (!$this->response_body) {
- return '';
- }
- if (strlen($this->response_body) <= $maxLength) {
- return $this->response_body;
- }
- return substr($this->response_body, 0, $maxLength) . '...';
- }
- /**
- * 获取请求的基本信息
- *
- * @return array
- */
- public function getRequestSummary(): array
- {
- return [
- 'method' => $this->method,
- 'url' => $this->url,
- 'status' => $this->response_status,
- 'response_time' => $this->getFormattedResponseTime(),
- 'level' => $this->getLevelLabel(),
- 'created_at' => $this->created_at->format('Y-m-d H:i:s'),
- ];
- }
- /**
- * 关联第三方服务
- *
- * @return BelongsTo
- */
- public function service(): BelongsTo
- {
- return $this->belongsTo(ThirdPartyService::class, 'service_id');
- }
- /**
- * 关联认证凭证
- *
- * @return BelongsTo
- */
- public function credential(): BelongsTo
- {
- return $this->belongsTo(ThirdPartyCredential::class, 'credential_id');
- }
- /**
- * 生成唯一的请求ID
- *
- * @return string
- */
- public static function generateRequestId(): string
- {
- return uniqid('req_', true);
- }
- /**
- * 创建日志记录
- *
- * @param array $data
- * @return static
- */
- public static function createLog(array $data): static
- {
- // 自动设置创建时间
- if (!isset($data['created_at'])) {
- $data['created_at'] = now();
- }
- // 自动生成请求ID
- if (!isset($data['request_id'])) {
- $data['request_id'] = static::generateRequestId();
- }
- // 自动设置日志级别
- if (!isset($data['level'])) {
- if (isset($data['response_status'])) {
- if ($data['response_status'] >= 400) {
- $data['level'] = LOG_LEVEL::ERROR->value;
- } elseif ($data['response_status'] >= 300) {
- $data['level'] = LOG_LEVEL::WARNING->value;
- } else {
- $data['level'] = LOG_LEVEL::INFO->value;
- }
- } else {
- $data['level'] = LOG_LEVEL::INFO->value;
- }
- }
- return static::create($data);
- }
- /**
- * 按日期范围查询
- *
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param string $startDate
- * @param string $endDate
- * @return \Illuminate\Database\Eloquent\Builder
- */
- public function scopeDateRange($query, string $startDate, string $endDate)
- {
- return $query->whereBetween('created_at', [$startDate, $endDate]);
- }
- /**
- * 按服务查询
- *
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param int $serviceId
- * @return \Illuminate\Database\Eloquent\Builder
- */
- public function scopeByService($query, int $serviceId)
- {
- return $query->where('service_id', $serviceId);
- }
- /**
- * 按日志级别查询
- *
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param string $level
- * @return \Illuminate\Database\Eloquent\Builder
- */
- public function scopeByLevel($query, string $level)
- {
- return $query->where('level', $level);
- }
- /**
- * 查询错误日志
- *
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @return \Illuminate\Database\Eloquent\Builder
- */
- public function scopeErrors($query)
- {
- return $query->whereIn('level', [LOG_LEVEL::ERROR->value, LOG_LEVEL::CRITICAL->value])
- ->orWhere('response_status', '>=', 400);
- }
- }
|