summaryrefslogtreecommitdiff
path: root/src/main/cpp/fixedwindowrollingpolicy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/cpp/fixedwindowrollingpolicy.cpp')
-rw-r--r--src/main/cpp/fixedwindowrollingpolicy.cpp295
1 files changed, 295 insertions, 0 deletions
diff --git a/src/main/cpp/fixedwindowrollingpolicy.cpp b/src/main/cpp/fixedwindowrollingpolicy.cpp
new file mode 100644
index 0000000..0e94007
--- /dev/null
+++ b/src/main/cpp/fixedwindowrollingpolicy.cpp
@@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+#if defined(_MSC_VER)
+#pragma warning ( disable: 4231 4251 4275 4786 )
+#endif
+
+
+#include <log4cxx/logstring.h>
+#include <log4cxx/rolling/fixedwindowrollingpolicy.h>
+#include <log4cxx/helpers/pool.h>
+#include <log4cxx/helpers/integer.h>
+#include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/optionconverter.h>
+#include <log4cxx/helpers/loglog.h>
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/rolling/rolloverdescription.h>
+#include <log4cxx/rolling/filerenameaction.h>
+#include <log4cxx/rolling/gzcompressaction.h>
+#include <log4cxx/rolling/zipcompressaction.h>
+#include <log4cxx/pattern/integerpatternconverter.h>
+
+using namespace log4cxx;
+using namespace log4cxx::rolling;
+using namespace log4cxx::helpers;
+using namespace log4cxx::pattern;
+
+IMPLEMENT_LOG4CXX_OBJECT(FixedWindowRollingPolicy)
+
+FixedWindowRollingPolicy::FixedWindowRollingPolicy() :
+ minIndex(1), maxIndex(7) {
+}
+
+void FixedWindowRollingPolicy::setMaxIndex(int maxIndex1) {
+ this->maxIndex = maxIndex1;
+}
+
+void FixedWindowRollingPolicy::setMinIndex(int minIndex1) {
+ this->minIndex = minIndex1;
+}
+
+
+
+void FixedWindowRollingPolicy::setOption(const LogString& option,
+ const LogString& value) {
+ if (StringHelper::equalsIgnoreCase(option,
+ LOG4CXX_STR("MININDEX"),
+ LOG4CXX_STR("minindex"))) {
+ minIndex = OptionConverter::toInt(value, 1);
+ } else if (StringHelper::equalsIgnoreCase(option,
+ LOG4CXX_STR("MAXINDEX"),
+ LOG4CXX_STR("maxindex"))) {
+ maxIndex = OptionConverter::toInt(value, 7);
+ } else {
+ RollingPolicyBase::setOption(option, value);
+ }
+}
+
+/**
+ * {@inheritDoc}
+ */
+void FixedWindowRollingPolicy::activateOptions(Pool& p) {
+ RollingPolicyBase::activateOptions(p);
+
+ if (maxIndex < minIndex) {
+ LogLog::warn(
+ LOG4CXX_STR("MaxIndex cannot be smaller than MinIndex."));
+ maxIndex = minIndex;
+ }
+
+ if ((maxIndex - minIndex) > MAX_WINDOW_SIZE) {
+ LogLog::warn(LOG4CXX_STR("Large window sizes are not allowed."));
+ maxIndex = minIndex + MAX_WINDOW_SIZE;
+ }
+
+ PatternConverterPtr itc = getIntegerPatternConverter();
+
+ if (itc == NULL) {
+ throw IllegalStateException();
+ }
+}
+
+/**
+ * {@inheritDoc}
+ */
+RolloverDescriptionPtr FixedWindowRollingPolicy::initialize(
+ const LogString& file, bool append, log4cxx::helpers::Pool& p) {
+ LogString newActiveFile(file);
+ explicitActiveFile = false;
+
+ if (file.length() > 0) {
+ explicitActiveFile = true;
+ newActiveFile = file;
+ }
+
+ if (!explicitActiveFile) {
+ LogString buf;
+ ObjectPtr obj(new Integer(minIndex));
+ formatFileName(obj, buf, p);
+ newActiveFile = buf;
+ }
+
+ ActionPtr noAction;
+
+ return new RolloverDescription(newActiveFile, append, noAction, noAction);
+}
+
+/**
+ * {@inheritDoc}
+ */
+RolloverDescriptionPtr FixedWindowRollingPolicy::rollover(
+ const LogString& currentFileName,
+ log4cxx::helpers::Pool& p) {
+ RolloverDescriptionPtr desc;
+ if (maxIndex >= 0) {
+ int purgeStart = minIndex;
+
+ if (!explicitActiveFile) {
+ purgeStart++;
+ }
+
+ if (!purge(purgeStart, maxIndex, p)) {
+ return desc;
+ }
+
+ LogString buf;
+ ObjectPtr obj(new Integer(purgeStart));
+ formatFileName(obj, buf, p);
+
+ LogString renameTo(buf);
+ LogString compressedName(renameTo);
+ ActionPtr compressAction ;
+
+ if (StringHelper::endsWith(renameTo, LOG4CXX_STR(".gz"))) {
+ renameTo.resize(renameTo.size() - 3);
+ compressAction =
+ new GZCompressAction(
+ File().setPath(renameTo), File().setPath(compressedName), true);
+ } else if (StringHelper::endsWith(renameTo, LOG4CXX_STR(".zip"))) {
+ renameTo.resize(renameTo.size() - 4);
+ compressAction =
+ new ZipCompressAction(
+ File().setPath(renameTo), File().setPath(compressedName), true);
+ }
+
+ FileRenameActionPtr renameAction =
+ new FileRenameAction(
+ File().setPath(currentFileName), File().setPath(renameTo), false);
+
+ desc = new RolloverDescription(
+ currentFileName, false, renameAction, compressAction);
+ }
+
+ return desc;
+}
+
+/**
+ * Get index of oldest log file to be retained.
+ * @return index of oldest log file.
+ */
+int FixedWindowRollingPolicy::getMaxIndex() const {
+ return maxIndex;
+}
+
+/**
+ * Get index of most recent log file.
+ * @return index of oldest log file.
+ */
+int FixedWindowRollingPolicy::getMinIndex() const {
+ return minIndex;
+}
+
+
+/**
+ * Purge and rename old log files in preparation for rollover
+ * @param lowIndex low index
+ * @param highIndex high index. Log file associated with high
+ * index will be deleted if needed.
+ * @return true if purge was successful and rollover should be attempted.
+ */
+bool FixedWindowRollingPolicy::purge(int lowIndex, int highIndex, Pool& p) const {
+ int suffixLength = 0;
+
+ std::vector<FileRenameActionPtr> renames;
+ LogString buf;
+ ObjectPtr obj = new Integer(lowIndex);
+ formatFileName(obj, buf, p);
+
+ LogString lowFilename(buf);
+
+ if (lowFilename.compare(lowFilename.length() - 3, 3, LOG4CXX_STR(".gz")) == 0) {
+ suffixLength = 3;
+ } else if (lowFilename.compare(lowFilename.length() - 4, 4, LOG4CXX_STR(".zip")) == 0) {
+ suffixLength = 4;
+ }
+
+ for (int i = lowIndex; i <= highIndex; i++) {
+ File toRenameCompressed;
+ toRenameCompressed.setPath(lowFilename);
+ File toRenameBase;
+ toRenameBase.setPath(lowFilename.substr(0, lowFilename.length() - suffixLength));
+ File* toRename = &toRenameCompressed;
+ bool isBase = false;
+ bool exists = toRenameCompressed.exists(p);
+
+ if (suffixLength > 0) {
+ if (exists) {
+ if (toRenameBase.exists(p)) {
+ toRenameBase.deleteFile(p);
+ }
+ } else {
+ toRename = &toRenameBase;
+ exists = toRenameBase.exists(p);
+ isBase = true;
+ }
+ }
+
+ if (exists) {
+ //
+ // if at upper index then
+ // attempt to delete last file
+ // if that fails then abandon purge
+ if (i == highIndex) {
+ if (!toRename->deleteFile(p)) {
+ return false;
+ }
+
+ break;
+ }
+
+ //
+ // if intermediate index
+ // add a rename action to the list
+ buf.erase(buf.begin(), buf.end());
+ obj = new Integer(i + 1);
+ formatFileName(obj, buf, p);
+
+ LogString highFilename(buf);
+ LogString renameTo(highFilename);
+
+ if (isBase) {
+ renameTo =
+ highFilename.substr(0, highFilename.length() - suffixLength);
+ }
+
+ renames.push_back(new FileRenameAction(*toRename, File().setPath(renameTo), true));
+ lowFilename = highFilename;
+ } else {
+ break;
+ }
+ }
+
+ //
+ // work renames backwards
+ //
+ for(std::vector<FileRenameActionPtr>::reverse_iterator iter = renames.rbegin();
+ iter != renames.rend();
+ iter++) {
+
+ try {
+ if (!(*iter)->execute(p)) {
+ return false;
+ }
+ } catch (std::exception& ex) {
+ LogLog::warn(LOG4CXX_STR("Exception during purge in RollingFileAppender"));
+
+ return false;
+ }
+ }
+ return true;
+}
+
+#define RULES_PUT(spec, cls) \
+specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), (PatternConstructor) cls ::newInstance))
+
+
+log4cxx::pattern::PatternMap FixedWindowRollingPolicy::getFormatSpecifiers() const {
+ PatternMap specs;
+ RULES_PUT("i", IntegerPatternConverter);
+ RULES_PUT("index", IntegerPatternConverter);
+ return specs;
+}