

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在适用于 C\$1\$1 的 AWS SDK 中配置和使用日志记录
<a name="logging"></a>

适用于 C\$1\$1 的 AWS SDK 包括可配置的日志记录，用于生成 SDK 在执行期间所执行操作的记录。要启用日志记录，请将 `SDKOptions` 的 `LogLevel` 设置为适合您的应用程序的详细程度。

```
    Aws::SDKOptions options;
    options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info;
```

有七个详细级别可供选择。默认值为 `Off`，不生成日志。`Trace` 将生成最详细的细节，`Fatal` 将生成最少的消息，仅报告致命错误情况。

在您的应用程序中启用日志记录功能后，SDK 将按照默认命名模式（`aws_sdk_<date>.log`）在您的可执行文件目录中生成日志文件。由前缀命名选项生成的日志文件每小时滚动一次，以便存档或删除日志文件。

SDK 的较新版本越来越依赖底层的 AWS 公共运行时（CRT）库。这些库在 SDK 中提供通用功能和基本操作。默认情况下，来自 CRT 库的所有日志消息都将重定向到适用于 C\$1\$1 的 SDK。您为适用于 C\$1\$1 的 SDK 指定的日志级别和日志记录系统也适用于 CRT。

在前面的示例中，CRT 将继承 `LogLevel::Info` 级别，并将 `Info` 级别的消息记录到同一文件中。

您可以独立控制 CRT 库的日志记录，方法是将其输出重定向到单独的日志文件，也可以为来自 CRT 的消息设置不同的日志级别。通常，降低 CRT 库的日志详细级别是有好处的，这样可以避免它们使日志信息量过大。例如，**只有 CRT 输出的日志级别可以设置为 `Warn`，如下所示：

```
options.loggingOptions.crt_logger_create_fn =
    [](){ return Aws::MakeShared<Aws::Utils::Logging::DefaultCRTLogSystem>("CRTLogSystem", Aws::Utils::Logging::LogLevel::Warn); };
```

（可选）通过使用方法 `InitializeAWSLogging`，您可以控制 `DefaultLogSystem` 的详细级别和日志输出。您可以配置日志文件名前缀，或者将输出重定向到流而不是文件。

```
Aws::Utils::Logging::InitializeAWSLogging(
    Aws::MakeShared<Aws::Utils::Logging::DefaultLogSystem>(
        "RunUnitTests", Aws::Utils::Logging::LogLevel::Trace, "aws_sdk_"));
```

或者，除了使用 `DefaultLogSystem`，您也可以使用此方法来提供自己的日志记录实现。

```
InitializeAWSLogging(Aws::MakeShared<CustomLoggingSystem>());
```

如果您调用方法 `InitializeAWSLogging`，请在程序结束时通过调用 `ShutdownAWSLogging` 来释放资源。

```
Aws::Utils::Logging::ShutdownAWSLogging();
```

 **带日志记录的集成测试示例** 

```
#include <aws/external/gtest.h>

#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/logging/DefaultLogSystem.h>
#include <aws/core/utils/logging/AWSLogging.h>

#include <iostream>

int main(int argc, char** argv)
{
    Aws::Utils::Logging::InitializeAWSLogging(
        Aws::MakeShared<Aws::Utils::Logging::DefaultLogSystem>(
            "RunUnitTests", Aws::Utils::Logging::LogLevel::Trace, "aws_sdk_"));
    ::testing::InitGoogleTest(&argc, argv);
    int exitCode = RUN_ALL_TESTS();
    Aws::Utils::Logging::ShutdownAWSLogging();
    return exitCode;
}
```

 **用于自定义日志记录的 `Aws::Utils::Logging::DefaultLogSystem` 子类示例** 

 以下代码演示了如何继承 `Aws::Utils::Logging::DefaultLogSystem` 类，该类是适用于 C\$1\$1 的 AWS SDK 的一部分。此示例覆盖了 `ProcessFormattedStatement` 虚拟函数来自定义日志记录。

 `Aws::Utils::Logging::DefaultLogSystem` 是适用于 C\$1\$1 的 AWS SDK 中几个继承自 `Aws::Utils::Logging::LogSystemInterface` 的类之一，用于实现自定义日志记录。

```
class LogSystemOverride : public Aws::Utils::Logging::DefaultLogSystem {
public:
    explicit LogSystemOverride(Aws::Utils::Logging::LogLevel logLevel,
                               const Aws::String &logPrefix)
            : DefaultLogSystem(logLevel, logPrefix), mLogToStreamBuf(false) {}

    const Aws::Utils::Stream::SimpleStreamBuf &GetStreamBuf() const {
        return mStreamBuf;
    }

    void setLogToStreamBuf(bool logToStreamBuf) {
        mLogToStreamBuf = logToStreamBuf;
    }

protected:

    void ProcessFormattedStatement(Aws::String &&statement) override {
        if (mLogToStreamBuf) {
            std::lock_guard<std::mutex> lock(mStreamMutex);
            mStreamBuf.sputn(statement.c_str(), statement.length());
        }

        DefaultLogSystem::ProcessFormattedStatement(std::move(statement));
    }

private:
    Aws::Utils::Stream::SimpleStreamBuf mStreamBuf;
    // Use a mutex when writing to the buffer because
    // ProcessFormattedStatement can be called from multiple threads.
    std::mutex mStreamMutex;
    std::atomic<bool> mLogToStreamBuf;
};
```

```
int main(int argc, char **argv) {
    Aws::SDKOptions options;
    options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
    auto logSystemOverride = Aws::MakeShared<LogSystemOverride>("AllocationTag",
                                                                options.loggingOptions.logLevel,
                                                                options.loggingOptions.defaultLogPrefix);
    options.loggingOptions.logger_create_fn = [logSystemOverride]() {
        return logSystemOverride;
    };

    Aws::InitAPI(options);  // Call Aws::InitAPI only once in an application.
    {
        Aws::Client::ClientConfiguration clientConfig;
        // Optional: Set to the AWS Region (overrides config file).
        // clientConfig.region = "us-east-1";

        Aws::S3::S3Client s3Client(clientConfig);

        logSystemOverride->setLogToStreamBuf(true);
        auto outcome = s3Client.ListBuckets();
        if (!outcome.IsSuccess()) {
            std::cerr << "ListBuckets error: " <<
                      outcome.GetError().GetExceptionName() << " " <<
                      outcome.GetError().GetMessage() << std::endl;
        }

        logSystemOverride->setLogToStreamBuf(false);

        std::cout << "Log for ListBuckets" << std::endl;
        std::cout << logSystemOverride->GetStreamBuf().str() << std::endl;
    }

    Aws::ShutdownAPI(options);

    return 0;
}
```

请参阅 GitHub 上的[完整示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sdk-customization/override_default_logger.cpp)。