Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add apollo audit log common solution backend #4985

Merged
merged 54 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
4911b87
7.3
BlackBear2003 Jul 3, 2023
b7b7b61
Merge branch 'apolloconfig:master' into add-audit-logs
BlackBear2003 Jul 3, 2023
687b73b
Merge branch 'apolloconfig:master' into add-audit-logs
BlackBear2003 Jul 26, 2023
d1b4574
plc success except jpa part
BlackBear2003 Aug 3, 2023
57eb3d6
successfully run by EntityScan annotation(not a good way)
BlackBear2003 Aug 8, 2023
83e7021
successfully run by add packages to bean registrar
BlackBear2003 Aug 8, 2023
d291b7d
'app create' audit log and query poc success
BlackBear2003 Aug 9, 2023
bf4105d
App create/update/delete poc success.
BlackBear2003 Aug 15, 2023
4031cc2
add License
BlackBear2003 Aug 15, 2023
85a2403
add License
BlackBear2003 Aug 15, 2023
b556305
try to pass tests
BlackBear2003 Aug 16, 2023
668a34e
try to pass tests
BlackBear2003 Aug 16, 2023
ff6fb0e
fix ${revision} to ${project.version}
BlackBear2003 Aug 17, 2023
ac42630
add no-op implement and no-op autoconfiguration.
BlackBear2003 Sep 1, 2023
154a17b
Merge branch 'apolloconfig:master' into add-audit-logs
BlackBear2003 Sep 1, 2023
7608549
rebase and add license
BlackBear2003 Sep 1, 2023
721cd4f
add audit controller
BlackBear2003 Sep 4, 2023
50a1ee5
- change controller
BlackBear2003 Sep 15, 2023
a6e7b3c
- make ApolloAuditHttpInterceptor uses Api while not tracer
BlackBear2003 Sep 15, 2023
ca7469e
- retry workflows
BlackBear2003 Sep 15, 2023
21b061f
- change for code review
BlackBear2003 Sep 19, 2023
1da08c3
- basically finish front-end part.
BlackBear2003 Sep 24, 2023
7be4d34
- fix for hound
BlackBear2003 Sep 24, 2023
c43217e
- update
BlackBear2003 Sep 24, 2023
bae4aad
- update
BlackBear2003 Sep 24, 2023
39491ef
Merge remote-tracking branch 'origin/add-audit-logs' into add-audit-logs
BlackBear2003 Sep 24, 2023
c345830
- add ApolloAuditLogApiNoOpImpl.class to @ContextConfiguration at App…
BlackBear2003 Sep 25, 2023
87ef435
- add license and fix for hound
BlackBear2003 Sep 25, 2023
4ce1f9d
- fix front-end bug
BlackBear2003 Sep 30, 2023
8a45abf
- fix front-end bug
BlackBear2003 Sep 30, 2023
beecd44
- remove query for auditing AppNamespace
BlackBear2003 Sep 30, 2023
c73c8d7
fix for changed requested
BlackBear2003 Oct 4, 2023
0e4f852
- change: always record if the method have no annotation
BlackBear2003 Oct 8, 2023
2dc02c0
- add test cover manually add dataInfluence when delete app
BlackBear2003 Oct 10, 2023
bbdd361
- try to write part of tests in impl
BlackBear2003 Oct 15, 2023
d0654b3
- finish ApolloAuditLogApiJpaImplTest
BlackBear2003 Oct 16, 2023
f0eaa34
- finish most part of context's unit-tests
BlackBear2003 Oct 16, 2023
ba3c354
- finish some unit-tests
BlackBear2003 Oct 17, 2023
ad324de
- fix database design bug
BlackBear2003 Oct 17, 2023
add5f0d
- add prompt sheet for disabling audit log feature
BlackBear2003 Oct 19, 2023
a154f53
- fix test bugs
BlackBear2003 Oct 19, 2023
62cbdc9
- change the way of getting op-type for data influences
BlackBear2003 Oct 20, 2023
b7a2c25
- enhance front-end design
BlackBear2003 Oct 20, 2023
08f6fb9
- enhance front-end design
BlackBear2003 Oct 20, 2023
a6ff3a6
Merge branch 'master' into add-audit-logs
BlackBear2003 Oct 21, 2023
37a8148
- add AuditLog Search dropdown
BlackBear2003 Oct 21, 2023
ee5c271
- add any-match data influences for batch-delete operation auditing
BlackBear2003 Oct 24, 2023
1e04137
- fix bugs
BlackBear2003 Oct 24, 2023
93b2907
- fix front-end bugs
BlackBear2003 Oct 25, 2023
36f0d75
- fix test failure
BlackBear2003 Oct 25, 2023
37c1458
- fix test failure
BlackBear2003 Oct 25, 2023
5430d0b
- update javadoc
BlackBear2003 Oct 25, 2023
c670758
- update README
BlackBear2003 Oct 25, 2023
f4de3b3
- update README
BlackBear2003 Oct 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apollo-adminservice/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-biz</artifactId>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-audit-spring-boot-starter</artifactId>
</dependency>
<!-- end of apollo -->
<dependency>
<groupId>org.springframework.cloud</groupId>
Expand Down
4 changes: 4 additions & 0 deletions apollo-adminservice/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@

# You may change the following config to activate different database profiles like h2/postgres
spring.profiles.group.github = mysql

# true: enabled the new feature of audit log
# false/missing: disable it
apollo.audit.log.enabled = true
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.ctrip.framework.apollo.assembly;

import com.ctrip.framework.apollo.adminservice.AdminServiceApplication;
import com.ctrip.framework.apollo.audit.configuration.ApolloAuditAutoConfiguration;
import com.ctrip.framework.apollo.configservice.ConfigServiceApplication;
import com.ctrip.framework.apollo.portal.PortalApplication;

Expand All @@ -31,7 +32,7 @@
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
HibernateJpaAutoConfiguration.class, ApolloAuditAutoConfiguration.class})
public class ApolloApplication {

private static final Logger logger = LoggerFactory.getLogger(ApolloApplication.class);
Expand Down
4 changes: 4 additions & 0 deletions apollo-assembly/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@

# You may change the following config to activate different database profiles like h2/postgres
spring.profiles.group.github = mysql

# true: enabled the new feature of audit log
# false/missing: disable it
apollo.audit.log.enabled = true
147 changes: 147 additions & 0 deletions apollo-audit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Features: Apollo-Audit-Log

This module provides audit log functions for other Apollo modules.

Only apolloconfig's developer need to read it,

apolloconfig's user doesn't need.

## How to enable/disable

We can switch this module freely by properties:

by adding properties to application.properties:

```
# true: enabled the new feature of audit log
# false/missing: disable it
apollo.audit.log.enabled = true
```

## How to generate audit log

### Append an AuditLog

Through an AuditLog, we have the ability to record **Who, When, Why, Where, What and How** operates something.

We can do this by using annotations:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may use 5W1H to describe it.


```java
@ApolloAuditLog(type=OpType.CREATE,name="App.create")
public App create() {
// ...
}
```

Through this, an AuditLog will be created and its AuditScope will be activated during the execution of this method.

Equally, we can use ApolloAuditLogApi to do this manually:

```java
public App create() {
try(AutoCloseable auditScope = api.appendAuditLog(type, name)) {
// ...
}
}
/**************OR**************/
public App create() {
Autocloseable auditScope = api.appendAuditLog(type, name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try with resources?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try with resources?

// ...
auditScope.close();
}
```

The only thing you need to pay attention to is that you need to close this scope manually~

### Append DataInfluence

This function can also be implemented automatically and manually.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes there is not DataInfluence, we should tell developer about it.


There is a corresponding relationship between DataInfluences and a certain AuditLog, and they are caused by this AuditLog. But not all AuditLogs will generate DataInfluences!

#### Mark which data change

First, we need to add audit-bean-definition to class of the entity you want to audit:

```java
@ApolloAuditLogDataInfluenceTable(tableName = "App")
public class App extends BaseEntity {
@ApolloAuditLogDataInfluenceTableField(fieldName = "Name")
private String name;
private String orgId;
}
```

In class App, we define that its data-influence table' name is "App", the field "name" needs to be audited and its audit field name in the table "App" is "Name". The field "orgId" is no need to be audited.

Second, use API's method to append it:

Actually we don't need to manually call it. We can depend on the DomainEvents that pre-set in BaseEntity:

```java
@DomainEvents
public Collection<ApolloAuditLogDataInfluenceEvent> domainEvents() {
return Collections.singletonList(new ApolloAuditLogDataInfluenceEvent(this.getClass(), this));
}
```

And this will call appendDataInfluences automatically by the listener.

#### Manually
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe should describe how to verify the audit log work too...

For example, which table's data change, or how to check it by UI


```java
/**
* Append DataInfluences by a list of entities needs to be audited, and their
* audit-bean-definition.
*/
ApolloAuditLogApi.appendDataInfluences(List<Object> entities, Class<?> beanDefinition);
```

Just call the api method in an active scope, the data influences will combine with the log automatically.

```java
public App create() {
try(AutoCloseable auditScope = api.appendAuditLog(type, name)) {
// ...
api.appendDataInfluences(appList, App.class);
// or.
api.appendDataInfluence("App","10001","Name","xxx");
}
}
```

#### some tricky situations

Yet, sometimes we can't catch the domain events like some operations that directly change database fields. We can use annotations to catch the input parameters:

```java
@ApolloAuditLog(type=OpType.DELETE,name="AppNamespace.batchDeleteByAppId")
public AppNamespace batchDeleteByAppId(
@ApolloAuditLogDataInfluence
@ApolloAuditLogDataInfluenceTable(tableName="AppNamespace")
@ApolloAuditLogDataInfluenceTableField(fieldName="AppId") String appId) {
// ...
}
```

This will generate a special data influence. It means that all entities matching the input parameter value have been affected.

## How to verify the audit-log work

### check-by-UI

The entrance of audit log UI is in Admin Tools.

Then, we can check if the AuditLogs are created properly by searching or just find in table below.

Then, check in the trace detail page.

We can check if the relationship between AuditLogs are correct and the DataInfluences caused by certain AuditLog is logically established.

In the rightmost column, we can view the historical operation records of the specified field's value. Null means being deleted~

### check-by-database

The databases are in ApolloPortalDB, the table `AuditLog` and `AuditLogDataInfluence`.

We can verify if the parent/followsfrom relationships are in line with our expectations.
31 changes: 31 additions & 0 deletions apollo-audit/apollo-audit-annotation/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2023 Apollo Authors
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apollo-audit</artifactId>
<groupId>com.ctrip.framework.apollo</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>apollo-audit-annotation</artifactId>
<version>${revision}</version>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2023 Apollo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.ctrip.framework.apollo.audit.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Mark which method should be audited, add to controller or service's method.
* <p></p>
* Define the attributes of the operation for persisting and querying. When adding to controller's
* methods, suggested that don't set name, and it will automatically be set to request's url.
* <p></p>
* Example usage:
* <pre>
* {@code
* @ApolloAuditLog(type=OpType.CREATE,name="App.create")
* public App create() {
* // ...
* }
* }
* </pre>
*
* @author luke0125
* @since 2.2.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApolloAuditLog {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need javadoc in all annotation and api


/**
* Define the type of operation.
*
* @return operation type
*/
OpType type();

/**
* Define the name of operation. The requested URL will be taken by default if no specific name is
* specified.
*
* @return operation name
*/
String name() default "";

/**
* Define the description of operation. Default is "no description".
*
* @return operation description
*/
String description() default "no description";
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2023 Apollo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.ctrip.framework.apollo.audit.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Combine with {@link ApolloAuditLog}, mark which method's parameter is audit log's data change.
* <p></p>
* Example usage:
* <pre>
* {@code
* @ApolloAuditLog(type=OpType.DELETE,name="AppNamespace.batchDeleteByAppId")
* public AppNamespace batchDeleteByAppId(
* @ApolloAuditLogDataInfluence String appId) {
* // ...
* }
* }
* </pre>
*
* @author luke0125
* @since 2.2.0
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApolloAuditLogDataInfluence {

}
Loading
Loading