whitedigital-eu/audit-service

审计服务

安装: 627

依赖: 2

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 0

开放性问题: 5

类型:symfony-bundle


README

重要:从 0.4(或更早版本)迁移到 0.5 时,配置和使用方式略有变化

  1. 当在包外部使用时,现在可以通过 WhiteDigital\Audit\Contracts\AuditServiceInterface 访问 AuditService,而不是 WhiteDigital\Audit\Service\AuditServiceLocator。已删除 AuditServiceLocator 类。
  2. 配置已更改,现在它高一个级别
    旧版本:
whitedigital:
    audit:
        enable: true
        audit_entity_manager: audit
        default_entity_manager: default
use Symfony\Config\WhitedigitalConfig;

return static function (WhitedigitalConfig $config): void {
    $config
        ->audit()
            ->enabled(true)
            ->auditEntityManager('audit')
            ->defaultEntityManager('default');
};

新版本:

audit:
    audit_entity_manager: audit
    default_entity_manager: default

如果用于php配置,现在使用的是 AuditConfig 而不是 WhitedigitalConfig

use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->auditEntityManager('audit')
        ->defaultEntityManager('default');
};

由于此捆绑包现在已启用,已删除 enabled 参数

这是什么?

审计是用于将事件(日志)记录到数据库的服务。目前该包仅提供doctrine实现来保存数据,但您可以轻松扩展功能(见下文)以使用其他存储方式。

系统要求

PHP 8.1+
Symfony 6.3+

项目要求

2个独立的Doctrine实体管理器(如果使用提供的AuditService

安装

推荐安装方式是通过Composer

composer require whitedigital-eu/audit-service

配置

配置因默认设置和覆盖设置而不同。如果您对覆盖部分包的配置感兴趣,请向下滚动到相应的部分。

audit:
    audit_entity_manager: audit
    default_entity_manager: default
use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->auditEntityManager('audit')
        ->defaultEntityManager('default');
};

audit_entity_manager 是用于审计的实体管理器
default_entity_manager 是您用于数据库操作的实体管理器

逻辑在两个管理器之间分割,因为这更容易审计数据库异常。如果使用一个实体管理器,则需要采取很多额外的步骤(打开已关闭的实体管理器,检查操作状态等。)

之后,您需要更新数据库模式以使用Audit实体。
如果使用迁移

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate

如果通过模式更新

bin/console doctrine:schema:update --force

这就完成了,现在您可以使用审计。它已配置并自动注入为 AuditServiceInterface

use WhiteDigital\Audit\Contracts\AuditType;
use WhiteDigital\Audit\Contracts\AuditServiceInterface;

public function __construct(private AuditServiceInterface $audit){}

$this->audit->audit(AuditType::EXCEPTION, 'something happened');

try {
    somefunction();
} catch (Exception $exception){
    $this->audit->auditException($exception);
}

审计服务包含2个事件订阅者:一个用于异常,一个用于数据库事件。

异常订阅者:
默认情况下,异常订阅者会审计所有异常,除了404响应代码。您可以通过以下方式覆盖此逻辑:

audit:
    excluded:
        response_codes:
            - 404
            - 405
use Symfony\Config\AuditConfig;
use Symfony\Component\HttpFoundation\Response;

return static function (AuditConfig $config): void {
    $config
        ->excluded()
            ->responseCodes([
                Response::HTTP_NOT_FOUND,
                Response::HTTP_METHOD_NOT_ALLOWED,
            ]);
};

默认情况下,异常订阅者会审计所有路由和路径上的所有异常。您可以通过以下方式覆盖此逻辑:路径

audit:
    excluded:
        paths:
            - '/test'
use Symfony\Config\AuditConfig;
use Symfony\Component\HttpFoundation\Response;

return static function (AuditConfig $config): void {
    $config
        ->excluded()
            ->paths([
                '/test',
            ]);
};

路由

audit:
    excluded:
        routes:
            - 'app_test'
use Symfony\Config\AuditConfig;
use Symfony\Component\HttpFoundation\Response;

return static function (AuditConfig $config): void {
    $config
        ->excluded()
            ->routes([
                'app_test',
            ]);
};

允许的审计类型

为了不在审计记录中造成混乱,只能使用指定的审计类型。
默认值是:AUTHENTICATIONDATABASEETL_PIPELINEEXCEPTIONEXTERNAL_CALL

如果您没有自定义类型,可以使用 WhiteDigital\Audit\Contracts\AuditType 类来使用默认常量。

如果您希望添加更多类型,可以按以下方式配置新类型

audit:
    additional_audit_types:
        - test1
        - test2
use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->additionalAuditTypes([
            'test1',
            'test2',
        ]);
};

可以运行symfony命令来根据默认类型和添加的类型生成接口,以便更容易地完成代码

bin/console make:audit-types

此命令将根据包配置生成新文件。默认情况下,此命令将创建 App\Audit\AuditType 类。您可以在配置中覆盖此名称

audit:
    audit_type_interface_namespace: 'App\Audit'
    audit_type_interface_class_name: 'AuditType'
use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->auditTypeInterfaceNamespace('App\Audit')
        ->auditTypeInterfaceClassName('AuditType');
};

如果您已定义此接口并希望添加更多允许的类型,只需将其添加到该接口中,而无需将类型添加到包配置中。允许的类型将合并自配置和接口。

API资源

此包包含AuditResource,用于api-platform,其iri为 /api/audits

覆盖捆绑包的部分

覆盖审计服务
如果您不希望使用本软件包附带审计服务,您可以使用自己的服务进行覆盖。
要实现这一点,请在您的服务中实现 AuditServiceInterface 接口

use WhiteDigital\Audit\Contracts\AuditServiceInterface;

class YourAuditService implements AuditServiceInterface {
    public function audit(string $type, string $message, array $data = [], string $class = ''): void
    {
    }

    public function auditException(Throwable $exception, ?string $url = null, string $class = ''): void
    {
    }
    
    public static function getDefaultPriority(): int
    {
        return 2;
    }
}

本包中的 AuditService 优先级为 1。要覆盖它,请确保添加的优先级高于它。

如果您的自定义 AuditService 不使用数据库作为审计存储,您需要禁用需要 2 个实体管理器的部分。您可以这样做:

audit:
    custom_configuration: true
use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->customConfiguration(true);
};

覆盖默认 API 资源(以及因此的 API 端点)

默认情况下,Audit 资源基于 AuditResource
如果您不希望使用此资源并且不公开它提供的 API 端点,只需使用配置值设置自定义 API 资源路径。如果将其设置为 null,API 平台将不会注册此包中定位的 API 资源。

audit:
    custom_api_resource_path: '%kernel.project_dir%/src/MyCustomPath'
#    custom_api_resource_path: null
use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->customApiResourcePath('%kernel.project_dir%/src/MyCustomPath')
        // or  ->customApiResourcePath(null);
};

覆盖默认 API 资源后,不要忘记更新 whitedigital-eu/entity-resource-mapper-bundle 中用于资源与实体映射的 ClassMapperConfigurator 配置。

use App\ApiResource\Admin\AuditResource;
use WhiteDigital\Audit\Entity\Audit;
use WhiteDigital\EntityResourceMapper\Mapper\ClassMapper;
use WhiteDigital\EntityResourceMapper\Mapper\ClassMapperConfiguratorInterface;

final class ClassMapperConfigurator implements ClassMapperConfiguratorInterface
{
    public function __invoke(ClassMapper $classMapper): void
    {
        $classMapper->registerMapping(AuditResource::class, Audit::class);
    }
}

覆盖默认实体
默认情况下,Audit 实体基于来自 whitedigital-eu/entity-resource-mapper-bundleBaseEntity
如果您完全不想使用此基类,您需要创建新的实体并将 AuditEntityInterface 实现到其中

use Doctrine\ORM\Mapping as ORM;
use WhiteDigital\Audit\Contracts\AuditEntityInterface;

#[ORM\Entity]
class AuditEntity implements AuditEntityInterface {}

或者您可以使用包中的 Model

use Doctrine\ORM\Mapping as ORM;
use WhiteDigital\Audit\Model\Audit;

#[ORM\Entity]
class AuditEntity extends Audit {}

如果您希望添加新属性或可能为来自包的 Audit 实体使用不同的名称

use Doctrine\ORM\Mapping as ORM;
use WhiteDigital\Audit\Entity\Audit as BaseAudit;

#[ORM\Entity]
#[ORM\Table('new_audit_table_name')]
class AuditEntity extends BaseAudit {}

现在当您在项目中使用 audit()auditException() 函数时,您需要告诉服务使用您的实体

use WhiteDigital\Audit\Contracts\AuditType;
use WhiteDigital\Audit\Contracts\AuditServiceInterface;

use App\Entity\AuditEntity; // example

public function __construct(private AuditServiceInterface $audit){}

$this->audit->audit(AuditType::EXTERNAL, 'something happened', [], AuditEntity::class);

$this->audit->audit(AuditType::ETL, 'something happened', class: AuditEntity::class);

try {
    somefunction();
} catch (Exception $exception){
    $this->audit->auditException($exception, '', AuditEntity::class);
    
    $this->audit->auditException($exception, class: AuditEntity::class);
}

此包自动将 WhiteDigital\Audit\Entity 命名空间添加到两个实体管理器中。如果您希望不这样做,例如,如果您不使用默认实体或可能根本不在数据库中存储审计,您需要配置此选项以禁用它

audit:
    set_doctrine_mappings: false
use Symfony\Config\AuditConfig;

return static function (AuditConfig $config): void {
    $config
        ->setDoctrineMappings(false);
};

覆盖实体事件的审计
您可以通过调用实体事件订阅者的 setIsEnabled 设置器在运行时禁用实体事件审计

use WhiteDigital\Audit\EventSubscriber\AuditDoctrineEventSubscriber;

public function __construct(private AuditDoctrineEventSubscriber $subscriber){}

$this->subscriber->setIsEnabled(false);
someFunction();
$this->subscriber->setIsEnabled(true);

PHP CS Fixer

重要:在运行 php-cs-fixer 时,请确保不要格式化 skeleton 文件夹中的文件。否则,maker 命令将停止工作。