Skip to content

Conversation

@itssimon
Copy link
Member

@itssimon itssimon commented Jan 22, 2026

Summary by CodeRabbit

  • New Features

    • Per-request log capture is now included with request logs for richer tracing when enabled.
    • Captured logs are safely limited (fixed-size buffer) and long messages are truncated to avoid oversized entries.
  • Configuration

    • New toggle to enable/disable log capture; capture is only active when enabled.
  • Tests

    • Added tests covering capture lifecycle, buffer limits, and message truncation.

✏️ Tip: You can customize this high-level summary in your review settings.

@itssimon itssimon self-assigned this Jan 22, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

Walkthrough

Adds thread-local log capture via a new Logback appender and LogRecord DTO, wires captured logs through request logging and RequestLogItem, exposes a config flag, integrates capture start/stop in the Spring filter/autoconfiguration, updates ConsumerRegistry, and adjusts tests for capture and serialization. (50 words)

Changes

Cohort / File(s) Summary
Log capture implementation
src/main/java/io/apitally/common/ApitallyAppender.java, src/main/java/io/apitally/common/dto/LogRecord.java
New Logback appender with ThreadLocal fixed-size buffer (MAX_BUFFER_SIZE=1000), message truncation (MAX_MESSAGE_LENGTH=2048), start/end capture API and static register(); new immutable LogRecord DTO (timestamp, logger, level, message).
Request logging model & usage
src/main/java/io/apitally/common/RequestLogger.java, src/main/java/io/apitally/common/dto/RequestLogItem.java
logRequest(...) signature updated to accept List<LogRecord> logs; RequestLogItem gains logs field, constructor updated, and @JsonProperty("logs") getter to include captured logs in serialized output.
Configuration & registry
src/main/java/io/apitally/common/RequestLoggingConfig.java, src/main/java/io/apitally/common/ConsumerRegistry.java
Added logCaptureEnabled flag with getter/setter on RequestLoggingConfig; added reset() to ConsumerRegistry to clear internal consumers/identifiers.
Spring integration & filter flow
src/main/java/io/apitally/spring/ApitallyAutoConfiguration.java, src/main/java/io/apitally/spring/ApitallyFilter.java
Autoconfiguration registers the appender when request logging + capture enabled; filter starts per-thread capture at request start, ends capture in finally, and forwards captured logs to RequestLogger.
Unit & integration tests
src/test/java/io/apitally/common/ApitallyAppenderTest.java, src/test/java/io/apitally/common/RequestLoggerTest.java, src/test/java/io/apitally/common/ApitallyClientTest.java, src/test/java/io/apitally/spring/ApitallyFilterTest.java
New tests for ApitallyAppender lifecycle, buffer limit, truncation; tests updated to pass and assert logs; tests call ApitallyAppender.register() and use ConsumerRegistry.reset() where applicable.
Test app code changes
src/test/java/io/apitally/spring/app/RequestLoggingCallbacks.java, src/test/java/io/apitally/spring/app/TestController.java
shouldExclude() flipped to always return false; TestController augmented with SLF4J logger and simple request/result logs.
CI workflow
.github/workflows/tests.yaml
Updated Python version to 3.14 and expanded Spring Boot matrix to include 3.5.9.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Capture application logs' directly and clearly describes the main purpose of the PR, which adds log capture functionality across multiple components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch simon/dev-9-add-application-log-capture-to-java-sdk

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 22, 2026

Codecov Report

❌ Patch coverage is 83.07692% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.20%. Comparing base (f086f5f) to head (e8fe2df).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...main/java/io/apitally/common/ApitallyAppender.java 81.81% 3 Missing and 3 partials ⚠️
...rc/main/java/io/apitally/common/RequestLogger.java 60.00% 1 Missing and 1 partial ⚠️
.../io/apitally/spring/ApitallyAutoConfiguration.java 0.00% 2 Missing ⚠️
...c/main/java/io/apitally/spring/ApitallyFilter.java 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main      #52      +/-   ##
============================================
+ Coverage     77.25%   78.20%   +0.95%     
- Complexity      326      358      +32     
============================================
  Files            32       34       +2     
  Lines          1121     1184      +63     
  Branches        140      150      +10     
============================================
+ Hits            866      926      +60     
- Misses          172      175       +3     
  Partials         83       83              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/test/java/io/apitally/common/RequestLoggerTest.java (1)

71-112: Fix failing test: enable log capture before asserting logs

CI shows logsNode is null in testEndToEnd. logCaptureEnabled defaults to false, so the provided logs get dropped in RequestLogger.logRequest(...). Enable log capture in the test before asserting on logs.

✅ Suggested fix
     `@Test`
     void testEndToEnd() {
+        requestLoggingConfig.setLogCaptureEnabled(true);
         Header[] requestHeaders = new Header[] {
                 new Header("User-Agent", "Test"),
         };
@@
         List<LogRecord> logs = new ArrayList<>();
         logs.add(new LogRecord(System.currentTimeMillis() / 1000.0, "test.Logger", "INFO", "Test log message"));
         requestLogger.logRequest(request, response, exception, logs);
🤖 Fix all issues with AI agents
In `@src/main/java/io/apitally/spring/ApitallyAutoConfiguration.java`:
- Around line 30-32: ApitallyAppender.register() currently assumes Logback by
casting LoggerFactory.getILoggerFactory() to
ch.qos.logback.classic.LoggerContext, which can throw ClassCastException for
other SLF4J backends; modify ApitallyAppender.register() to first check if
org.slf4j.LoggerFactory.getILoggerFactory() is an instance of
ch.qos.logback.classic.LoggerContext before casting, and if not, log a safe
warning via SLF4J and return without registering; also wrap the registration
logic in a try/catch(ClassCastException | LinkageError) that logs a non-fatal
warning and aborts registration so startup does not fail even when
ApitallyAutoConfiguration invokes register().
🧹 Nitpick comments (1)
src/main/java/io/apitally/common/RequestLogger.java (1)

151-190: Consider adding a backward-compatible overload for logRequest

The signature change can break external users of this SDK. If RequestLogger is part of the public API, consider keeping the old overload delegating to the new one (or explicitly bump major version / document the break).

♻️ Suggested overload
+    public void logRequest(Request request, Response response, Exception exception) {
+        logRequest(request, response, exception, null);
+    }
+
     public void logRequest(Request request, Response response, Exception exception, List<LogRecord> logs) {
         if (!enabled || suspendUntil != null && suspendUntil > System.currentTimeMillis()) {
             return;
         }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.github/workflows/tests.yaml:
- Around line 41-43: The workflow matrix includes an invalid Spring Boot
version; remove "3.5.9" from the spring-boot matrix so it lists only released
versions (keep spring-boot: [3.0.13, 3.1.12, 3.2.12, 3.3.8, 3.4.3]) to prevent
Maven Central resolution failures; update the matrix entry named "spring-boot"
in the tests.yaml matrix block accordingly.
🧹 Nitpick comments (1)
src/test/java/io/apitally/common/RequestLoggerTest.java (1)

108-114: Consider adding timestamp validation for completeness.

The LogRecord includes a timestamp field that is set when creating the test log record (line 73), but the assertions only validate logger, level, and message. Adding a timestamp assertion would ensure the field is correctly serialized.

💡 Suggested enhancement
         JsonNode logsNode = jsonNode.get("logs");
         assertTrue(logsNode.isArray());
         assertEquals(1, logsNode.size());
+        assertTrue(logsNode.get(0).has("timestamp"));
+        assertTrue(logsNode.get(0).get("timestamp").asDouble() > 0);
         assertEquals("test.Logger", logsNode.get(0).get("logger").asText());
         assertEquals("INFO", logsNode.get(0).get("level").asText());
         assertEquals("Test log message", logsNode.get(0).get("message").asText());

@itssimon itssimon merged commit 1392b58 into main Jan 22, 2026
18 checks passed
@itssimon itssimon deleted the simon/dev-9-add-application-log-capture-to-java-sdk branch January 22, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants