Duansg opened a new pull request, #7852:
URL: https://github.com/apache/shenyu/pull/7852
## Summary
The logging plugins (Kafka, Elasticsearch, RocketMQ and plugin-store loggers
built on `AbstractLoggingPlugin`) ignored the configured `maxRequestBody` /
`maxResponseBody`. The size checks read a static `GenericGlobalConfig` in
`LogCollectConfigUtils` that was never populated from plugin data, so the 512
KiB default always applied. `BodyWriter` also buffered the entire body
regardless of size and discarded it only after the request completed.
## Changes
- **Use the plugin's limits.** `AbstractLoggingPlugin` resolves the
plugin's config once per request through
`LogCollectConfigUtils.getGlobalConfig(selector.getPluginId())`. This uses the
same key as sampling: the plugin id cached by `AbstractLogPluginDataHandler`.
The limits are passed to the request and response decorators. If no config is
cached, the defaults apply.
- **Bounded `BodyWriter`.**
- Buffers at most the limit. Once the limit is exceeded, the buffer is
released, so its array can be collected before the request ends, and only the
total byte count is tracked.
- Allocates the buffer lazily, so empty bodies allocate nothing.
- All methods are `synchronized`, because a cancel-triggered `doFinally`
can run concurrently with `onNext`.
- Does not modify the caller's buffer.
- **Overflow detection.** Callers decide whether to log a body with
`isLimitExceeded()`. `size()` saturates at `Integer.MAX_VALUE`, so comparing it
against a limit of `Integer.MAX_VALUE` cannot detect overflow. `size()` is
still used for `responseContentLength`.
- **Compatibility.**
- The existing `LoggingServerHttpRequest`/`LoggingServerHttpResponse`
constructors and the no-arg `BodyWriter()` are kept and behave as before
(default limits / unbounded).
- `LogCollectConfigUtils#isRequestBodyTooLarge` / `#isResponseBodyTooLarge`
are deprecated. They still check the defaults, which is what they effectively
did before.
- `GenericGlobalConfig` exposes `DEFAULT_MAX_REQUEST_BODY` /
`DEFAULT_MAX_RESPONSE_BODY`.
## Performance
JMH 1.37, JDK 21, Apple M1 Pro, 512 KiB limit, 8 KiB direct-buffer chunks,
one full decorator lifecycle per op (HEAD vs. this PR):
| Body | Before | After | Alloc before | Alloc after |
|---|---|---|---|---|
| empty | 0.020 µs | 0.001 µs | 200 B | 0 B |
| 64 KiB | 12.50 µs | 12.46 µs | 263 KB | 263 KB |
| 512 KiB (at limit) | 92.46 µs | 92.34 µs | 2.10 MB | 2.10 MB |
| 4 MiB (8× over) | 386.1 µs | 57.2 µs | 8.42 MB | 1.08 MB |
With 4 threads, the 4 MiB case improves from 721 µs to 95 µs. Bodies
within the limit show no measurable difference. The per-request config lookup
adds about 4 ns.
## Tests
- `AbstractLoggingPluginBodyLimitTest`: configured request/response limits
and their boundaries, limits larger than the default, defaults when the config
or its JSON fields are missing, per-plugin isolation, config updates applied to
the next request, UTF-8 bodies across chunks, non-positive limits, and the
error path (synchronous and reactive).
- `BodyWriterTest`: limit boundary, overflow releases the buffer and keeps
counting without reallocating, oversized first chunk, non-positive limits,
`size()` saturation, no writes accepted after `output()`, concurrent
`write`/`output`. Checks are deterministic and do not rely on GC timing.
- `LoggingBodySaturatedSizeTest`: when `size()` has saturated, request and
response bodies stay `null`.
- `LogCollectConfigUtilsTest`: config lookup by plugin id, fresh default
config when missing or when the plugin id is `null`, and the deprecated
default-limit checks.
- Mutation-checked: reverting to `stream.reset()` or to `size()`-based
caller checks makes the new tests fail.
`./mvnw install` with checkstyle passes for
`shenyu-plugin-logging-common`, `-kafka`, `-elasticsearch`, `-rocketmq` and
`-console`.
Make sure that:
- [x] You have read the [contribution
guidelines](https://shenyu.apache.org/community/contributor-guide).
- [x] You submit test cases (unit or integration tests) that back your
changes.
- [x] Your local test passed `./mvnw clean install
-Dmaven.javadoc.skip=true`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]