mirror of
https://github.com/sky22333/qqbot.git
synced 2026-05-11 18:11:33 +08:00
202 lines
5.4 KiB
Go
202 lines
5.4 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
type Config struct {
|
|
App AppConfig `toml:"app"`
|
|
QQBot QQBotConfig `toml:"qqbot"`
|
|
Server ServerConfig `toml:"server"`
|
|
Dispatch DispatchConfig `toml:"dispatch"`
|
|
Runtime RuntimeConfig `toml:"runtime"`
|
|
Collector CollectorConfig `toml:"collector"`
|
|
Targets TargetsConfig `toml:"targets"`
|
|
}
|
|
|
|
type AppConfig struct {
|
|
LogLevel string `toml:"log_level"`
|
|
}
|
|
|
|
type QQBotConfig struct {
|
|
AppID string `toml:"app_id"`
|
|
ClientSecret string `toml:"client_secret"`
|
|
TokenURL string `toml:"token_url"`
|
|
APIBase string `toml:"api_base"`
|
|
RequestTimout string `toml:"request_timeout"`
|
|
Markdown bool `toml:"markdown"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
ListenAddr string `toml:"listen_addr"`
|
|
APIToken string `toml:"api_token"`
|
|
ReadTimeout string `toml:"read_timeout"`
|
|
WriteTimeout string `toml:"write_timeout"`
|
|
ShutdownTimeout string `toml:"shutdown_timeout"`
|
|
MaxBodyBytes int64 `toml:"max_body_bytes"`
|
|
}
|
|
|
|
type DispatchConfig struct {
|
|
QueueSize int `toml:"queue_size"`
|
|
Workers int `toml:"workers"`
|
|
RetryMax int `toml:"retry_max"`
|
|
RetryBackoffMS int `toml:"retry_backoff_ms"`
|
|
EnqueueTimeout string `toml:"enqueue_timeout"`
|
|
}
|
|
|
|
type RuntimeConfig struct {
|
|
StatusTTLSeconds int `toml:"status_ttl_seconds"`
|
|
IdempotencyTTLSeconds int `toml:"idempotency_ttl_seconds"`
|
|
CleanupIntervalSec int `toml:"cleanup_interval_seconds"`
|
|
}
|
|
|
|
type CollectorConfig struct {
|
|
ReconnectDelay string `toml:"reconnect_delay"`
|
|
}
|
|
|
|
type TargetsConfig struct {
|
|
FilePath string `toml:"file_path"`
|
|
MaxRecords int `toml:"max_records"`
|
|
FlushInterval string `toml:"flush_interval"`
|
|
}
|
|
|
|
func Default() Config {
|
|
return Config{
|
|
App: AppConfig{
|
|
LogLevel: "info",
|
|
},
|
|
QQBot: QQBotConfig{
|
|
TokenURL: "https://bots.qq.com/app/getAppAccessToken",
|
|
APIBase: "https://api.sgroup.qq.com",
|
|
RequestTimout: "10s",
|
|
Markdown: false,
|
|
},
|
|
Server: ServerConfig{
|
|
ListenAddr: ":8080",
|
|
ReadTimeout: "10s",
|
|
WriteTimeout: "15s",
|
|
ShutdownTimeout: "10s",
|
|
MaxBodyBytes: 1 << 20,
|
|
},
|
|
Dispatch: DispatchConfig{
|
|
QueueSize: 2048,
|
|
Workers: 8,
|
|
RetryMax: 3,
|
|
RetryBackoffMS: 200,
|
|
EnqueueTimeout: "3s",
|
|
},
|
|
Runtime: RuntimeConfig{
|
|
StatusTTLSeconds: 86400,
|
|
IdempotencyTTLSeconds: 3600,
|
|
CleanupIntervalSec: 60,
|
|
},
|
|
Collector: CollectorConfig{
|
|
ReconnectDelay: "3s",
|
|
},
|
|
Targets: TargetsConfig{
|
|
FilePath: "data/targets.json",
|
|
MaxRecords: 1000,
|
|
FlushInterval: "2s",
|
|
},
|
|
}
|
|
}
|
|
|
|
func Load(path string) (Config, error) {
|
|
cfg := Default()
|
|
if _, err := toml.DecodeFile(path, &cfg); err != nil {
|
|
return Config{}, err
|
|
}
|
|
if err := cfg.Validate(); err != nil {
|
|
return Config{}, err
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func (c Config) Validate() error {
|
|
if strings.TrimSpace(c.QQBot.AppID) == "" {
|
|
return errors.New("qqbot.app_id 不能为空")
|
|
}
|
|
if strings.TrimSpace(c.QQBot.ClientSecret) == "" {
|
|
return errors.New("qqbot.client_secret 不能为空")
|
|
}
|
|
if strings.TrimSpace(c.Server.ListenAddr) == "" {
|
|
return errors.New("server.listen_addr 不能为空")
|
|
}
|
|
if c.Dispatch.QueueSize <= 0 {
|
|
return errors.New("dispatch.queue_size 必须大于 0")
|
|
}
|
|
if c.Dispatch.Workers <= 0 {
|
|
return errors.New("dispatch.workers 必须大于 0")
|
|
}
|
|
if c.Dispatch.RetryMax < 0 {
|
|
return errors.New("dispatch.retry_max 不能小于 0")
|
|
}
|
|
if c.Dispatch.RetryBackoffMS <= 0 {
|
|
return errors.New("dispatch.retry_backoff_ms 必须大于 0")
|
|
}
|
|
if c.Server.MaxBodyBytes <= 0 {
|
|
return errors.New("server.max_body_bytes 必须大于 0")
|
|
}
|
|
if _, err := c.RequestTimeout(); err != nil {
|
|
return fmt.Errorf("qqbot.request_timeout 无效: %w", err)
|
|
}
|
|
if _, err := c.ReadTimeout(); err != nil {
|
|
return fmt.Errorf("server.read_timeout 无效: %w", err)
|
|
}
|
|
if _, err := c.WriteTimeout(); err != nil {
|
|
return fmt.Errorf("server.write_timeout 无效: %w", err)
|
|
}
|
|
if _, err := c.ShutdownTimeout(); err != nil {
|
|
return fmt.Errorf("server.shutdown_timeout 无效: %w", err)
|
|
}
|
|
if _, err := c.EnqueueTimeout(); err != nil {
|
|
return fmt.Errorf("dispatch.enqueue_timeout 无效: %w", err)
|
|
}
|
|
if _, err := c.CollectorReconnectDelay(); err != nil {
|
|
return fmt.Errorf("collector.reconnect_delay 无效: %w", err)
|
|
}
|
|
if strings.TrimSpace(c.Targets.FilePath) == "" {
|
|
return errors.New("targets.file_path 不能为空")
|
|
}
|
|
if c.Targets.MaxRecords <= 0 {
|
|
return errors.New("targets.max_records 必须大于 0")
|
|
}
|
|
if _, err := c.TargetsFlushInterval(); err != nil {
|
|
return fmt.Errorf("targets.flush_interval 无效: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c Config) RequestTimeout() (time.Duration, error) {
|
|
return time.ParseDuration(c.QQBot.RequestTimout)
|
|
}
|
|
|
|
func (c Config) ReadTimeout() (time.Duration, error) {
|
|
return time.ParseDuration(c.Server.ReadTimeout)
|
|
}
|
|
|
|
func (c Config) WriteTimeout() (time.Duration, error) {
|
|
return time.ParseDuration(c.Server.WriteTimeout)
|
|
}
|
|
|
|
func (c Config) ShutdownTimeout() (time.Duration, error) {
|
|
return time.ParseDuration(c.Server.ShutdownTimeout)
|
|
}
|
|
|
|
func (c Config) EnqueueTimeout() (time.Duration, error) {
|
|
return time.ParseDuration(c.Dispatch.EnqueueTimeout)
|
|
}
|
|
|
|
func (c Config) CollectorReconnectDelay() (time.Duration, error) {
|
|
return time.ParseDuration(c.Collector.ReconnectDelay)
|
|
}
|
|
|
|
func (c Config) TargetsFlushInterval() (time.Duration, error) {
|
|
return time.ParseDuration(c.Targets.FlushInterval)
|
|
}
|