blob: ee8d3a92efd8878536fcd166e65be5ce258b0002 [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.
#include "kudu/subprocess/subprocess_proxy.h"
#include <string>
#include <vector>
#include "kudu/gutil/strings/join.h"
#include "kudu/gutil/strings/substitute.h"
using std::string;
using std::vector;
using strings::Substitute;
namespace kudu {
namespace subprocess {
namespace {
// Helpers to generate log4j2 properties suitable for a Java-based subprocess.
// TODO(awong): if our logging requirements get more complex, we should
// consider a builder for these.
// $0: appender instance
// $1: appender name
// $2: log directory
// $3: log filename base - new logs will be called "{log directory}/{log
// filename base}.log" and will roll to include the date in the name
// $4: rollover policy size in MB
// $5: number of files max
const char* kLog4j2RollingPropertiesTemplate = R"(
appender.$0.type = RollingFile
appender.$0.name = $1
appender.$0.layout.type = PatternLayout
appender.$0.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%p - %t] (%F:%L) %m%n
appender.$0.filename = $2/$3.log
appender.$0.filePattern = $2/$3.%d{yyyyMMdd-HHmmss}.log.gz
appender.$0.policies.type = Policies
appender.$0.policies.size.type = SizeBasedTriggeringPolicy
appender.$0.policies.size.size = $4 MB
appender.$0.strategy.type = DefaultRolloverStrategy
appender.$0.strategy.max = $5
)";
// $0: appender instance
// $1: appender name
const char* kLog4j2ConsoleProperties = R"(
appender.$0.type = Console
appender.$0.name = $1
appender.$0.layout.type = PatternLayout
appender.$0.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%p - %t] (%F:%L) %m%n
)";
// $0: name of the creator of these properties (e.g. the program name)
// $1: comma-separated list of appender instances
// $2: newline-separated list of appender configs
// $3: log level (supports "all", "debug", "info", "warn", "error", "fatal")
// $4: comma-separated list of appender refs
// $5: newline-separated list of appender ref name specifications
const char* kLog4j2PropertiesTemplate = R"(
# THIS FILE WAS GENERATED BY $0.
status = error
name = PropertiesConfig
appenders = $1
$2
rootLogger.level = $3
rootLogger.appenderRefs = $4
$5
)";
} // anonymous namespace
string Log4j2Properties(const string& creator, const string& log_dir,
const string& log_filename, int rollover_size_mb,
int max_files, const string& log_level,
bool log_to_stdout) {
static const char* kRollingInstance = "rollingFile";
static const char* kRollingName = "RollingFileAppender";
static const char* kRollingRef = "rolling";
vector<string> appender_instances = { kRollingInstance };
vector<string> appender_names = { kRollingName };
vector<string> appender_configs = {
Substitute(kLog4j2RollingPropertiesTemplate, kRollingInstance, kRollingName,
log_dir, log_filename, rollover_size_mb, max_files)
};
vector<string> appender_refs = { kRollingRef };
if (log_to_stdout) {
static const char* kConsoleInstance = "console";
static const char* kConsoleName = "SystemOutAppender";
static const char* kConsoleRef = "stdout";
appender_instances.emplace_back(kConsoleInstance);
appender_names.emplace_back(kConsoleName);
appender_refs.emplace_back(kConsoleRef);
appender_configs.emplace_back(
strings::Substitute(kLog4j2ConsoleProperties, kConsoleInstance, kConsoleName));
}
DCHECK_EQ(appender_refs.size(), appender_names.size());
vector<string> appender_ref_name_specs(appender_refs.size());
for (int i = 0; i < appender_refs.size(); i++) {
appender_ref_name_specs.emplace_back(
strings::Substitute("rootLogger.appenderRef.$0.ref = $1",
appender_refs[i], appender_names[i]));
}
return Substitute(kLog4j2PropertiesTemplate, creator,
JoinStrings(appender_instances, ", "),
JoinStrings(appender_configs, "\n"),
log_level,
JoinStrings(appender_refs, ", "),
JoinStrings(appender_ref_name_specs, "\n"));
}
} // namespace subprocess
} // namespace kudu