Skip to content

配置选项

本文档详细介绍 CFLogger 的所有配置选项。

日志级别配置

level 枚举

cpp
enum class level {
    TRACE,   // 最详细的输出
    DEBUG,   // 调试信息
    INFO,    // 一般信息
    WARNING, // 警告信息
    ERROR    // 错误信息
};
```text

### 设置最低级别

```cpp
// 简单 API
set_level(level::INFO);

// 高级 API
Logger::instance().setMininumLevel(level::INFO);
```text

### 级别关系

```text
TRACE (0) < DEBUG (1) < INFO (2) < WARNING (3) < ERROR (4)
```bash

设置某级别后,只有该级别及以上的日志会被记录:

| 设置级别 | TRACE | DEBUG | INFO | WARNING | ERROR |
|----------|-------|-------|------|---------|-------|
| TRACE    ||||||
| DEBUG    ||||||
| INFO     ||||||
| WARNING  ||||||
| ERROR    ||||||

### 环境相关配置

```cpp
void setup_logging_by_env() {
    const char* env = std::getenv("LOG_LEVEL");

    level lvl = level::INFO;  // 默认

    if (env) {
        std::string env_str(env);
        if (env_str == "TRACE") lvl = level::TRACE;
        else if (env_str == "DEBUG") lvl = level::DEBUG;
        else if (env_str == "INFO") lvl = level::INFO;
        else if (env_str == "WARNING") lvl = level::WARNING;
        else if (env_str == "ERROR") lvl = level::ERROR;
    }

    Logger::instance().setMininumLevel(lvl);
}
```text

## FormatterFlag 配置

### 标志详解

```cpp
enum FormatterFlag : uint32_t {
    NONE = 0,
    TIMESTAMP = 1 << 0,       // 时间戳
    LEVEL = 1 << 1,           // 日志级别
    TAG = 1 << 2,             // 标签
    THREAD_ID = 1 << 3,       // 线程 ID
    SOURCE_LOCATION = 1 << 4, // 源代码位置 (file:line)
    MESSAGE = 1 << 5,         // 消息内容
    COLOR = 1 << 6,           // ANSI 颜色
};
```text

### 预设组合

```cpp
MINIMAL = LEVEL | MESSAGE;
DEFAULT = TIMESTAMP | LEVEL | TAG | SOURCE_LOCATION | MESSAGE;
VERBOSE = TIMESTAMP | LEVEL | TAG | THREAD_ID | SOURCE_LOCATION | MESSAGE;
```bash

### 输出组件示例

| 标志 | 示例输出 |
|------|----------|
| TIMESTAMP | `[14:23:45]` |
| LEVEL | `[INFO]` |
| TAG | `[CFLog]` |
| THREAD_ID | `[12345]` |
| SOURCE_LOCATION | `main.cpp:42` |
| MESSAGE | `Hello World` |

### 运行时修改

```cpp
auto formatter = std::make_shared<AsciiColorFormatter>();
auto config = std::make_shared<FormatterConfig>();

// 单个操作
config->enable(FormatterFlag::THREAD_ID);
config->disable(FormatterFlag::SOURCE_LOCATION);

// 检查状态
if (config->is_enabled(FormatterFlag::COLOR)) {
    // 颜色已启用
}

// 批量设置
config->set_flags(FormatterFlag::MINIMAL);

formatter->set_config(config);
```text

### 位运算组合

```cpp
// 组合多个标志
auto flags = FormatterFlag::TIMESTAMP | FormatterFlag::LEVEL | FormatterFlag::MESSAGE;

// 移除某个标志
auto flags = FormatterFlag::DEFAULT & ~FormatterFlag::SOURCE_LOCATION;

// 添加某个标志
auto flags = FormatterFlag::MINIMAL | FormatterFlag::TIMESTAMP;
```text

## 时间戳格式配置

### strftime 格式

```cpp
auto config = std::make_shared<FormatterConfig>();
config->set_timestamp_format("%Y-%m-%d %H:%M:%S");
```bash

### 常用格式

| 格式字符串 | 输出示例 | 说明 |
|-----------|----------|------|
| `"%H:%M:%S"` | `14:23:45` | 时:分:秒(默认) |
| `"%Y-%m-%d %H:%M:%S"` | `2026-03-16 14:23:45` | 完整日期时间 |
| `"%m/%d %H:%M:%S"` | `03/16 14:23:45` |/日 时间 |
| `"%Y%m%d_%H%M%S"` | `20260316_142345` | 紧凑格式 |
| `"%T"` | `14:23:45` | ISO 8601 时间 |
| `"%F %T"` | `2026-03-16 14:23:45` | ISO 8601 日期时间 |

### strftime 说明符

| 说明符 | 说明 | 示例 |
|--------|------|------|
| `%Y` | 四位年份 | 2026 |
| `%m` | 月份(01-12| 03 |
| `%d` | 日期(01-31| 16 |
| `%H` | 小时(00-23| 14 |
| `%M` | 分钟(00-59| 23 |
| `%S` | 秒(00-60| 45 |
| `%F` | 等同于 %Y-%m-%d | 2026-03-16 |
| `%T` | 等同于 %H:%M:%S | 14:23:45 |

## 颜色配置

### ANSI 颜色代码

CFLogger 使用的颜色映射:

| 级别 | ANSI 代码 | 终端效果 |
|------|-----------|----------|
| TRACE | `\033[96m` | 青色 |
| DEBUG | `\033[94m` | 蓝色 |
| INFO | `\033[92m` | 绿色 |
| WARNING | `\033[93m` | 黄色 |
| ERROR | `\033[91m` | 红色 |

### 禁用颜色

```cpp
// 方法1:使用不带 COLOR 的标志
auto formatter = std::make_shared<AsciiColorFormatter>(
    FormatterFlag::DEFAULT  // 不包含 COLOR
);

// 方法2:运行时禁用
auto config = std::make_shared<FormatterConfig>();
config->disable(FormatterFlag::COLOR);
formatter->set_config(config);

// 方法3:使用 FileFormatter(自动忽略颜色)
auto formatter = std::make_shared<FileFormatter>();
```text

## 队列配置

### 队列容量

```cpp
// AsyncPostQueue 中的常量
static constexpr size_t kMaxNormalQueueSize = 65536;  // 2^16
```bash

这是编译时常量,运行时不可修改。

### 队列行为

| 队列类型 | 容量 | 满时行为 |
|----------|------|----------|
| normalQueue_ | 65,536 | 丢弃新日志 |
| errorQueue_ | 无限制 | 永不丢弃 |

### 监控队列溢出

```cpp
// 获取溢出计数
size_t overflow_count = Logger::instance().get_normal_queue_overflow();

// 定期检查
void monitor_queue() {
    static size_t last_count = 0;
    size_t current_count = Logger::instance().get_normal_queue_overflow();

    if (current_count > last_count) {
        std::cout << "警告: 队列溢出 "
                  << (current_count - last_count)
                  << " 条日志" << std::endl;
        last_count = current_count;
    }
}
```text

## 文件 Sink 配置

### OpenMode 选项

```cpp
enum class OpenMode {
    Append,   // 追加到文件末尾
    Truncate  // 覆盖现有文件
};
```text

### 使用示例

```cpp
// 追加模式(生产环境推荐)
auto sink = std::make_shared<FileSink>("app.log");

// 覆盖模式(测试环境)
auto sink = std::make_shared<FileSink>("app.log", OpenMode::Truncate);
```text

## 多环境配置

### 开发环境

```cpp
void setup_dev_environment() {
    using namespace cf::log;

    FormatterFactory factory;
    factory.register_formatter("dev", []() {
        return std::make_shared<AsciiColorFormatter>(
            FormatterFlag::VERBOSE | FormatterFlag::COLOR
        );
    });

    auto console = std::make_shared<ConsoleSink>();
    auto config = std::make_shared<FormatterConfig>();
    config->set_timestamp_format("%H:%M:%S.%ms");  // 毫秒精度

    auto formatter = factory.create("dev");
    formatter->set_config(config);
    console->setFormat(formatter);

    Logger::instance().clear_sinks();
    Logger::instance().add_sink(console);
    Logger::instance().setMininumLevel(level::TRACE);
}
```text

### 测试环境

```cpp
void setup_test_environment() {
    using namespace cf::log;

    FormatterFactory factory;
    factory.register_formatter("test", []() {
        return std::make_shared<AsciiColorFormatter>(
            FormatterFlag::DEFAULT | FormatterFlag::COLOR
        );
    });

    auto console = std::make_shared<ConsoleSink>();
    console->setFormat(factory.create("test"));

    Logger::instance().clear_sinks();
    Logger::instance().add_sink(console);
    Logger::instance().setMininumLevel(level::DEBUG);
}
```text

### 生产环境

```cpp
void setup_production_environment() {
    using namespace cf::log;

    FormatterFactory factory;
    factory.register_formatter("prod", []() {
        return std::make_shared<FileFormatter>(
            FormatterFlag::DEFAULT
        );
    });

    // 主日志文件
    auto main_log = std::make_shared<FileSink>(
        "/var/log/myapp/app.log",
        OpenMode::Append
    );
    main_log->setFormat(factory.create("prod"));

    // 错误日志文件
    auto error_log = std::make_shared<FileSink>(
        "/var/log/myapp/error.log",
        OpenMode::Append
    );
    error_log->setFormat(factory.create("prod"));

    auto config = std::make_shared<FormatterConfig>();
    config->set_timestamp_format("%Y-%m-%d %H:%M:%S");
    main_log->getFormat()->set_config(config);
    error_log->getFormat()->set_config(config);

    Logger::instance().clear_sinks();
    Logger::instance().add_sink(main_log);
    Logger::instance().add_sink(error_log);
    Logger::instance().setMininumLevel(level::INFO);
}
```text

## 配置文件示例

### JSON 配置

```json
{
    "logging": {
        "level": "INFO",
        "sinks": [
            {
                "type": "console",
                "formatter": {
                    "type": "ascii_color",
                    "flags": "DEFAULT",
                    "color": true,
                    "timestamp_format": "%H:%M:%S"
                }
            },
            {
                "type": "file",
                "path": "app.log",
                "mode": "append",
                "formatter": {
                    "type": "file",
                    "flags": "DEFAULT",
                    "timestamp_format": "%Y-%m-%d %H:%M:%S"
                }
            }
        ]
    }
}
```text

### 命令行参数

```cpp
#include <getopt.h>

void parse_command_line_args(int argc, char** argv) {
    using namespace cf::log;

    level log_level = level::INFO;
    bool enable_file = false;
    std::string log_path = "app.log";

    static struct option long_options[] = {
        {"log-level", required_argument, 0, 'l'},
        {"log-file", required_argument, 0, 'f'},
        {"enable-file", no_argument, 0, 'e'},
        {0, 0, 0, 0}
    };

    int opt;
    while ((opt = getopt_long(argc, argv, "l:f:e", long_options, NULL)) != -1) {
        switch (opt) {
            case 'l':
                if (strcmp(optarg, "TRACE") == 0) log_level = level::TRACE;
                else if (strcmp(optarg, "DEBUG") == 0) log_level = level::DEBUG;
                else if (strcmp(optarg, "INFO") == 0) log_level = level::INFO;
                else if (strcmp(optarg, "WARNING") == 0) log_level = level::WARNING;
                else if (strcmp(optarg, "ERROR") == 0) log_level = level::ERROR;
                break;
            case 'f':
                log_path = optarg;
                enable_file = true;
                break;
            case 'e':
                enable_file = true;
                break;
        }
    }

    Logger::instance().setMininumLevel(log_level);

    if (enable_file) {
        auto file_sink = std::make_shared<FileSink>(log_path);
        file_sink->setFormat(std::make_shared<FileFormatter>());
        Logger::instance().add_sink(file_sink);
    }
}
```text

## 配置最佳实践

1. **环境区分**:开发、测试、生产使用不同配置
2. **级别控制**:生产环境不低于 INFO
3. **文件分离**:普通日志和错误日志分开
4. **格式一致**:同类日志使用统一格式
5. **性能平衡**:生产环境避免过于详细的格式

## 下一步

- 阅读 [最佳实践](./best_practices.md)
- 学习 [性能优化](./performance.md)

## 相关文档

- [格式化器详解](./formatters.md)
- [Sink 详解](./sinks.md)
- [最佳实践](./best_practices.md)

Built with VitePress