Browse Source

Register pprof as a plugin

sunshineplan 1 year ago
parent
commit
44a28de6f8
5 changed files with 122 additions and 171 deletions
  1. 83 0
      main/commands/run.go
  2. 0 78
      main/commands/run_default.go
  3. 0 93
      main/commands/run_pprof.go
  4. 11 0
      main/plugins/plugin.go
  5. 28 0
      main/plugins/plugin_pprof.go

+ 83 - 0
main/commands/run.go

@@ -4,15 +4,59 @@ import (
 	"fmt"
 	"log"
 	"os"
+	"os/signal"
 	"path/filepath"
+	"runtime"
 	"strings"
+	"syscall"
 
 	core "github.com/v2fly/v2ray-core/v5"
 	"github.com/v2fly/v2ray-core/v5/common/cmdarg"
 	"github.com/v2fly/v2ray-core/v5/common/platform"
 	"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 (
 	configFiles          cmdarg.Arg
 	configDirs           cmdarg.Arg
@@ -30,6 +74,45 @@ func setConfigFlags(cmd *base.Command) {
 	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 {
 	info, err := os.Stat(file)
 	return err == nil && !info.IsDir()

+ 0 - 78
main/commands/run_default.go

@@ -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
-	}
-}

+ 0 - 93
main/commands/run_pprof.go

@@ -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 - 0
main/plugins/plugin.go

@@ -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)
+}

+ 28 - 0
main/plugins/plugin_pprof.go

@@ -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)
+}