-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[ingestion] Add rate-limited exception logging for transformers #17239
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
[ingestion] Add rate-limited exception logging for transformers #17239
Conversation
- Simplified API: PinotThrottledLogger now accepts IngestionConfig and table name directly, eliminating duplicated rate conversion logic across transformers - Backward compatible: Changed default ingestionExceptionLogRateLimitPerMin from 5 to 0; rate=0 falls back to DEBUG logging (original behavior) - Added ServerMeter emission: LOGS_DROPPED_BY_THROTTLED_LOGGER metric tracks suppressed logs per table when table name is provided - Updated all transformers: FilterTransformer, DataTypeTransformer, ComplexTypeTransformer, ExpressionTransformer, SchemaConformingTransformer, TimeValidationTransformer now use simplified constructor - Test updates: PinotThrottledLoggerTest updated to verify DEBUG fallback behavior when rate=0
…dLogger Key changes: - Log throttled exceptions at DEBUG level to ensure no exception info is lost - Simplify from ConcurrentHashMap/AtomicLong to HashMap/long for single-threaded usage - Combine two maps into one ExceptionState wrapper for single lookup - Update javadoc to clarify three-level logging behavior - Remove thread-safety test (single-threaded per TransformPipeline instance) Logging behavior after this change: - Rate ≤ 0: All logs at DEBUG (backward compatible) - Rate > 0, within quota: WARN/ERROR with suppression counts - Rate > 0, quota exceeded: DEBUG while tracking suppression counts
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #17239 +/- ##
============================================
+ Coverage 63.17% 63.19% +0.01%
- Complexity 1428 1432 +4
============================================
Files 3121 3133 +12
Lines 184814 185904 +1090
Branches 28332 28401 +69
============================================
+ Hits 116760 117473 +713
- Misses 59033 59366 +333
- Partials 9021 9065 +44
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Jackie-Jiang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly good. Please update the PR description about the concurrency part
pinot-common/src/main/java/org/apache/pinot/common/utils/PinotThrottledLogger.java
Outdated
Show resolved
Hide resolved
pinot-common/src/main/java/org/apache/pinot/common/utils/PinotThrottledLogger.java
Outdated
Show resolved
Hide resolved
pinot-common/src/main/java/org/apache/pinot/common/utils/PinotThrottledLogger.java
Outdated
Show resolved
Hide resolved
pinot-common/src/main/java/org/apache/pinot/common/utils/PinotThrottledLogger.java
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| private void logWithRateLimit(String msg, Throwable t, BiConsumer<String, Throwable> consumer) { | ||
| if (_permitsPerSecond <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider modeling this as a separate DebugOnlyLogger. We can also have a UnthrottledLogger if necessary
pinot-common/src/main/java/org/apache/pinot/common/utils/PinotThrottledLogger.java
Outdated
Show resolved
Hide resolved
pinot-common/src/main/java/org/apache/pinot/common/metrics/ServerMeter.java
Outdated
Show resolved
Hide resolved
…ensive unit tests. Simplify `ThrottledLogger` by removing inlined RateLimiter and update related tests.
Jackie-Jiang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM otherwise
| } | ||
| LOGGER.debug("Caught exception while transforming complex types for record: {}", record.toString(), e); | ||
| _throttledLogger.warn( | ||
| String.format("Caught exception while transforming complex types for record: %s", record.toString()), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using String.format as it is quite expensive. Concatanation should be cheaper.
Given LOGGER.debug() doesn't do anything when debug level log is not enabled, and we are already paying overhead of constructing the string, we should consider either:
- Expose
acquire()from_throttledLogger - Pass arguments the same way as what
LOGGERexpects
Not introduced in this PR, but we shouldn't call record.toString(). Instead, we should directly pass record
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed record logging itself. that address both performance and data risks.
…ving record details for clarity and consistency.
Introduces
ThrottledLoggerutility to provide rate-limited exception logging for record transformers, solving the problem where high-frequency errors pollute logs and starve low-frequency critical errors.Key Changes
Core Implementation
New
ThrottledLoggerutilityNew
RateLimiterclassUpdated 6 transformers to use throttled logger:
FilterTransformerDataTypeTransformerExpressionTransformerComplexTypeTransformerSchemaConformingTransformerTimeValidationTransformerNew configuration:
IngestionConfig.ingestionExceptionLogRateLimitPerMin(default: 5)Testing
Benefits
NumberFormatExceptionwon't starve low-frequencyConnectExceptionExample Output
Meanwhile, different exception types (e.g.,
ConnectException) log immediately using independent rate limiters.Implementation Details
IngestionConfigdirectly to logger@VisibleForTestingconstructor allows controlled time in tests