001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.loggers; 018import static org.opends.messages.LoggerMessages.*; 019 020import java.io.File; 021import java.util.Arrays; 022import java.util.List; 023 024import org.forgerock.i18n.LocalizableMessage; 025import org.forgerock.i18n.slf4j.LocalizedLogger; 026import org.forgerock.opendj.config.server.ConfigurationChangeListener; 027import org.forgerock.opendj.server.config.server.SizeLimitLogRetentionPolicyCfg; 028import org.opends.server.core.DirectoryServer; 029import org.forgerock.opendj.config.server.ConfigChangeResult; 030import org.opends.server.types.DirectoryException; 031 032/** 033 * This class implements a retention policy based on the amount of 034 * space taken by the log files. 035 */ 036public class SizeBasedRetentionPolicy implements 037 RetentionPolicy<SizeLimitLogRetentionPolicyCfg>, 038 ConfigurationChangeListener<SizeLimitLogRetentionPolicyCfg> 039{ 040 041 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 042 private static final File[] EMPTY_FILE_LIST = new File[0]; 043 044 private long size; 045 private FileComparator comparator; 046 private SizeLimitLogRetentionPolicyCfg config; 047 048 @Override 049 public void initializeLogRetentionPolicy( 050 SizeLimitLogRetentionPolicyCfg config) 051 { 052 this.size = config.getDiskSpaceUsed(); 053 this.comparator = new FileComparator(); 054 this.config = config; 055 056 config.addSizeLimitChangeListener(this); 057 } 058 059 @Override 060 public boolean isConfigurationChangeAcceptable( 061 SizeLimitLogRetentionPolicyCfg config, 062 List<LocalizableMessage> unacceptableReasons) 063 { 064 // Changes should always be OK 065 return true; 066 } 067 068 @Override 069 public ConfigChangeResult applyConfigurationChange( 070 SizeLimitLogRetentionPolicyCfg config) 071 { 072 this.size = config.getDiskSpaceUsed(); 073 this.config = config; 074 075 return new ConfigChangeResult(); 076 } 077 078 @Override 079 public File[] deleteFiles(FileNamingPolicy fileNamingPolicy) 080 throws DirectoryException 081 { 082 File[] files = fileNamingPolicy.listFiles(); 083 if(files == null) 084 { 085 throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), 086 ERR_LOGGER_ERROR_LISTING_FILES.get(fileNamingPolicy.getInitialName())); 087 } 088 089 long totalLength = 0; 090 for (File file : files) 091 { 092 totalLength += file.length(); 093 } 094 095 logger.trace("Total size of files: %d, Max: %d", totalLength, size); 096 097 if (totalLength <= size) 098 { 099 return EMPTY_FILE_LIST; 100 } 101 102 long freeSpaceNeeded = totalLength - size; 103 104 // Sort files based on last modified time. 105 Arrays.sort(files, comparator); 106 107 long freedSpace = 0; 108 int j; 109 for (j = files.length - 1; j >= 0; j--) 110 { 111 freedSpace += files[j].length(); 112 if (freedSpace >= freeSpaceNeeded) 113 { 114 break; 115 } 116 } 117 118 File[] filesToDelete = new File[files.length - j]; 119 System.arraycopy(files, j, filesToDelete, 0, filesToDelete.length); 120 return filesToDelete; 121 } 122 123 @Override 124 public String toString() 125 { 126 return "Size Based Retention Policy " + config.dn(); 127 } 128} 129