guochao e14bcb205b
All checks were successful
build container / build-container (push) Successful in 6m4s
run go test / test (push) Successful in 3m23s
rename handlerlog to handlerctx
2025-03-03 09:59:19 +08:00

143 lines
3.2 KiB
Go

package main
import (
"flag"
"log/slog"
"net/http"
"net/http/pprof"
"os"
"path/filepath"
"time"
cacheproxy "git.jeffthecoder.xyz/guochao/cache-proxy"
"git.jeffthecoder.xyz/guochao/cache-proxy/pkgs/middleware"
"git.jeffthecoder.xyz/guochao/cache-proxy/pkgs/middleware/handlerctx"
"git.jeffthecoder.xyz/guochao/cache-proxy/pkgs/middleware/httplog"
"git.jeffthecoder.xyz/guochao/cache-proxy/pkgs/middleware/recover"
"github.com/getsentry/sentry-go"
"gopkg.in/yaml.v3"
)
var (
configFilePath = "config.yaml"
logLevel = "info"
sentrydsn = ""
pprofEnabled = false
)
func init() {
if v, ok := os.LookupEnv("CONFIG_PATH"); ok {
configFilePath = v
}
if v, ok := os.LookupEnv("LOG_LEVEL"); ok {
logLevel = v
}
flag.StringVar(&configFilePath, "config", configFilePath, "path to config file")
flag.StringVar(&logLevel, "log-level", logLevel, "log level. (trace, debug, info, warn, error)")
}
func configFromFile(path string) (*cacheproxy.Config, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
config := &cacheproxy.Config{
Upstreams: []cacheproxy.Upstream{
{
Server: "https://mirrors.ustc.edu.cn",
},
},
Storage: cacheproxy.Storage{
Type: "local",
Local: &cacheproxy.LocalStorage{
Path: "./data",
TemporaryFilePattern: "temp.*",
Accel: cacheproxy.Accel{
RespondWithHeaders: []string{"X-Sendfile", "X-Accel-Redirect"},
},
},
},
Misc: cacheproxy.MiscConfig{
FirstChunkBytes: 1024 * 1024 * 50,
ChunkBytes: 1024 * 1024,
},
Cache: cacheproxy.Cache{
RefreshAfter: time.Hour,
},
}
if err := yaml.NewDecoder(file).Decode(&config); err != nil {
return nil, err
}
if config.Storage.Local != nil {
localPath, err := filepath.Abs(config.Storage.Local.Path)
if err != nil {
return nil, err
}
config.Storage.Local.Path = localPath
}
return config, nil
}
func main() {
flag.Parse()
lvl := slog.LevelInfo
if err := lvl.UnmarshalText([]byte(logLevel)); err != nil {
slog.With("error", err).Error("failed to parse log level")
os.Exit(-1)
} else {
slog.SetLogLoggerLevel(lvl)
}
if sentrydsn != "" {
if err := sentry.Init(sentry.ClientOptions{
Dsn: sentrydsn,
}); err != nil {
slog.With("dsn", sentrydsn, "error", err).Error("failed to setup sentry")
os.Exit(-1)
}
defer sentry.Flush(time.Second * 3)
}
config, err := configFromFile(configFilePath)
if err != nil {
panic(err)
}
ch := make(chan any, 10)
for idx := 0; idx < 10; idx += 1 {
ch <- idx
}
server := cacheproxy.NewServer(*config)
mux := http.NewServeMux()
mux.HandleFunc("GET /", server.HandleRequestWithCache)
if pprofEnabled {
mux.HandleFunc("GET /debug/pprof/", pprof.Index)
mux.HandleFunc("GET /debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("GET /debug/pprof/profile", pprof.Profile)
mux.HandleFunc("GET /debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("GET /debug/pprof/trace", pprof.Trace)
}
slog.With("addr", ":8881").Info("serving app")
if err := http.ListenAndServe(":8881", middleware.Use(mux,
recover.Recover(),
handlerctx.FindHandler(mux),
httplog.Log(httplog.Config{LogStart: true, LogFinish: true}),
)); err != nil {
slog.With("error", err).Error("failed to start server")
os.Exit(-1)
}
}