Commit 8af0eef9 authored by Adam Simpkins's avatar Adam Simpkins Committed by Facebook Github Bot

logging: add a LogConfig class and parsing code

Summary:
Add a new LogConfig class to represent the current configuration state of the
LoggerDB.  This also includes code to parse config strings in both JSON and a
simpler more human-writable format (intended primarily for use in command line
arguments).

I generally expect the human-writable format to be used mainly to configure log
levels.  It also supports configuring log handler details as well, but the
format for this data is slightly more cumbersome and will probably be harder
for people to easily remember.

The parsing code is intentionally kept as part of the 'init' library rather
than the core 'logging' library so that other libraries that simply wish to log
messages do not need to depend on it.  For instance, this would allow the folly
JSON library to use the logging library without causing a circular dependency.

Reviewed By: bolinfest

Differential Revision: D6200560

fbshipit-source-id: e4e3c7f941808251b6c7bcbbdac0210118675fb0
parent 65d63573
......@@ -385,6 +385,7 @@ if (BUILD_TESTS)
DIRECTORY experimental/logging/test/
TEST async_file_writer_test SOURCES AsyncFileWriterTest.cpp
TEST config_parser_test SOURCES ConfigParserTest.cpp
TEST glog_formatter_test SOURCES GlogFormatterTest.cpp
TEST immediate_file_writer_test SOURCES ImmediateFileWriterTest.cpp
TEST log_category_test SOURCES LogCategoryTest.cpp
......
......@@ -160,10 +160,14 @@ nobase_follyinclude_HEADERS = \
experimental/logging/ImmediateFileWriter.h \
experimental/logging/Init.h \
experimental/logging/LogCategory.h \
experimental/logging/LogCategoryConfig.h \
experimental/logging/LogConfig.h \
experimental/logging/LogConfigParser.h \
experimental/logging/LogFormatter.h \
experimental/logging/Logger.h \
experimental/logging/LoggerDB.h \
experimental/logging/LogHandler.h \
experimental/logging/LogHandlerConfig.h \
experimental/logging/LogLevel.h \
experimental/logging/LogMessage.h \
experimental/logging/LogName.h \
......
/*
* Copyright 2004-present Facebook, Inc.
*
* 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/experimental/logging/LogCategoryConfig.h>
namespace folly {
LogCategoryConfig::LogCategoryConfig(LogLevel l, bool inherit)
: level{l}, inheritParentLevel{inherit} {}
LogCategoryConfig::LogCategoryConfig(
LogLevel l,
bool inherit,
std::vector<std::string> h)
: level{l}, inheritParentLevel{inherit}, handlers{h} {}
bool LogCategoryConfig::operator==(const LogCategoryConfig& other) const {
return level == other.level &&
inheritParentLevel == other.inheritParentLevel &&
handlers == other.handlers;
}
bool LogCategoryConfig::operator!=(const LogCategoryConfig& other) const {
return !(*this == other);
}
} // namespace folly
/*
* Copyright 2004-present Facebook, Inc.
*
* 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.
*/
#pragma once
#include <string>
#include <vector>
#include <folly/Optional.h>
#include <folly/experimental/logging/LogLevel.h>
namespace folly {
/**
* Configuration for a LogCategory
*/
class LogCategoryConfig {
public:
explicit LogCategoryConfig(
LogLevel level = LogLevel::WARNING,
bool inheritParentLevel = true);
LogCategoryConfig(
LogLevel level,
bool inheritParentLevel,
std::vector<std::string> handlers);
bool operator==(const LogCategoryConfig& other) const;
bool operator!=(const LogCategoryConfig& other) const;
/**
* The LogLevel for this category.
*/
LogLevel level{LogLevel::WARNING};
/**
* Whether this category should inherit its effective log level from its
* parent category, if the parent category has a more verbose log level.
*/
bool inheritParentLevel{true};
/**
* An optional list of LogHandler names to use for this category.
*
* When applying config changes to an existing LogCategory, the existing
* LogHandler list will be left unchanged if this field is unset.
*/
Optional<std::vector<std::string>> handlers;
};
} // namespace folly
/*
* Copyright 2004-present Facebook, Inc.
*
* 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/experimental/logging/LogConfig.h>
namespace folly {
bool LogConfig::operator==(const LogConfig& other) const {
return handlerConfigs_ == other.handlerConfigs_ &&
categoryConfigs_ == other.categoryConfigs_;
}
bool LogConfig::operator!=(const LogConfig& other) const {
return !(*this == other);
}
} // namespace folly
/*
* Copyright 2004-present Facebook, Inc.
*
* 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.
*/
#pragma once
#include <string>
#include <unordered_map>
#include <folly/experimental/logging/LogCategoryConfig.h>
#include <folly/experimental/logging/LogHandlerConfig.h>
namespace folly {
/**
* LogConfig contains configuration for the LoggerDB.
*
* This includes information about the log levels for log categories,
* as well as what log handlers are configured and which categories they are
* attached to.
*/
class LogConfig {
public:
using CategoryConfigMap = std::unordered_map<std::string, LogCategoryConfig>;
using HandlerConfigMap = std::unordered_map<std::string, LogHandlerConfig>;
LogConfig() = default;
explicit LogConfig(
HandlerConfigMap handlerConfigs,
CategoryConfigMap catConfigs)
: handlerConfigs_{std::move(handlerConfigs)},
categoryConfigs_{std::move(catConfigs)} {}
const CategoryConfigMap& getCategoryConfigs() const {
return categoryConfigs_;
}
const HandlerConfigMap& getHandlerConfigs() const {
return handlerConfigs_;
}
bool operator==(const LogConfig& other) const;
bool operator!=(const LogConfig& other) const;
private:
HandlerConfigMap handlerConfigs_;
CategoryConfigMap categoryConfigs_;
};
} // namespace folly
This diff is collapsed.
/*
* Copyright 2004-present Facebook, Inc.
*
* 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.
*/
#pragma once
#include <stdexcept>
#include <folly/Range.h>
#include <folly/experimental/logging/LogConfig.h>
/*
* This file contains utility functions for parsing and serializing
* LogConfig strings.
*
* This is separate from the LogConfig class itself, to reduce the dependencies
* of the core logging library. Other code that wants to use the logging
* library to log messages but does not need to parse log config strings
* therefore does not need to depend on the folly JSON library.
*/
namespace folly {
struct dynamic;
class LogConfigParseError : public std::invalid_argument {
public:
using std::invalid_argument::invalid_argument;
};
/**
* Parse a log configuration string.
*
* See the documentation in logging/docs/Config.md for a description of the
* configuration string syntax.
*
* Throws a LogConfigParseError on error.
*/
LogConfig parseLogConfig(StringPiece value);
/**
* Parse a JSON configuration string.
*
* See the documentation in logging/docs/Config.md for a description of the
* JSON configuration object format.
*
* This function uses relaxed JSON parsing, allowing C and C++ style
* comments, as well as trailing commas.
*/
LogConfig parseLogConfigJson(StringPiece value);
/**
* Parse a folly::dynamic object.
*
* The input should be an object data type, and is parsed the same as a JSON
* object accpted by parseLogConfigJson().
*/
LogConfig parseLogConfigDynamic(const dynamic& value);
/**
* Convert a LogConfig object to a folly::dynamic object.
*
* This can be used to serialize it as a JSON string, which can later be read
* back using parseLogConfigJson().
*/
dynamic logConfigToDynamic(const LogConfig& config);
dynamic logConfigToDynamic(const LogHandlerConfig& config);
dynamic logConfigToDynamic(const LogCategoryConfig& config);
} // namespace folly
/*
* Copyright 2004-present Facebook, Inc.
*
* 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/experimental/logging/LogHandlerConfig.h>
namespace folly {
LogHandlerConfig::LogHandlerConfig(StringPiece t) : type{t.str()} {}
LogHandlerConfig::LogHandlerConfig(StringPiece t, Options opts)
: type{t.str()}, options{std::move(opts)} {}
bool LogHandlerConfig::operator==(const LogHandlerConfig& other) const {
return type == other.type && options == other.options;
}
bool LogHandlerConfig::operator!=(const LogHandlerConfig& other) const {
return !(*this == other);
}
} // namespace folly
/*
* Copyright 2004-present Facebook, Inc.
*
* 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.
*/
#pragma once
#include <string>
#include <unordered_map>
#include <folly/Range.h>
namespace folly {
/**
* Configuration for a LogHandler
*/
class LogHandlerConfig {
public:
using Options = std::unordered_map<std::string, std::string>;
explicit LogHandlerConfig(folly::StringPiece type);
LogHandlerConfig(folly::StringPiece type, Options options);
bool operator==(const LogHandlerConfig& other) const;
bool operator!=(const LogHandlerConfig& other) const;
std::string type;
Options options;
};
} // namespace folly
......@@ -8,8 +8,12 @@ libfollylogging_la_SOURCES = \
ImmediateFileWriter.cpp \
Init.cpp \
LogCategory.cpp \
LogCategoryConfig.cpp \
LogConfig.cpp \
LogConfigParser.cpp \
Logger.cpp \
LoggerDB.cpp \
LogHandlerConfig.cpp \
LogLevel.cpp \
LogMessage.cpp \
LogName.cpp \
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment