Skip to content

Commit 2e39ea1

Browse files
committed
优化日志
1 parent 88f203f commit 2e39ea1

File tree

15 files changed

+501
-193
lines changed

15 files changed

+501
-193
lines changed

hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenReactiveAuthenticationSupplier.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.hswebframework.web.authorization.exception.UnAuthorizedException;
77
import org.hswebframework.web.context.ContextKey;
88
import org.hswebframework.web.context.ContextUtils;
9+
import org.hswebframework.web.logger.ReactiveLogger;
910
import org.springframework.beans.factory.annotation.Autowired;
1011
import reactor.core.publisher.Mono;
1112

@@ -73,9 +74,11 @@ public Mono<Authentication> get() {
7374
.getByToken(t.getToken())
7475
.filter(UserToken::validate))
7576
.map(tokenMono -> tokenMono
76-
.doOnNext(token->userTokenManager.touch(token.getToken()))
77+
.doOnNext(token -> userTokenManager.touch(token.getToken()))
7778
.flatMap(token -> get(thirdPartAuthenticationManager.get(token.getType()), token.getUserId())))
78-
.orElseGet(Mono::empty));
79+
.orElseGet(Mono::empty))
80+
.flatMap(auth -> ReactiveLogger.mdc("userId", auth.getUser().getId()).thenReturn(auth))
81+
;
7982

8083
}
8184
}

hsweb-authorization/hsweb-authorization-api/src/test/java/org/hswebframework/web/authorization/AuthenticationTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
66
import org.hswebframework.web.authorization.token.*;
77
import org.hswebframework.web.context.ContextKey;
8+
import org.hswebframework.web.logger.ReactiveLogger;
89
import org.junit.Assert;
910
import org.junit.Before;
1011
import org.junit.Test;
1112
import reactor.core.publisher.Mono;
13+
import reactor.core.publisher.SignalType;
1214
import reactor.test.StepVerifier;
1315

1416
import java.util.Collections;
@@ -127,12 +129,17 @@ public String getType() {
127129
return token.getType();
128130
}
129131
};
132+
130133
//获取当前登录用户
131134
Authentication
132135
.currentReactive()
133136
.map(Authentication::getUser)
134137
.map(User::getId)
138+
.doOnEach(ReactiveLogger.on(SignalType.ON_NEXT,(ctx,signal)->{
139+
System.out.println(ctx);
140+
}))
135141
.subscriberContext(acceptContext(ctx -> ctx.put(ContextKey.of(ParsedToken.class), parsedToken)))
142+
// .subscriberContext(ReactiveLogger.start("rid","1"))
136143
.as(StepVerifier::create)
137144
.expectNext("admin")
138145
.verifyComplete();

hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DimensionDataAccessHandler.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ protected Object handleById(DimensionDataAccessConfig config,
114114
DataAccessHandlerContext context,
115115
MappingInfo mappingInfo,
116116
Object id) {
117+
118+
if (id instanceof Param || id instanceof Entity) {
119+
120+
applyQueryParam(config, context, id);
121+
return id;
122+
}
123+
117124
List<Dimension> dimensions = context.getDimensions();
118125

119126
Set<Object> scope = CollectionUtils.isNotEmpty(config.getScope()) ?
@@ -138,11 +145,25 @@ protected Object handleById(DimensionDataAccessConfig config,
138145
if (id instanceof Publisher) {
139146
if (id instanceof Mono) {
140147
return ((Mono) id)
141-
.flatMap(r -> reactiveCheck.apply(r instanceof Collection ? ((Collection) r) : Collections.singleton(r)))
148+
.flatMap(r -> {
149+
if (r instanceof Param) {
150+
applyQueryParam(config, context, r);
151+
return Mono.just(r);
152+
}
153+
return reactiveCheck.apply(r instanceof Collection ? ((Collection) r) : Collections.singleton(r));
154+
155+
})
142156
.then((Mono) id);
143157
}
144158
if (id instanceof Flux) {
145159
return ((Flux) id)
160+
.filter(v -> {
161+
if (v instanceof Param) {
162+
applyQueryParam(config, context, v);
163+
return false;
164+
}
165+
return true;
166+
})
146167
.collectList()
147168
.flatMap(reactiveCheck)
148169
.thenMany((Flux) id);
@@ -272,7 +293,7 @@ protected boolean doHandleQuery(DimensionDataAccessConfig cfg, DataAccessHandler
272293
MappingInfo mappingInfo = getMappingInfo(context).get(cfg.getScopeType());
273294

274295
//根据结果控制
275-
if (context.getDefinition().getPhased() == Phased.after) {
296+
if (context.getDefinition().getResources().getPhased() == Phased.after) {
276297
Object result = context.getParamContext().getInvokeResult();
277298
Set<Object> scope = CollectionUtils.isNotEmpty(cfg.getScope()) ?
278299
cfg.getScope() :
@@ -283,12 +304,14 @@ protected boolean doHandleQuery(DimensionDataAccessConfig cfg, DataAccessHandler
283304
String property = mappingInfo.getProperty();
284305

285306
if (result instanceof Mono) {
286-
context.getParamContext().setInvokeResult(((Mono) result).
287-
filter(data -> hasAccessByProperty(scope, property, data)));
307+
context.getParamContext()
308+
.setInvokeResult(((Mono) result).
309+
filter(data -> hasAccessByProperty(scope, property, data)));
288310
return true;
289311
} else if (result instanceof Flux) {
290-
context.getParamContext().setInvokeResult(((Flux) result).
291-
filter(data -> hasAccessByProperty(scope, property, data)));
312+
context.getParamContext()
313+
.setInvokeResult(((Flux) result).
314+
filter(data -> hasAccessByProperty(scope, property, data)));
292315
return true;
293316
}
294317
return hasAccessByProperty(scope, property, result);

hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenWebFilter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.hswebframework.web.authorization.token.ParsedToken;
66
import org.hswebframework.web.authorization.token.UserTokenManager;
77
import org.hswebframework.web.context.ContextUtils;
8+
import org.hswebframework.web.logger.ReactiveLogger;
89
import org.springframework.beans.BeansException;
910
import org.springframework.beans.factory.annotation.Autowired;
1011
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -42,7 +43,9 @@ public Mono<Void> filter(@NonNull ServerWebExchange exchange, WebFilterChain cha
4243
.subscriberContext(ContextUtils.acceptContext(ctx ->
4344
Flux.fromIterable(parsers)
4445
.flatMap(parser -> parser.parseToken(exchange))
45-
.subscribe(token -> ctx.put(ParsedToken.class, token))));
46+
.subscribe(token -> ctx.put(ParsedToken.class, token))))
47+
.subscriberContext(ReactiveLogger.start("requestId", exchange.getRequest().getId()))
48+
;
4649
}
4750

4851
@EventListener

hsweb-core/src/main/java/org/hswebframework/web/aop/MethodInterceptorHolder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,17 @@ public static MethodInterceptorHolder create(MethodInvocation invocation) {
5252
String[] argNames = nameDiscoverer.getParameterNames(invocation.getMethod());
5353
Object[] args = invocation.getArguments();
5454
Map<String, Object> argMap = new LinkedHashMap<>();
55+
String[] names = new String[args.length];
5556
for (int i = 0, len = args.length; i < len; i++) {
56-
argMap.put((argNames == null || argNames[i] == null) ? "arg" + i : argNames[i], args[i]);
57+
names[i] = (argNames == null || argNames.length <= i || argNames[i] == null) ? "arg" + i : argNames[i];
58+
argMap.put(names[i], args[i]);
5759
}
5860

5961
return new MethodInterceptorHolder(id,
6062
invocation.getMethod(),
6163
invocation.getThis(),
6264
args,
65+
names,
6366
argMap);
6467
}
6568

@@ -71,6 +74,8 @@ public static MethodInterceptorHolder create(MethodInvocation invocation) {
7174

7275
private Object[] arguments;
7376

77+
private String[] argumentsNames;
78+
7479
private Map<String, Object> namedArguments;
7580

7681

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package org.hswebframework.web.logger;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.slf4j.MDC;
5+
import reactor.core.publisher.Mono;
6+
import reactor.core.publisher.Signal;
7+
import reactor.core.publisher.SignalType;
8+
import reactor.util.context.Context;
9+
10+
import java.util.*;
11+
import java.util.function.BiConsumer;
12+
import java.util.function.Consumer;
13+
import java.util.function.Function;
14+
15+
@Slf4j
16+
public class ReactiveLogger {
17+
18+
private static String CONTEXT_KEY = ReactiveLogger.class.getName();
19+
20+
public static Function<Context, Context> start(String key, String value) {
21+
return start(Collections.singletonMap(key, value));
22+
}
23+
24+
public static Mono<Void> mdc(String key, String value) {
25+
return Mono.<Void>empty()
26+
.subscriberContext(start(key, value));
27+
}
28+
29+
public static Function<Context, Context> start(Map<String, String> context) {
30+
return ctx -> {
31+
Optional<Map<String, String>> maybeContextMap = ctx.getOrEmpty(CONTEXT_KEY);
32+
if (maybeContextMap.isPresent()) {
33+
maybeContextMap.get().putAll(context);
34+
return ctx;
35+
} else {
36+
return ctx.put(CONTEXT_KEY, new LinkedHashMap<>(context));
37+
}
38+
};
39+
}
40+
41+
42+
public static <T> void log(Context context, Consumer<Map<String, String>> logger) {
43+
Optional<Map<String, String>> maybeContextMap = context.getOrEmpty(CONTEXT_KEY);
44+
if (!maybeContextMap.isPresent()) {
45+
logger.accept(new HashMap<>());
46+
} else {
47+
Map<String, String> ctx = maybeContextMap.get();
48+
MDC.setContextMap(ctx);
49+
try {
50+
logger.accept(ctx);
51+
} finally {
52+
MDC.clear();
53+
}
54+
}
55+
}
56+
57+
public static <T> Consumer<Signal<T>> on(SignalType type, BiConsumer<Map<String, String>, Signal<T>> logger) {
58+
return signal -> {
59+
if (signal.getType() != type) {
60+
return;
61+
}
62+
Optional<Map<String, String>> maybeContextMap
63+
= signal.getContext().getOrEmpty(CONTEXT_KEY);
64+
if (!maybeContextMap.isPresent()) {
65+
logger.accept(new HashMap<>(), signal);
66+
} else {
67+
Map<String, String> ctx = maybeContextMap.get();
68+
MDC.setContextMap(ctx);
69+
try {
70+
logger.accept(ctx, signal);
71+
} finally {
72+
MDC.clear();
73+
}
74+
}
75+
};
76+
}
77+
78+
public static Mono<Void> mdc(Consumer<Map<String, String>> consumer) {
79+
return Mono.subscriberContext()
80+
.doOnNext(ctx -> {
81+
Optional<Map<String, String>> maybeContextMap = ctx.getOrEmpty(CONTEXT_KEY);
82+
if (maybeContextMap.isPresent()) {
83+
consumer.accept(maybeContextMap.get());
84+
} else {
85+
consumer.accept(Collections.emptyMap());
86+
log.warn("logger context is empty,please call publisher.subscriberContext(ReactiveLogger.mdc()) first!");
87+
}
88+
})
89+
.then();
90+
}
91+
92+
public static <T> Consumer<Signal<T>> onNext(Consumer<T> logger) {
93+
return on(SignalType.ON_NEXT, (ctx, signal) -> {
94+
logger.accept(signal.get());
95+
});
96+
97+
}
98+
99+
public static <T> Consumer<Signal<T>> onComplete(Runnable logger) {
100+
return on(SignalType.ON_COMPLETE, (ctx, signal) -> {
101+
logger.run();
102+
});
103+
}
104+
105+
public static <T> Consumer<Signal<T>> onError(Consumer<Throwable> logger) {
106+
return on(SignalType.ON_ERROR, (ctx, signal) -> {
107+
logger.accept(signal.getThrowable());
108+
});
109+
}
110+
111+
112+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.hswebframework.web.logger;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.junit.Test;
5+
import reactor.core.publisher.Flux;
6+
import reactor.test.StepVerifier;
7+
8+
import java.time.Duration;
9+
10+
import static org.junit.Assert.*;
11+
12+
@Slf4j
13+
public class ReactiveLoggerTest {
14+
15+
16+
@Test
17+
public void test() {
18+
19+
Flux.range(0, 5)
20+
.delayElements(Duration.ofSeconds(2))
21+
.flatMap(i -> ReactiveLogger.mdc("requestId", "test").thenReturn(i))
22+
.doOnEach(ReactiveLogger.onNext(v -> {
23+
log.info("test:{}", v);
24+
}))
25+
.subscriberContext(ReactiveLogger.start("r","1"))
26+
.as(StepVerifier::create)
27+
.expectNextCount(5)
28+
.verifyComplete();
29+
30+
31+
}
32+
33+
}

hsweb-logging/hsweb-access-logging-aop/pom.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,32 @@
3434
<groupId>io.swagger</groupId>
3535
<artifactId>swagger-annotations</artifactId>
3636
</dependency>
37+
3738
<dependency>
3839
<groupId>org.springframework</groupId>
3940
<artifactId>spring-webmvc</artifactId>
41+
<optional>true</optional>
42+
</dependency>
43+
44+
<dependency>
45+
<groupId>org.springframework</groupId>
46+
<artifactId>spring-webflux</artifactId>
47+
<optional>true</optional>
4048
</dependency>
49+
4150
<dependency>
4251
<groupId>org.hswebframework.web</groupId>
4352
<artifactId>hsweb-core</artifactId>
4453
<version>${project.version}</version>
4554
</dependency>
55+
56+
<dependency>
57+
<groupId>org.hswebframework.web</groupId>
58+
<artifactId>hsweb-authorization-api</artifactId>
59+
<version>${project.version}</version>
60+
<optional>true</optional>
61+
</dependency>
62+
4663
<dependency>
4764
<groupId>javax.servlet</groupId>
4865
<artifactId>javax.servlet-api</artifactId>

0 commit comments

Comments
 (0)