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