KeepLastNCleanupPolicy.java
/*
* Copyright 2017 Providence Authors
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package net.morimekta.providence.logging.rolling;
import net.morimekta.providence.logging.RollingFileMessageWriter;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Cleanup policy that keeps the N <i>previous</i> files. This means
* there should be no more than <code>N + 1</code> files or the writer
* at any time.
*/
public class KeepLastNCleanupPolicy implements RollingFileMessageWriter.CleanupPolicy {
private final int keepLastN;
private final Pattern filePattern;
public KeepLastNCleanupPolicy(int keepLastN,
String filePattern) {
this(keepLastN, Pattern.compile(filePattern));
}
public KeepLastNCleanupPolicy(int keepLastN,
Pattern filePattern) {
this.keepLastN = keepLastN;
this.filePattern = filePattern;
}
@Nonnull
@Override
@SuppressWarnings("unchecked")
public List<String> getFilesToDelete(@Nonnull List<String> candidateFiles,
@Nonnull String currentFileName) {
List<String> out = new ArrayList<>();
List<String> candidatesBeforeFiles = candidateFiles
.stream()
.filter(f -> filePattern.matcher(f).matches())
.filter(f -> f.compareTo(currentFileName) < 0)
.sorted()
.collect(Collectors.toList());
List<String> candidatesAfterFiles = candidateFiles
.stream()
.filter(f -> filePattern.matcher(f).matches())
.filter(f -> f.compareTo(currentFileName) > 0)
.sorted()
.collect(Collectors.toList());
// including N as this list does not contain the current file.
if (candidatesAfterFiles.size() > 0 &&
candidatesAfterFiles.size() + candidatesBeforeFiles.size() >= keepLastN) {
// First remove files sorted AFTER the current file.
int remove = (candidatesBeforeFiles.size() + candidatesAfterFiles.size()) - keepLastN + 1;
out.addAll(candidatesAfterFiles.stream()
.limit(remove)
.collect(Collectors.toList()));
}
// including N as this list does not contain the current file.
if (candidatesBeforeFiles.size() >= keepLastN) {
int remove = candidatesBeforeFiles.size() - keepLastN + 1;
out.addAll(candidatesBeforeFiles.subList(0, remove));
}
return out;
}
}