1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-09 19:58:45 -05:00

Register pprof as a plugin

This commit is contained in:
sunshineplan 2024-08-22 10:50:05 +08:00 committed by Xiaokang Wang (Shelikhoo)
parent 0809cdedfe
commit 44a28de6f8
5 changed files with 122 additions and 171 deletions

View File

@ -4,15 +4,59 @@ import (
"fmt" "fmt"
"log" "log"
"os" "os"
"os/signal"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"syscall"
core "github.com/v2fly/v2ray-core/v5" core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/common/cmdarg" "github.com/v2fly/v2ray-core/v5/common/cmdarg"
"github.com/v2fly/v2ray-core/v5/common/platform" "github.com/v2fly/v2ray-core/v5/common/platform"
"github.com/v2fly/v2ray-core/v5/main/commands/base" "github.com/v2fly/v2ray-core/v5/main/commands/base"
"github.com/v2fly/v2ray-core/v5/main/plugins"
) )
// CmdRun runs V2Ray with config
var CmdRun = &base.Command{
CustomFlags: true,
UsageLine: "{{.Exec}} run [-c config.json] [-d dir]",
Short: "run V2Ray with config",
Long: `
Run V2Ray with config.
{{.Exec}} will also use the config directory specified by environment
variable "v2ray.location.confdir". If no config found, it tries
to load config from one of below:
1. The default "config.json" in the current directory
2. The config file from ENV "v2ray.location.config"
3. The stdin if all failed above
Arguments:
-c, -config <file>
Config file for V2Ray. Multiple assign is accepted.
-d, -confdir <dir>
A directory with config files. Multiple assign is accepted.
-r
Load confdir recursively.
-format <format>
Format of config input. (default "auto")
Examples:
{{.Exec}} {{.LongName}} -c config.json
{{.Exec}} {{.LongName}} -d path/to/dir
Use "{{.Exec}} help format-loader" for more information about format.
`,
Run: executeRun,
}
var ( var (
configFiles cmdarg.Arg configFiles cmdarg.Arg
configDirs cmdarg.Arg configDirs cmdarg.Arg
@ -30,6 +74,45 @@ func setConfigFlags(cmd *base.Command) {
cmd.Flag.Var(&configDirs, "d", "") cmd.Flag.Var(&configDirs, "d", "")
} }
func executeRun(cmd *base.Command, args []string) {
setConfigFlags(cmd)
var pluginFuncs []func() error
for _, plugin := range plugins.Plugins {
if f := plugin(cmd); f != nil {
pluginFuncs = append(pluginFuncs, f)
}
}
cmd.Flag.Parse(args)
printVersion()
configFiles = getConfigFilePath()
server, err := startV2Ray()
if err != nil {
base.Fatalf("Failed to start: %s", err)
}
for _, f := range pluginFuncs {
go func(f func() error) {
if err := f(); err != nil {
log.Print(err)
}
}(f)
}
if err := server.Start(); err != nil {
base.Fatalf("Failed to start: %s", err)
}
defer server.Close()
// Explicitly triggering GC to remove garbage from config loading.
runtime.GC()
{
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, syscall.SIGTERM)
<-osSignals
}
}
func fileExists(file string) bool { func fileExists(file string) bool {
info, err := os.Stat(file) info, err := os.Stat(file)
return err == nil && !info.IsDir() return err == nil && !info.IsDir()

View File

@ -1,78 +0,0 @@
//go:build !pprof
// +build !pprof
package commands
import (
"os"
"os/signal"
"runtime"
"syscall"
"github.com/v2fly/v2ray-core/v5/main/commands/base"
)
// CmdRun runs V2Ray with config
var CmdRun = &base.Command{
CustomFlags: true,
UsageLine: "{{.Exec}} run [-c config.json] [-d dir]",
Short: "run V2Ray with config",
Long: `
Run V2Ray with config.
{{.Exec}} will also use the config directory specified by environment
variable "v2ray.location.confdir". If no config found, it tries
to load config from one of below:
1. The default "config.json" in the current directory
2. The config file from ENV "v2ray.location.config"
3. The stdin if all failed above
Arguments:
-c, -config <file>
Config file for V2Ray. Multiple assign is accepted.
-d, -confdir <dir>
A directory with config files. Multiple assign is accepted.
-r
Load confdir recursively.
-format <format>
Format of config input. (default "auto")
Examples:
{{.Exec}} {{.LongName}} -c config.json
{{.Exec}} {{.LongName}} -d path/to/dir
Use "{{.Exec}} help format-loader" for more information about format.
`,
Run: executeRun,
}
func executeRun(cmd *base.Command, args []string) {
setConfigFlags(cmd)
cmd.Flag.Parse(args)
printVersion()
configFiles = getConfigFilePath()
server, err := startV2Ray()
if err != nil {
base.Fatalf("Failed to start: %s", err)
}
if err := server.Start(); err != nil {
base.Fatalf("Failed to start: %s", err)
}
defer server.Close()
// Explicitly triggering GC to remove garbage from config loading.
runtime.GC()
{
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, syscall.SIGTERM)
<-osSignals
}
}

View File

@ -1,93 +0,0 @@
//go:build pprof
// +build pprof
package commands
import (
"log"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"runtime"
"syscall"
"github.com/v2fly/v2ray-core/v5/main/commands/base"
)
// CmdRun runs V2Ray with config
var CmdRun = &base.Command{
CustomFlags: true,
UsageLine: "{{.Exec}} run [-c config.json] [-d dir] [-pprof port]",
Short: "run V2Ray with config",
Long: `
Run V2Ray with config.
{{.Exec}} will also use the config directory specified by environment
variable "v2ray.location.confdir". If no config found, it tries
to load config from one of below:
1. The default "config.json" in the current directory
2. The config file from ENV "v2ray.location.config"
3. The stdin if all failed above
Arguments:
-c, -config <file>
Config file for V2Ray. Multiple assign is accepted.
-d, -confdir <dir>
A directory with config files. Multiple assign is accepted.
-r
Load confdir recursively.
-format <format>
Format of config input. (default "auto")
-pprof <port>
HTTP server port for pprof debugging. (default "8080")
Examples:
{{.Exec}} {{.LongName}} -c config.json
{{.Exec}} {{.LongName}} -d path/to/dir
Use "{{.Exec}} help format-loader" for more information about format.
`,
Run: executeRun,
}
func executeRun(cmd *base.Command, args []string) {
setConfigFlags(cmd)
pprof := cmd.Flag.String("pprof", ":8080", "")
cmd.Flag.Parse(args)
printVersion()
configFiles = getConfigFilePath()
server, err := startV2Ray()
if err != nil {
base.Fatalf("Failed to start: %s", err)
}
if addr := *pprof; addr != "" {
go func() {
if err := http.ListenAndServe(addr, nil); err != nil {
log.Print(err)
}
}()
}
if err := server.Start(); err != nil {
base.Fatalf("Failed to start: %s", err)
}
defer server.Close()
// Explicitly triggering GC to remove garbage from config loading.
runtime.GC()
{
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, syscall.SIGTERM)
<-osSignals
}
}

11
main/plugins/plugin.go Normal file
View File

@ -0,0 +1,11 @@
package plugins
import "github.com/v2fly/v2ray-core/v5/main/commands/base"
var Plugins []Plugin
type Plugin func(*base.Command) func() error
func RegisterPlugin(plugin Plugin) {
Plugins = append(Plugins, plugin)
}

View File

@ -0,0 +1,28 @@
package plugins
import (
"net/http"
"net/http/pprof"
"github.com/v2fly/v2ray-core/v5/main/commands/base"
)
var pprofPlugin Plugin = func(cmd *base.Command) func() error {
addr := cmd.Flag.String("pprof", "", "")
return func() error {
if *addr != "" {
h := http.NewServeMux()
h.HandleFunc("/debug/pprof/", pprof.Index)
h.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
h.HandleFunc("/debug/pprof/profile", pprof.Profile)
h.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
h.HandleFunc("/debug/pprof/trace", pprof.Trace)
return (&http.Server{Addr: *addr, Handler: h}).ListenAndServe()
}
return nil
}
}
func init() {
RegisterPlugin(pprofPlugin)
}