blob: 8c2a09c3bfd3558251c733169ceeba4faef3b09a [file]
/*
* 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 "fury/util/logging.h"
#include "absl/debugging/failure_signal_handler.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
#include "fury/util/time_util.h"
#include <unordered_map>
#include <vector>
namespace std {
template <> struct hash<fury::FuryLogLevel> {
size_t operator()(fury::FuryLogLevel t) const { return size_t(t); }
};
} // namespace std
namespace fury {
const FuryLogLevel fury_severity_threshold = FuryLog::GetLogLevel();
std::string GetCallTrace() {
std::vector<void *> local_stack;
local_stack.resize(100);
absl::GetStackTrace(local_stack.data(), 100, 0);
static constexpr size_t buf_size = 16 * 1024;
char buf[buf_size];
std::string output;
for (auto &stack : local_stack) {
if (absl::Symbolize(stack, buf, buf_size)) {
output.append(" ").append(buf).append("\n");
}
}
return output;
}
std::unordered_map<FuryLogLevel, std::string> log_level_to_str = {
{FuryLogLevel::DEBUG, "DEBUG"}, {FuryLogLevel::INFO, "INFO"},
{FuryLogLevel::WARNING, "WARNING"}, {FuryLogLevel::ERROR, "ERROR"},
{FuryLogLevel::FATAL, "FATAL"},
};
std::string LogLevelAsString(FuryLogLevel level) {
auto it = log_level_to_str.find(level);
if (it == log_level_to_str.end()) {
return "UNKNOWN";
}
return it->second;
}
FuryLogLevel FuryLog::GetLogLevel() {
FuryLogLevel severity_threshold = FuryLogLevel::INFO;
const char *var_value = std::getenv("FURY_LOG_LEVEL");
if (var_value != nullptr) {
std::string data = var_value;
std::transform(data.begin(), data.end(), data.begin(), ::tolower);
if (data == "debug") {
severity_threshold = FuryLogLevel::DEBUG;
} else if (data == "info") {
severity_threshold = FuryLogLevel::INFO;
} else if (data == "warning") {
severity_threshold = FuryLogLevel::WARNING;
} else if (data == "error") {
severity_threshold = FuryLogLevel::ERROR;
} else if (data == "fatal") {
severity_threshold = FuryLogLevel::FATAL;
} else {
FURY_LOG_INTERNAL(WARNING)
<< "Unrecognized setting of FuryLogLevel=" << var_value;
}
FURY_LOG_INTERNAL(INFO)
<< "Set ray log level from environment variable RAY_BACKEND_LOG_LEVEL"
<< " to " << static_cast<int>(severity_threshold);
}
return severity_threshold;
}
FuryLog::FuryLog(const char *file_name, int line_number, FuryLogLevel severity)
: severity_(severity) {
Stream() << "[" << FormatTimePoint(std::chrono::system_clock::now()) << "] "
<< LogLevelAsString(severity) << " " << file_name << ":"
<< line_number << ": ";
}
FuryLog::~FuryLog() {
if (severity_ == FuryLogLevel::FATAL) {
Stream() << "\n*** StackTrace Information ***\n" << ::fury::GetCallTrace();
Stream() << std::endl;
std::_Exit(EXIT_FAILURE);
}
Stream() << "\n" << std::endl;
}
bool FuryLog::IsLevelEnabled(FuryLogLevel log_level) {
return log_level >= fury_severity_threshold;
}
} // namespace fury