unioil-loyalty-rn-app/ios/Pods/Flipper-Folly/folly/logging/StandardLogHandlerFactory.cpp

195 lines
5.9 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed 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 <folly/logging/StandardLogHandlerFactory.h>
#include <folly/MapUtil.h>
#include <folly/String.h>
#include <folly/logging/CustomLogFormatter.h>
#include <folly/logging/GlogStyleFormatter.h>
#include <folly/logging/LogLevel.h>
#include <folly/logging/LogWriter.h>
#include <folly/logging/StandardLogHandler.h>
using std::string;
namespace folly {
namespace {
class GlogFormatterFactory
: public StandardLogHandlerFactory::FormatterFactory {
public:
bool processOption(StringPiece /* name */, StringPiece /* value */) override {
return false;
}
std::shared_ptr<LogFormatter> createFormatter(
const std::shared_ptr<LogWriter>& /* logWriter */) override {
return std::make_shared<GlogStyleFormatter>();
}
};
class CustomLogFormatterFactory
: public StandardLogHandlerFactory::FormatterFactory {
public:
enum Colored { ALWAYS, AUTO, NEVER };
bool processOption(StringPiece name, StringPiece value) override {
if (name == "log_format") {
format_ = value.str();
return true;
} else if (name == "colored") {
if (value == "always") {
colored_ = ALWAYS;
} else if (value == "auto") {
colored_ = AUTO;
} else if (value == "never") {
colored_ = NEVER;
} else {
throw std::invalid_argument(to<string>(
"unknown colored type \"",
value,
"\". Needs to be always/never/auto"));
}
return true;
}
return false;
}
std::shared_ptr<LogFormatter> createFormatter(
const std::shared_ptr<LogWriter>& logWriter) override {
bool colored;
switch (colored_) {
case ALWAYS:
colored = true;
break;
case AUTO:
colored = logWriter->ttyOutput();
break;
case NEVER:
colored = false;
break;
}
return std::make_shared<CustomLogFormatter>(format_, colored);
}
private:
std::string format_;
Colored colored_{NEVER}; // Turn off coloring by default.
};
} // namespace
std::shared_ptr<StandardLogHandler> StandardLogHandlerFactory::createHandler(
StringPiece type, WriterFactory* writerFactory, const Options& options) {
std::unique_ptr<FormatterFactory> formatterFactory;
// Get the log formatter type
auto* formatterType = get_ptr(options, "formatter");
if (!formatterType || *formatterType == "glog") {
formatterFactory = std::make_unique<GlogFormatterFactory>();
} else if (!formatterType || *formatterType == "custom") {
formatterFactory = std::make_unique<CustomLogFormatterFactory>();
} else {
throw std::invalid_argument(
to<string>("unknown log formatter type \"", *formatterType, "\""));
}
return createHandler(type, writerFactory, formatterFactory.get(), options);
}
std::shared_ptr<StandardLogHandler> StandardLogHandlerFactory::createHandler(
StringPiece type,
WriterFactory* writerFactory,
FormatterFactory* formatterFactory,
const Options& options) {
Optional<LogLevel> logLevel;
Optional<LogLevel> syncLevel;
// Process the log formatter and log handler options
std::vector<string> errors;
for (const auto& entry : options) {
bool handled = false;
try {
// Allow both the formatterFactory and writerFactory to consume an
// option. In general they probably should have mutually exclusive
// option names, but we don't give precedence to one over the other here.
handled |= formatterFactory->processOption(entry.first, entry.second);
handled |= writerFactory->processOption(entry.first, entry.second);
} catch (const std::exception& ex) {
errors.push_back(to<string>(
"error processing option \"", entry.first, "\": ", ex.what()));
continue;
}
// We explicitly processed the "formatter" option above.
handled |= handled || (entry.first == "formatter");
if (entry.first == "level") {
try {
logLevel = stringToLogLevel(entry.second);
} catch (const std::exception& ex) {
errors.push_back(to<string>(
"unable to parse value for option \"",
entry.first,
"\": ",
ex.what()));
}
handled = true;
} else if (entry.first == "sync_level") {
// Process the "sync_level" option.
try {
syncLevel = stringToLogLevel(entry.second);
} catch (const std::exception& ex) {
errors.push_back(to<string>(
"unable to parse value for option \"",
entry.first,
"\": ",
ex.what()));
}
handled = true;
}
// Complain about unknown options.
if (!handled) {
errors.push_back(to<string>("unknown option \"", entry.first, "\""));
}
}
if (!errors.empty()) {
throw std::invalid_argument(join(", ", errors));
}
// Construct the formatter and writer
auto writer = writerFactory->createWriter();
auto formatter = formatterFactory->createFormatter(writer);
std::shared_ptr<StandardLogHandler> logHandler;
if (syncLevel) {
logHandler = std::make_shared<StandardLogHandler>(
LogHandlerConfig{type, options}, formatter, writer, *syncLevel);
} else {
logHandler = std::make_shared<StandardLogHandler>(
LogHandlerConfig{type, options}, formatter, writer);
}
if (logLevel) {
logHandler->setLevel(*logLevel);
}
return logHandler;
}
} // namespace folly