Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion .gitignore

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request 概述

这个 PR 主要进行了以下优化:

  1. 配置管理系统优化

    • 支持 config.local.yaml 本地配置文件,方便开发环境配置。
    • 建立了配置优先级:环境变量 > 配置文件 > 默认值。
    • 添加了完整的默认配置,确保零配置启动。
    • 新增 machine_id_file 配置项,支持自定义机器ID文件路径。
  2. 数据上报机制优化

    • 分离了机器ID生成和数据上报逻辑。
    • 支持配置化的机器ID文件路径。
    • 实现了优雅降级:无上报密钥时跳过上报但保留机器ID生成。
    • 代码重构,提取 ensureMachineID() 方法,提高了可维护性。
  3. 项目管理规范化

    • 完善了 .gitignore,增加了对 IDE、系统临时文件、日志和运行时文件的忽略规则。

文件变更说明

  • .gitignore: 增加了 IDE、系统临时文件、日志和运行时文件的忽略规则。
  • backend/config/config.go: 添加了 machine_id_file 配置项,支持读取本地配置文件,并设置了默认值。
  • backend/config/config.local.yaml: 新增本地开发配置文件示例。
  • backend/pkg/report/report.go: 优化了数据上报和机器ID生成逻辑,实现了配置化路径和优雅降级。

这些变更提升了开发体验、配置灵活性和系统的健壮性。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request 概述

该 PR 实现了配置管理系统和数据上报机制的优化,旨在提高本地开发体验和系统的可配置性。

主要变更内容:

  1. 配置系统优化 (backend/config/config.go):

    • 支持 config.local.yaml 本地配置文件,方便开发环境配置。
    • 建立了环境变量 > 配置文件 > 默认值的配置优先级体系。
    • 增加了完整的默认配置,确保程序在无配置时也能启动。
    • 新增 machine_id_file 配置项以支持自定义机器ID文件路径。
  2. 数据上报机制优化 (backend/pkg/report/report.go):

    • 分离了机器ID生成与数据上报逻辑。
    • 支持从配置中读取机器ID文件路径,默认路径为 /app/static/.machine_id
    • 实现了优雅降级:当无上报密钥时跳过上报但保留机器ID生成功能。
    • 提取了 ensureMachineID() 方法,提高了代码的可维护性。
  3. 项目管理规范化 (.gitignore):

    • 增加了完整的忽略规则,包括支持主流IDE(如 IntelliJ IDEA、VS Code)的忽略规则。
    • 忽略了系统临时文件、日志文件和运行时文件,规范了项目文件管理。

文件变更说明

  • backend/config/config.go:增加了对本地配置文件的支持,设置了配置优先级和默认值,并添加了机器ID文件路径配置项。
  • backend/config/config.local.yaml:新增了本地开发配置文件,提供了一套完整的本地开发环境配置示例。
  • backend/pkg/report/report.go:重构了数据上报逻辑,实现了配置化机器ID路径、优雅降级和机器ID生成功能的分离。
  • .gitignore:完善了忽略规则,增强了项目的规范性。

Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
backend/assets
backend/docs/swagger.json
backend/assets-amd64
backend/assets-amd64

# 本地开发配置文件,不提交到代码库
#backend/config/config.local.yaml

# IDE - IntelliJ IDEA
.idea/
*.iml
*.ipr
*.iws
out/

# IDE - VS Code
.vscode/
*.code-workspace

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Temporary folders
tmp/
temp/
18 changes: 17 additions & 1 deletion backend/config/config.go

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

添加本地配置文件支持是一个很好的改进。建议考虑以下几点:

  1. config.go 中添加关于 config.local.yaml 使用方法的注释,帮助开发者了解其用途和使用方式。
  2. 考虑增加一个示例配置文件(如 config.local.yaml.example),并将其添加到版本控制中,供开发者参考。

这将进一步提升开发体验和项目的可维护性。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

将机器ID文件路径配置化是一个很好的改进,提升了系统的灵活性。建议在配置结构体中为 MachineIDFile 字段添加注释,说明其用途和默认值,以便其他开发者更好地理解和使用这个配置项。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

添加默认机器ID文件路径是必要的。建议将默认路径 /app/static/.machine_id 定义为一个常量,以提高代码的可读性和可维护性。

例如:

const defaultMachineIDFile = "/app/static/.machine_id"

// 在设置默认值时使用
v.SetDefault("data_report.machine_id_file", defaultMachineIDFile)

Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ type Config struct {
} `mapstructure:"extension"`

DataReport struct {
Key string `mapstructure:"key"`
Key string `mapstructure:"key"`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议为MachineIDFile字段添加注释,说明其用途和默认值,以提高代码可读性。

Suggested change
Key string `mapstructure:"key"`
// MachineIDFile 指定存储机器ID的文件路径,默认为"/app/static/.machine_id"
MachineIDFile string `mapstructure:"machine_id_file"`

MachineIDFile string `mapstructure:"machine_id_file"`
} `mapstructure:"data_report"`

Security struct {
Expand Down Expand Up @@ -121,6 +122,20 @@ func Init() (*Config, error) {
v.SetEnvPrefix("MONKEYCODE")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

// 可选的配置文件读取(保持向后兼容)
// 优先级:环境变量 > 配置文件 > 默认值
v.SetConfigType("yaml")
v.AddConfigPath("./config")
v.AddConfigPath(".")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 可选的配置文件读取(保持向后兼容)
// 优先级:环境变量 > 配置文件 > 默认值
v.SetConfigType("yaml")
v.AddConfigPath("./config")
v.AddConfigPath(".")

// 尝试读取本地开发配置(仅用于开发环境便利性)
v.SetConfigName("config.local")
if err := v.ReadInConfig(); err != nil {
    // 本地配置不存在是正常的,不需要报错
    // 线上部署完全依赖环境变量,这样保持向后兼容
}

// 设置默认值,确保在没有配置文件时程序能启动(云上部署场景)

这段代码实现了配置优先级机制,很好地平衡了开发便利性和生产环境的稳定性。建议添加日志记录,当读取本地配置文件成功时输出一条调试日志,方便开发者确认配置是否生效。

// 尝试读取本地开发配置(仅用于开发环境便利性)
v.SetConfigName("config.local")
if err := v.ReadInConfig(); err != nil {
// 本地配置不存在是正常的,不需要报错
// 线上部署完全依赖环境变量,这样保持向后兼容
}

// 设置默认值,确保在没有配置文件时程序能启动(云上部署场景)
v.SetDefault("debug", false)
v.SetDefault("read_only", false)
v.SetDefault("logger.level", "info")
Expand Down Expand Up @@ -152,6 +167,7 @@ func Init() (*Config, error) {
v.SetDefault("extension.limit", 1)
v.SetDefault("extension.limit_second", 10)
v.SetDefault("data_report.key", "")
v.SetDefault("data_report.machine_id_file", "static/.machine_id")
v.SetDefault("security.queue_limit", 5)
v.SetDefault("embedding.model_name", "qwen3-embedding-0.6b")
v.SetDefault("embedding.api_endpoint", "https://aiapi.chaitin.net/v1/embeddings")
Expand Down
62 changes: 62 additions & 0 deletions backend/config/config.local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# 本地开发配置文件 - 纯YAML格式(非模版)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议在文件头部添加版权信息或项目相关信息,以符合项目规范。

Suggested change
# 本地开发配置文件 - 纯YAML格式(非模版)
# Copyright (c) 2025 Chaitin Tech. All rights reserved.
# 本地开发配置文件 - 纯YAML格式(非模版)


base_url: http://localhost:8080

# 启用调试模式
debug: true

logger:
level: debug

server:
addr: :8080
port: ""

admin:
user: admin
password: admin123

database:
master: postgres://monkeycode:123456@localhost:5432/monkeycode?sslmode=disable&timezone=Asia/Shanghai
slave: postgres://monkeycode:123456@localhost:5432/monkeycode?sslmode=disable&timezone=Asia/Shanghai
max_open_conns: 25
max_idle_conns: 5

redis:
host: localhost
port: "6379"
pass: ""
db: 0
idle_conn: 5

llm_proxy:
timeout: 30s
keep_alive: 1m
client_pool_size: 5
request_log_path: ./logs

vscode:
vsix_file: ./static/monkeycode.vsix

# 关闭数据上报
data_report:
key: ""
machine_id_file: "./static/.machine_id"

init_model:
model_name: ""
model_key: ""
model_url: ""

extension:
baseurl: "https://release.baizhi.cloud"
limit: 1
limit_second: 10

security:
queue_limit: 5

embedding:
model_name: "qwen3-embedding-0.6b"
api_endpoint: "https://aiapi.chaitin.net/v1/embeddings"
api_key: ""
40 changes: 33 additions & 7 deletions backend/pkg/report/report.go

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

分离机器ID生成和数据上报逻辑是很好的重构。建议为 ensureMachineID 方法添加注释,说明其功能和使用场景,以便其他开发者更好地理解和使用这个方法。

Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ func NewReport(logger *slog.Logger, cfg *config.Config, version *version.Version
u, _ := url.Parse(raw)
client := request.NewClient(u.Scheme, u.Host, 30*time.Second)

// 从配置文件读取机器ID文件路径
idFilePath := cfg.DataReport.MachineIDFile
if idFilePath == "" {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 从配置文件读取机器ID文件路径
idFilePath := cfg.DataReport.MachineIDFile
if idFilePath == "" {
    idFilePath = "/app/static/.machine_id"
}

这部分代码实现了机器ID文件路径的可配置化,提升了系统的灵活性。建议将默认路径 /app/static/.machine_id 定义为常量,便于维护和修改。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议将默认路径定义为常量,以提高代码的可维护性。

Suggested change
if idFilePath == "" {
const defaultMachineIDFile = "/app/static/.machine_id"
// ...
idFilePath := cfg.DataReport.MachineIDFile
if idFilePath == "" {
idFilePath = defaultMachineIDFile
}

idFilePath = "/app/static/.machine_id"
}
r := &Reporter{
client: client,
logger: logger.With("module", "reporter"),
IDFile: "/app/static/.machine_id",
IDFile: idFilePath,
cfg: cfg,
version: version,
}
Expand Down Expand Up @@ -82,17 +87,42 @@ func (r *Reporter) GetMachineID() string {
}

func (r *Reporter) ReportInstallation() error {
// 先确保机器ID存在(无论是否上报数据)
if err := r.ensureMachineID(); err != nil {
return err
}

// 如果密钥为空,跳过数据上报,但机器ID已经生成
if r.cfg.DataReport.Key == "" {
r.logger.Info("data report disabled (empty key), but machine ID is ready")
return nil
}

// 执行数据上报
return r.Report("monkeycode-installation", InstallData{
MachineID: r.machineID,
Version: r.version.Version(),
Timestamp: time.Now().Format(time.RFC3339),
Type: "installation",
})
}

// ensureMachineID 确保机器ID存在,如果不存在则生成并保存
func (r *Reporter) ensureMachineID() error {
// 如果已经有机器ID,直接返回
if r.machineID != "" {
return nil
}

// 生成新的机器ID
id, err := machine.GenerateMachineID()
if err != nil {
r.logger.With("error", err).Warn("generate machine id failed")
return err
}
r.machineID = id

// 保存到文件
f, err := os.Create(r.IDFile)
if err != nil {
r.logger.With("error", err).Warn("create machine id file failed")
Expand All @@ -106,10 +136,6 @@ func (r *Reporter) ReportInstallation() error {
return err
}

return r.Report("monkeycode-installation", InstallData{
MachineID: id,
Version: r.version.Version(),
Timestamp: time.Now().Format(time.RFC3339),
Type: "installation",
})
r.logger.Info("machine id generated and saved", "file", r.IDFile)
return nil
}