Add aws_logging
This commit is contained in:
parent
22609c8683
commit
75a455a941
@ -26,6 +26,7 @@ cc_library(
|
||||
}),
|
||||
deps = [
|
||||
":aws_crypto",
|
||||
":aws_logging",
|
||||
"//tensorflow/c:logging",
|
||||
"//tensorflow/c:tf_status",
|
||||
"//tensorflow/c/experimental/filesystem:filesystem_interface",
|
||||
@ -46,6 +47,18 @@ cc_library(
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "aws_logging",
|
||||
srcs = ["aws_logging.cc"],
|
||||
hdrs = ["aws_logging.h"],
|
||||
deps = [
|
||||
"//tensorflow/c:logging",
|
||||
"@aws",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
],
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
tf_cc_test(
|
||||
name = "s3_filesystem_test",
|
||||
srcs = [
|
||||
|
159
tensorflow/c/experimental/filesystem/plugins/s3/aws_logging.cc
Normal file
159
tensorflow/c/experimental/filesystem/plugins/s3/aws_logging.cc
Normal file
@ -0,0 +1,159 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
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 "tensorflow/c/experimental/filesystem/plugins/s3/aws_logging.h"
|
||||
|
||||
#include <aws/core/Aws.h>
|
||||
#include <aws/core/utils/logging/AWSLogging.h>
|
||||
#include <aws/core/utils/logging/LogSystemInterface.h>
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "tensorflow/c/logging.h"
|
||||
|
||||
static constexpr char kAWSLoggingTag[] = "AWSLogging";
|
||||
|
||||
static const std::map<const std::string, const Aws::Utils::Logging::LogLevel>
|
||||
log_levels_string_to_aws = {
|
||||
{"off", Aws::Utils::Logging::LogLevel::Off},
|
||||
{"fatal", Aws::Utils::Logging::LogLevel::Fatal},
|
||||
{"error", Aws::Utils::Logging::LogLevel::Error},
|
||||
{"warn", Aws::Utils::Logging::LogLevel::Warn},
|
||||
{"info", Aws::Utils::Logging::LogLevel::Info},
|
||||
{"debug", Aws::Utils::Logging::LogLevel::Debug},
|
||||
{"trace", Aws::Utils::Logging::LogLevel::Trace}};
|
||||
|
||||
static const std::map<const int, const Aws::Utils::Logging::LogLevel>
|
||||
log_levels_tf_to_aws = {{0, Aws::Utils::Logging::LogLevel::Info},
|
||||
{1, Aws::Utils::Logging::LogLevel::Warn},
|
||||
{2, Aws::Utils::Logging::LogLevel::Error},
|
||||
{3, Aws::Utils::Logging::LogLevel::Fatal}};
|
||||
|
||||
namespace tf_s3_filesystem {
|
||||
|
||||
AWSLogSystem::AWSLogSystem(Aws::Utils::Logging::LogLevel log_level)
|
||||
: log_level_(log_level) {}
|
||||
|
||||
void AWSLogSystem::LogMessage(Aws::Utils::Logging::LogLevel log_level,
|
||||
const std::string& message) {
|
||||
if (message == "Initializing Curl library") return;
|
||||
switch (log_level) {
|
||||
case Aws::Utils::Logging::LogLevel::Info:
|
||||
TF_Log(TF_INFO, message.c_str());
|
||||
break;
|
||||
case Aws::Utils::Logging::LogLevel::Warn:
|
||||
TF_Log(TF_WARNING, message.c_str());
|
||||
break;
|
||||
case Aws::Utils::Logging::LogLevel::Error:
|
||||
TF_Log(TF_ERROR, message.c_str());
|
||||
break;
|
||||
case Aws::Utils::Logging::LogLevel::Fatal:
|
||||
TF_Log(TF_FATAL, message.c_str());
|
||||
break;
|
||||
default:
|
||||
// this will match for DEBUG, TRACE
|
||||
TF_Log(TF_INFO, message.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AWSLogSystem::Log(Aws::Utils::Logging::LogLevel log_level, const char* tag,
|
||||
const char* format, ...) {
|
||||
char buffer[256];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer, 256, format, args);
|
||||
va_end(args);
|
||||
LogMessage(log_level, buffer);
|
||||
}
|
||||
|
||||
void AWSLogSystem::LogStream(Aws::Utils::Logging::LogLevel log_level,
|
||||
const char* tag,
|
||||
const Aws::OStringStream& message_stream) {
|
||||
LogMessage(log_level, message_stream.rdbuf()->str().c_str());
|
||||
}
|
||||
|
||||
void AWSLogSystem::Flush() { return; }
|
||||
|
||||
static Aws::Utils::Logging::LogLevel TfLogLevelToAwsLogLevel(int level) {
|
||||
// Converts TF Log Levels INFO, WARNING, ERROR and FATAL to the AWS enum
|
||||
// values for the levels
|
||||
if (log_levels_tf_to_aws.find(level) != log_levels_tf_to_aws.end()) {
|
||||
return log_levels_tf_to_aws.at(level);
|
||||
} else {
|
||||
// default to fatal
|
||||
return Aws::Utils::Logging::LogLevel::Fatal;
|
||||
}
|
||||
}
|
||||
|
||||
static Aws::Utils::Logging::LogLevel ParseAwsLogLevelFromEnv() {
|
||||
// defaults to FATAL log level for the AWS SDK
|
||||
// this is because many normal tensorflow operations are logged as errors in
|
||||
// the AWS SDK such as checking if a file exists can log an error in AWS SDK
|
||||
// if the file does not actually exist. Another such case is when reading a
|
||||
// file till the end, TensorFlow expects to see an InvalidRange exception at
|
||||
// the end, but this would be an error in the AWS SDK. This confuses users,
|
||||
// hence the default setting.
|
||||
Aws::Utils::Logging::LogLevel log_level =
|
||||
Aws::Utils::Logging::LogLevel::Fatal;
|
||||
|
||||
const char* aws_env_var_val = getenv("AWS_LOG_LEVEL");
|
||||
if (aws_env_var_val != nullptr) {
|
||||
std::string maybe_integer_str(aws_env_var_val, strlen(aws_env_var_val));
|
||||
std::istringstream ss(maybe_integer_str);
|
||||
int level;
|
||||
ss >> level;
|
||||
if (ss.fail()) {
|
||||
// wasn't a number
|
||||
// expecting a string
|
||||
std::string level_str = maybe_integer_str;
|
||||
if (log_levels_string_to_aws.find(level_str) !=
|
||||
log_levels_string_to_aws.end()) {
|
||||
log_level = log_levels_string_to_aws.at(level_str);
|
||||
}
|
||||
} else {
|
||||
// backwards compatibility
|
||||
// valid number, but this number follows the standard TensorFlow log
|
||||
// levels need to convert this to AWS SDK logging level number
|
||||
log_level = TfLogLevelToAwsLogLevel(level);
|
||||
}
|
||||
}
|
||||
return log_level;
|
||||
}
|
||||
|
||||
static bool initialized = false;
|
||||
ABSL_CONST_INIT static absl::Mutex s3_logging_mutex(absl::kConstInit);
|
||||
void AWSLogSystem::InitializeAWSLogging() {
|
||||
absl::MutexLock l(&s3_logging_mutex);
|
||||
if (!initialized) {
|
||||
Aws::Utils::Logging::InitializeAWSLogging(Aws::MakeShared<AWSLogSystem>(
|
||||
kAWSLoggingTag, ParseAwsLogLevelFromEnv()));
|
||||
initialized = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AWSLogSystem::ShutdownAWSLogging() {
|
||||
absl::MutexLock l(&s3_logging_mutex);
|
||||
if (initialized) {
|
||||
Aws::Utils::Logging::ShutdownAWSLogging();
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tf_s3_filesystem
|
@ -0,0 +1,64 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
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.
|
||||
==============================================================================*/
|
||||
#ifndef TENSORFLOW_C_EXPERIMENTAL_FILESYSTEM_PLUGINS_S3_AWS_LOGGING_H_
|
||||
#define TENSORFLOW_C_EXPERIMENTAL_FILESYSTEM_PLUGINS_S3_AWS_LOGGING_H_
|
||||
|
||||
#include <aws/core/utils/logging/LogLevel.h>
|
||||
#include <aws/core/utils/logging/LogSystemInterface.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
namespace tf_s3_filesystem {
|
||||
|
||||
class AWSLogSystem : public Aws::Utils::Logging::LogSystemInterface {
|
||||
public:
|
||||
static void InitializeAWSLogging();
|
||||
static void ShutdownAWSLogging();
|
||||
|
||||
explicit AWSLogSystem(Aws::Utils::Logging::LogLevel log_level);
|
||||
virtual ~AWSLogSystem() = default;
|
||||
|
||||
// Gets the currently configured log level.
|
||||
Aws::Utils::Logging::LogLevel GetLogLevel(void) const override {
|
||||
return log_level_;
|
||||
}
|
||||
|
||||
// Set a new log level. This has the immediate effect of changing the log.
|
||||
void SetLogLevel(Aws::Utils::Logging::LogLevel log_level) {
|
||||
log_level_.store(log_level);
|
||||
}
|
||||
|
||||
// Does a printf style output to ProcessFormattedStatement. Don't use this,
|
||||
// it's unsafe. See LogStream.
|
||||
void Log(Aws::Utils::Logging::LogLevel log_level, const char* tag,
|
||||
const char* format, ...) override;
|
||||
|
||||
// Writes the stream to ProcessFormattedStatement.
|
||||
void LogStream(Aws::Utils::Logging::LogLevel log_level, const char* tag,
|
||||
const Aws::OStringStream& messageStream) override;
|
||||
|
||||
// Flushes the buffered messages if the logger supports buffering
|
||||
void Flush() override;
|
||||
|
||||
private:
|
||||
void LogMessage(Aws::Utils::Logging::LogLevel log_level,
|
||||
const std::string& message);
|
||||
std::atomic<Aws::Utils::Logging::LogLevel> log_level_;
|
||||
};
|
||||
|
||||
} // namespace tf_s3_filesystem
|
||||
|
||||
#endif // TENSORFLOW_C_EXPERIMENTAL_FILESYSTEM_PLUGINS_S3_AWS_LOGGING_H_
|
@ -38,6 +38,7 @@ limitations under the License.
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "tensorflow/c/experimental/filesystem/filesystem_interface.h"
|
||||
#include "tensorflow/c/experimental/filesystem/plugins/s3/aws_crypto.h"
|
||||
#include "tensorflow/c/experimental/filesystem/plugins/s3/aws_logging.h"
|
||||
#include "tensorflow/c/logging.h"
|
||||
#include "tensorflow/c/tf_status.h"
|
||||
|
||||
@ -187,6 +188,8 @@ static void GetS3Client(tf_s3_filesystem::S3File* s3_file) {
|
||||
absl::MutexLock l(&s3_file->initialization_lock);
|
||||
|
||||
if (s3_file->s3_client.get() == nullptr) {
|
||||
tf_s3_filesystem::AWSLogSystem::InitializeAWSLogging();
|
||||
|
||||
Aws::SDKOptions options;
|
||||
options.cryptoOptions.sha256Factory_create_fn = []() {
|
||||
return Aws::MakeShared<tf_s3_filesystem::AWSSHA256Factory>(
|
||||
@ -251,6 +254,7 @@ static void ShutdownClient(Aws::S3::S3Client* s3_client) {
|
||||
delete s3_client;
|
||||
Aws::SDKOptions options;
|
||||
Aws::ShutdownAPI(options);
|
||||
tf_s3_filesystem::AWSLogSystem::ShutdownAWSLogging();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user