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-2015 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.opends.server.admin.server.ConfigurationChangeListener; 027import org.opends.server.admin.std.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 /** {@inheritDoc} */ 049 @Override 050 public void initializeLogRetentionPolicy( 051 SizeLimitLogRetentionPolicyCfg config) 052 { 053 this.size = config.getDiskSpaceUsed(); 054 this.comparator = new FileComparator(); 055 this.config = config; 056 057 config.addSizeLimitChangeListener(this); 058 } 059 060 /** {@inheritDoc} */ 061 @Override 062 public boolean isConfigurationChangeAcceptable( 063 SizeLimitLogRetentionPolicyCfg config, 064 List<LocalizableMessage> unacceptableReasons) 065 { 066 // Changes should always be OK 067 return true; 068 } 069 070 /** {@inheritDoc} */ 071 @Override 072 public ConfigChangeResult applyConfigurationChange( 073 SizeLimitLogRetentionPolicyCfg config) 074 { 075 this.size = config.getDiskSpaceUsed(); 076 this.config = config; 077 078 return new ConfigChangeResult(); 079 } 080 081 /** {@inheritDoc} */ 082 @Override 083 public File[] deleteFiles(FileNamingPolicy fileNamingPolicy) 084 throws DirectoryException 085 { 086 File[] files = fileNamingPolicy.listFiles(); 087 if(files == null) 088 { 089 throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), 090 ERR_LOGGER_ERROR_LISTING_FILES.get(fileNamingPolicy.getInitialName())); 091 } 092 093 long totalLength = 0; 094 for (File file : files) 095 { 096 totalLength += file.length(); 097 } 098 099 logger.trace("Total size of files: %d, Max: %d", totalLength, size); 100 101 if (totalLength <= size) 102 { 103 return EMPTY_FILE_LIST; 104 } 105 106 long freeSpaceNeeded = totalLength - size; 107 108 // Sort files based on last modified time. 109 Arrays.sort(files, comparator); 110 111 long freedSpace = 0; 112 int j; 113 for (j = files.length - 1; j >= 0; j--) 114 { 115 freedSpace += files[j].length(); 116 if (freedSpace >= freeSpaceNeeded) 117 { 118 break; 119 } 120 } 121 122 File[] filesToDelete = new File[files.length - j]; 123 System.arraycopy(files, j, filesToDelete, 0, filesToDelete.length); 124 return filesToDelete; 125 } 126 127 /** {@inheritDoc} */ 128 @Override 129 public String toString() 130 { 131 return "Size Based Retention Policy " + config.dn(); 132 } 133} 134