Skip to content

Conversation

@OpenZYK
Copy link

@OpenZYK OpenZYK commented Dec 23, 2025

At 0 o 'clock every day, a large number of machines begin to compress the log files of the previous day, resulting in the sharp rise of the disk IO of the container, which brings risk to the stability of the cloud disk. Now, the compression random delay x seconds is introduced to reduce the concentration of the compression trigger time and reduce the pressure on the disk.

        <RollingFile name="RollingFile" 
                    fileName="logs/app.log" 
                    filePattern="logs/app-%d{MM-dd-yyyy}-%i.log.gz">
           <PatternLayout>
               <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
           </PatternLayout>
           <Policies>
               <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
               <SizeBasedTriggeringPolicy size="10 MB"/>
           </Policies>
           <!-- deferred compression 1s~30s -->
           <DefaultRolloverStrategy max="10" delayedCompressionSeconds="30"/>
       </RollingFile>

@OpenZYK OpenZYK changed the title feature:support random delay compression feature:support random deferred compression Dec 24, 2025
@github-actions
Copy link

github-actions bot commented Dec 24, 2025

Job Requested goals Build Tool Version Build Outcome Build Scan®
build-macos-latest clean install 3.9.8 Build Scan PUBLISHED
build-ubuntu-latest clean install 3.9.8 Build Scan PUBLISHED
build-windows-latest clean install 3.9.8 Build Scan PUBLISHED
Generated by gradle/develocity-actions

@Mrkell76
Copy link

@

Copy link
Member

@vy vy left a comment

Choose a reason for hiding this comment

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

@OpenZYK, I think the suggested feature sounds legitimate. I've skimmed through the changes, and dropped some remarks. Would you also mind providing a test and a changelog entry, please?

Comment on lines 28 to 30
* Wrapper action that schedules compression for defferred execution.
* This action wraps another action and schedules it to be executed
* after a random defer within a specified time window.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Wrapper action that schedules compression for defferred execution.
* This action wraps another action and schedules it to be executed
* after a random defer within a specified time window.
* Decorates an {@link Action} to execute it after a certain amount of delay.

private boolean interrupted = false;

/**
* Creates a new DelayedCompressionAction.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Creates a new DelayedCompressionAction.
* Creates a new instance.

/**
* Creates a new DelayedCompressionAction.
*
* @param originalAction the action to be executed with defer
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param originalAction the action to be executed with defer
* @param originalAction the action to be executed with delay

* This action wraps another action and schedules it to be executed
* after a random defer within a specified time window.
*/
public class DeferredCompressionAction implements Action {
Copy link
Member

Choose a reason for hiding this comment

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

I think your earlier attempt, DelayedCompressionAction, fits the bill better. AFAICT, deferred waits for a condition, which does not necessarily needs to be a time, whereas delay makes it clear the involvement of time.

Once you implement this change, please update all the usages of [Dd]efer in this PR.

Comment on lines 52 to 57
/**
* Executes the action with a defer using sleep.
*
* @return true if the action was successfully executed
* @throws IOException if an error occurs during execution
*/
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/**
* Executes the action with a defer using sleep.
*
* @return true if the action was successfully executed
* @throws IOException if an error occurs during execution
*/

*/
@Override
public boolean execute() throws IOException {
if (interrupted) {
Copy link
Member

Choose a reason for hiding this comment

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

What about complete == true?

* @param originalAction the action to be executed with defer
* @param maxDeferSeconds the maximum defer in seconds (0 means immediate execution)
*/
public DeferredCompressionAction(Action originalAction, int maxDeferSeconds) {
Copy link
Member

Choose a reason for hiding this comment

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

Question: Shouldn't we be receiving a range instead of an upper bound?

@vy vy self-assigned this Dec 26, 2025
@vy vy added the appenders:Rolling Affects log file rolling functionality label Dec 26, 2025
@vy
Copy link
Member

vy commented Dec 26, 2025

@OpenZYK, TimeBasedTriggeringPolicy receives a maxRandomDelay configuration attribute — doesn't that precisely address the problem you're describing?

@OpenZYK
Copy link
Author

OpenZYK commented Dec 29, 2025

TimeBasedTriggeringPolicy receives a maxRandomDelay configuration attribute — This is a parameter for scrolling files, which may cause the logs of the first day to be written to the files of the next day. Splitting files itself is not very IO expensive, but what I'm addressing here is the impact of compression on disk IO. I will add some tests based on your suggestion

@vy
Copy link
Member

vy commented Dec 29, 2025

Can't we change the default behavior of the TimeBasedTriggeringPolicy.maxRandomDelay configuration attribute such that it will not affect the cut off time? That is, the roll over will happen precisely at the right time, but only the compression will honor the delay? @ppkarwasz, WDYT?

@ppkarwasz
Copy link
Contributor

@vy,

I think delaying when a rollover is triggered and delaying when the asynchronous rollover actions execute should have separate configuration knobs.

The execution of asynchronous actions lives in RollingFileManager, so tying that behavior to an attribute on a specific TriggeringPolicy (or rollover strategy) feels like a layering violation.

For this PR specifically, I believe there’s a simpler and cleaner approach: instead of wrapping actions and sleeping, we could replace the ExecutorService in RollingFileManager with a ScheduledExecutorService and apply the delay at scheduling time.

@OpenZYK
Copy link
Author

OpenZYK commented Dec 30, 2025

@ppkarwasz Your suggestion is great! I will follow this idea and add some test cases

@OpenZYK OpenZYK changed the title feature:support random deferred compression feature:support random delayed compression Dec 31, 2025
@ppkarwasz
Copy link
Contributor

@OpenZYK,

To be clear what I suggested was to start the AsyncAction from RollingFileManager with a delay, not to start delayed actions from within DelayedCompressAction: the rollover process has many inter-dependent actions and it is much simpler to execute them sequentially. If you execute them in parallel, you will encounter many subtle bugs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

appenders:Rolling Affects log file rolling functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants