Pull request 1947: AG-24320 home: pprof conf
Squashed commit of the following:
commit bc0facffe41e140fab00edeeeca3b69306cf2ceb
Merge: 71e0806ba c0691cab6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Wed Aug 2 17:34:15 2023 +0300
Merge branch 'master' into pprof-conf
commit 71e0806bac52412cae7cad2748216ece7fbed36f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date: Wed Aug 2 08:37:51 2023 +0300
all: docs
commit 6ebb6f9a5f4dbeb753dd470879f2e5ff556ee5f1
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date: Tue Aug 1 15:56:45 2023 +0300
home: imp code
commit ca084011cddc20f5c0b770ee38f9ac55d62bff24
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date: Tue Aug 1 13:57:53 2023 +0300
all: docs
commit 1b498a84d6cb8207d350fceb4db64d45dc2aa46d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date: Tue Aug 1 13:46:13 2023 +0300
all: docs
commit 0cd76c057e0f3e9e62e5bf38f95080afa830f4ff
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date: Tue Aug 1 13:00:43 2023 +0300
home: pprof conf
This commit is contained in:
parent
c0691cab6a
commit
5eb3cd0f92
30
CHANGELOG.md
30
CHANGELOG.md
|
@ -23,6 +23,36 @@ See also the [v0.107.37 GitHub milestone][ms-v0.107.37].
|
|||
NOTE: Add new changes BELOW THIS COMMENT.
|
||||
-->
|
||||
|
||||
### Added
|
||||
|
||||
- The ability to set the port for the `pprof` debug API, see configuration
|
||||
changes below.
|
||||
|
||||
### Changed
|
||||
|
||||
#### Configuration Changes
|
||||
|
||||
In this release, the schema version has changed from 24 to 25.
|
||||
|
||||
- Property `debug_pprof` which used to setup profiling HTTP handler, is now
|
||||
moved to the new `pprof` object under `http` section. The new object contains
|
||||
properties `enabled` and `port`:
|
||||
|
||||
```yaml
|
||||
# BEFORE:
|
||||
'debug_pprof': true
|
||||
|
||||
# AFTER:
|
||||
'http':
|
||||
'pprof':
|
||||
'enabled': true
|
||||
'port': 6060
|
||||
```
|
||||
|
||||
Note that the new default `6060` is used as default. To rollback this change,
|
||||
remove the new object `pprof`, set back `debug_pprof`, and change the
|
||||
`schema_version` back to `24`.
|
||||
|
||||
<!--
|
||||
NOTE: Add new changes ABOVE THIS COMMENT.
|
||||
-->
|
||||
|
|
|
@ -114,8 +114,6 @@ type configuration struct {
|
|||
Language string `yaml:"language"`
|
||||
// Theme is a UI theme for current user.
|
||||
Theme Theme `yaml:"theme"`
|
||||
// DebugPProf defines if the profiling HTTP handler will listen on :6060.
|
||||
DebugPProf bool `yaml:"debug_pprof"`
|
||||
|
||||
DNS dnsConfig `yaml:"dns"`
|
||||
TLS tlsConfigSettings `yaml:"tls"`
|
||||
|
@ -155,6 +153,9 @@ type configuration struct {
|
|||
// Field ordering is important, YAML fields better not to be reordered, if it's
|
||||
// not absolutely necessary.
|
||||
type httpConfig struct {
|
||||
// Pprof defines the profiling HTTP handler.
|
||||
Pprof *httpPprofConfig `yaml:"pprof"`
|
||||
|
||||
// Address is the address to serve the web UI on.
|
||||
Address netip.AddrPort
|
||||
|
||||
|
@ -163,6 +164,15 @@ type httpConfig struct {
|
|||
SessionTTL timeutil.Duration `yaml:"session_ttl"`
|
||||
}
|
||||
|
||||
// httpPprofConfig is the block with pprof HTTP configuration.
|
||||
type httpPprofConfig struct {
|
||||
// Port for the profiling handler.
|
||||
Port uint16 `yaml:"port"`
|
||||
|
||||
// Enabled defines if the profiling handler is enabled.
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
// dnsConfig is a block with DNS configuration params.
|
||||
//
|
||||
// Field ordering is important, YAML fields better not to be reordered, if it's
|
||||
|
@ -277,6 +287,10 @@ var config = &configuration{
|
|||
HTTPConfig: httpConfig{
|
||||
Address: netip.AddrPortFrom(netip.IPv4Unspecified(), 3000),
|
||||
SessionTTL: timeutil.Duration{Duration: 30 * timeutil.Day},
|
||||
Pprof: &httpPprofConfig{
|
||||
Enabled: false,
|
||||
Port: 6060,
|
||||
},
|
||||
},
|
||||
DNS: dnsConfig{
|
||||
BindHosts: []netip.Addr{netip.IPv4Unspecified()},
|
||||
|
|
|
@ -567,9 +567,8 @@ func run(opts options, clientBuildFS fs.FS) {
|
|||
err = config.write()
|
||||
fatalOnError(err)
|
||||
|
||||
if config.DebugPProf {
|
||||
// TODO(a.garipov): Make the address configurable.
|
||||
startPprof("localhost:6060")
|
||||
if config.HTTPConfig.Pprof.Enabled {
|
||||
startPprof(config.HTTPConfig.Pprof.Port)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
)
|
||||
|
||||
// currentSchemaVersion is the current schema version.
|
||||
const currentSchemaVersion = 24
|
||||
const currentSchemaVersion = 25
|
||||
|
||||
// These aliases are provided for convenience.
|
||||
type (
|
||||
|
@ -99,6 +99,7 @@ func upgradeConfigSchema(oldVersion int, diskConf yobj) (err error) {
|
|||
upgradeSchema21to22,
|
||||
upgradeSchema22to23,
|
||||
upgradeSchema23to24,
|
||||
upgradeSchema24to25,
|
||||
}
|
||||
|
||||
n := 0
|
||||
|
@ -1380,6 +1381,50 @@ func upgradeSchema23to24(diskConf yobj) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// upgradeSchema24to25 performs the following changes:
|
||||
//
|
||||
// # BEFORE:
|
||||
// 'debug_pprof': true
|
||||
//
|
||||
// # AFTER:
|
||||
// 'http':
|
||||
// 'pprof':
|
||||
// 'enabled': true
|
||||
// 'port': 6060
|
||||
func upgradeSchema24to25(diskConf yobj) (err error) {
|
||||
log.Printf("Upgrade yaml: 24 to 25")
|
||||
diskConf["schema_version"] = 25
|
||||
|
||||
debugPprofVal, ok := diskConf["debug_pprof"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
debugPprofEnabled, ok := debugPprofVal.(bool)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type of debug_pprof: %T", debugPprofVal)
|
||||
}
|
||||
|
||||
httpVal, ok := diskConf["http"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
httpObj, ok := httpVal.(yobj)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type of dns: %T", httpVal)
|
||||
}
|
||||
|
||||
httpObj["pprof"] = yobj{
|
||||
"enabled": debugPprofEnabled,
|
||||
"port": 6060,
|
||||
}
|
||||
|
||||
delete(diskConf, "debug_pprof")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// moveField gets field value for key from diskConf, and then set this value
|
||||
// in newConf for newKey.
|
||||
func moveField[T any](diskConf, newConf yobj, key, newKey string) (err error) {
|
||||
|
|
|
@ -1379,3 +1379,90 @@ func TestUpgradeSchema23to24(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpgradeSchema24to25(t *testing.T) {
|
||||
const newSchemaVer = 25
|
||||
|
||||
testCases := []struct {
|
||||
in yobj
|
||||
want yobj
|
||||
name string
|
||||
wantErrMsg string
|
||||
}{{
|
||||
name: "empty",
|
||||
in: yobj{},
|
||||
want: yobj{
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "ok",
|
||||
in: yobj{
|
||||
"http": yobj{
|
||||
"address": "0.0.0.0:3000",
|
||||
"session_ttl": "720h",
|
||||
},
|
||||
"debug_pprof": true,
|
||||
},
|
||||
want: yobj{
|
||||
"http": yobj{
|
||||
"address": "0.0.0.0:3000",
|
||||
"session_ttl": "720h",
|
||||
"pprof": yobj{
|
||||
"enabled": true,
|
||||
"port": 6060,
|
||||
},
|
||||
},
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "ok_disabled",
|
||||
in: yobj{
|
||||
"http": yobj{
|
||||
"address": "0.0.0.0:3000",
|
||||
"session_ttl": "720h",
|
||||
},
|
||||
"debug_pprof": false,
|
||||
},
|
||||
want: yobj{
|
||||
"http": yobj{
|
||||
"address": "0.0.0.0:3000",
|
||||
"session_ttl": "720h",
|
||||
"pprof": yobj{
|
||||
"enabled": false,
|
||||
"port": 6060,
|
||||
},
|
||||
},
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "invalid",
|
||||
in: yobj{
|
||||
"http": yobj{
|
||||
"address": "0.0.0.0:3000",
|
||||
"session_ttl": "720h",
|
||||
},
|
||||
"debug_pprof": 1,
|
||||
},
|
||||
want: yobj{
|
||||
"http": yobj{
|
||||
"address": "0.0.0.0:3000",
|
||||
"session_ttl": "720h",
|
||||
},
|
||||
"debug_pprof": 1,
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
wantErrMsg: "unexpected type of debug_pprof: int",
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := upgradeSchema24to25(tc.in)
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
|
||||
assert.Equal(t, tc.want, tc.in)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -312,8 +312,10 @@ func (web *webAPI) mustStartHTTP3(address string) {
|
|||
}
|
||||
}
|
||||
|
||||
// startPprof launches the debug and profiling server on addr.
|
||||
func startPprof(addr string) {
|
||||
// startPprof launches the debug and profiling server on the provided port.
|
||||
func startPprof(port uint16) {
|
||||
addr := netip.AddrPortFrom(netutil.IPv4Localhost(), port)
|
||||
|
||||
runtime.SetBlockProfileRate(1)
|
||||
runtime.SetMutexProfileFraction(1)
|
||||
|
||||
|
@ -324,7 +326,7 @@ func startPprof(addr string) {
|
|||
defer log.OnPanic("pprof server")
|
||||
|
||||
log.Info("pprof: listening on %q", addr)
|
||||
err := http.ListenAndServe(addr, mux)
|
||||
err := http.ListenAndServe(addr.String(), mux)
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
log.Error("pprof: shutting down: %s", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue