blob: 5f7bcd23ce7fa87238976ba2d767f88a493354c6 [file] [log] [blame]
/*
* 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 org.apache.geode.internal.logging;
import static org.apache.geode.internal.logging.ManagerLogWriter.getLogNameForOldMainLog;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.geode.GemFireIOException;
import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.internal.OSProcess;
import org.apache.geode.internal.process.ProcessLauncherContext;
import org.apache.geode.internal.statistics.StatisticsConfig;
import org.apache.geode.internal.util.LogFileUtils;
/**
* Factory for creating a {@link ManagerLogWriter}.
*/
public class ManagerLogWriterFactory {
private static final Logger LOGGER = StatusLogger.getLogger();
private final LogFileRolloverDetails logFileRolloverDetails;
private boolean security;
private boolean appendLog;
public ManagerLogWriterFactory() {
logFileRolloverDetails = new LogFileRolloverDetails();
}
public ManagerLogWriterFactory setSecurity(final boolean value) {
security = value;
return this;
}
public ManagerLogWriterFactory setAppendLog(final boolean value) {
appendLog = value;
return this;
}
public LogFileRolloverDetails getLogFileRolloverDetails() {
return logFileRolloverDetails;
}
public ManagerLogWriter create(final LogConfig logConfig, final StatisticsConfig statsConfig) {
File logFile = getLogFile(logConfig);
if (logFile == null || logFile.equals(new File(""))) {
return null;
}
// if logFile exists attempt to rename it for rolling
if (logFile.exists()) {
boolean useChildLogging = useChildLogging(logConfig);
boolean statArchivesRolling = statArchivesRolling(statsConfig);
if (!appendLog || useChildLogging || statArchivesRolling) {
File oldMain =
getLogNameForOldMainLog(logFile, security || useChildLogging || statArchivesRolling);
boolean succeeded = LogFileUtils.renameAggressively(logFile, oldMain);
if (succeeded) {
logFileRolloverDetails.message = String.format("Renamed old log file to %s.", oldMain);
} else {
logFileRolloverDetails.warning = true;
logFileRolloverDetails.message =
String.format("Could not rename %s to %s.", logFile, oldMain);
}
}
}
ManagerLogWriter logWriter = newManagerLogWriter(logConfig, createPrintStream(logFile));
logWriter.setConfig(logConfig);
redirectOutput(logConfig);
return logWriter;
}
@VisibleForTesting
File getLogFile(final LogConfig config) {
if (security) {
return config.getSecurityLogFile();
} else {
return config.getLogFile();
}
}
@VisibleForTesting
int getLogLevel(final LogConfig config) {
if (security) {
return config.getSecurityLogLevel();
} else {
return config.getLogLevel();
}
}
private boolean useChildLogging(final LogConfig config) {
return config.getLogFile() != null
&& !config.getLogFile().equals(new File("")) && config.getLogFileSizeLimit() != 0;
}
private boolean statArchivesRolling(final StatisticsConfig config) {
return config.getStatisticArchiveFile() != null
&& !config.getStatisticArchiveFile().equals(new File(""))
&& config.getArchiveFileSizeLimit() != 0 && config.getStatisticSamplingEnabled();
}
private PrintStream createPrintStream(final File logFile) {
FileOutputStream fos;
try {
fos = new FileOutputStream(logFile, true);
} catch (FileNotFoundException e) {
String message = String.format("Could not open log file %s.", logFile);
throw new GemFireIOException(message, e);
}
return new PrintStream(fos);
}
private ManagerLogWriter newManagerLogWriter(final LogConfig config,
final PrintStream printStream) {
if (security) {
return new SecurityManagerLogWriter(getLogLevel(config), printStream, config.getName(),
config.isLoner());
} else {
return new ManagerLogWriter(getLogLevel(config), printStream, config.getName(),
config.isLoner());
}
}
private void redirectOutput(final LogConfig config) {
if (ProcessLauncherContext.isRedirectingOutput()) {
try {
OSProcess.redirectOutput(config.getLogFile());
} catch (IOException e) {
LOGGER.error("Unable to redirect output to {}", config.getLogFile(), e);
}
}
}
public static class LogFileRolloverDetails {
private String message;
private boolean warning;
public String getMessage() {
return message;
}
public boolean isWarning() {
return warning;
}
public boolean exists() {
return message != null;
}
}
}