blob: 6370096aeafc8cc95bd6c6bfda1142b439164461 [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 "Logging.h"
#include <iostream> // std::cerr, std::endl
#include <memory>
#include <mutex>
#if SPDLOG_VER_MAJOR >= 1
#include <spdlog/async.h>
#include <spdlog/sinks/rotating_file_sink.h>
#else
#include <spdlog/async_logger.h>
#endif
#include "UtilAll.h"
namespace rocketmq {
static void ConfigSpdlog() {
spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v [%@ (%!)]");
// when an error occurred, flush disk immediately
spdlog::flush_on(spdlog::level::err);
#if SPDLOG_VER_MAJOR >= 1
spdlog::init_thread_pool(spdlog::details::default_async_q_size, 1);
spdlog::flush_every(std::chrono::seconds(3));
#else
spdlog::set_async_mode(8192, async_overflow_policy::block_retry, nullptr, std::chrono::milliseconds(3000), nullptr);
#endif
}
static std::shared_ptr<spdlog::logger> CreateRotatingLogger(const std::string& name,
const std::string& filepath,
std::size_t max_size,
std::size_t max_files) {
#if SPDLOG_VER_MAJOR >= 1
return spdlog::create_async<spdlog::sinks::rotating_file_sink_mt>(name, filepath, max_size, max_files);
#else
return spdlog::rotating_logger_mt(name, filepath, max_size, max_files);
#endif
}
static spdlog::level::level_enum ConvertLogLevel(LogLevel log_level) {
int level = static_cast<int>(log_level);
return static_cast<spdlog::level::level_enum>(6 - level);
}
static std::string GetDefaultLogDir() {
std::string log_dir;
const char* dir = std::getenv(ROCKETMQ_CPP_LOG_DIR_ENV.c_str());
if (dir != nullptr && dir[0] != '\0') {
// FIXME: replace '~' by home directory.
log_dir = dir;
} else {
log_dir = UtilAll::getHomeDirectory();
log_dir.append("/logs/rocketmq-cpp/");
}
if (log_dir[log_dir.size() - 1] != FILE_SEPARATOR) {
log_dir += FILE_SEPARATOR;
}
std::string log_file_name = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log";
return log_dir + log_file_name;
}
LoggerConfig& GetDefaultLoggerConfig() {
static LoggerConfig default_logger_config("default", GetDefaultLogDir());
return default_logger_config;
}
Logger& GetDefaultLogger() {
static Logger default_logger = []() {
auto& default_logger_config = GetDefaultLoggerConfig();
if (default_logger_config.config_spdlog()) {
ConfigSpdlog();
}
return Logger(default_logger_config);
}();
return default_logger;
}
Logger::Logger(const LoggerConfig& config) {
try {
logger_ = CreateRotatingLogger(config.name(), config.path(), config.file_size(), config.file_count());
logger_->set_level(ConvertLogLevel(config.level()));
} catch (std::exception& e) {
std::cerr << "initialite logger failed" << std::endl;
exit(-1);
}
}
Logger::~Logger() {
if (logger_ != nullptr) {
spdlog::drop(logger_->name());
}
}
} // namespace rocketmq