diff --git a/documentation/en/default-lotus-config.toml b/documentation/en/default-lotus-config.toml index ad917814b..1c9caf3a0 100644 --- a/documentation/en/default-lotus-config.toml +++ b/documentation/en/default-lotus-config.toml @@ -23,6 +23,12 @@ #DisableMetadataLog = false +[Logging] + [Logging.SubsystemLevels] + # env var: LOTUS_LOGGING_SUBSYSTEMLEVELS_EXAMPLE-SUBSYSTEM + #example-subsystem = "INFO" + + [Libp2p] # Binding address for the libp2p host - 0 means random port. # Format: multiaddress; see https://multiformats.io/multiaddr/ diff --git a/documentation/en/default-lotus-miner-config.toml b/documentation/en/default-lotus-miner-config.toml index 00370a9cc..a6a36f742 100644 --- a/documentation/en/default-lotus-miner-config.toml +++ b/documentation/en/default-lotus-miner-config.toml @@ -23,6 +23,12 @@ #DisableMetadataLog = false +[Logging] + [Logging.SubsystemLevels] + # env var: LOTUS_LOGGING_SUBSYSTEMLEVELS_EXAMPLE-SUBSYSTEM + #example-subsystem = "INFO" + + [Libp2p] # Binding address for the libp2p host - 0 means random port. # Format: multiaddress; see https://multiformats.io/multiaddr/ diff --git a/lib/lotuslog/config.go b/lib/lotuslog/config.go new file mode 100644 index 000000000..bf6ceb63f --- /dev/null +++ b/lib/lotuslog/config.go @@ -0,0 +1,11 @@ +package lotuslog + +import logging "github.com/ipfs/go-log/v2" + +func SetLevelsFromConfig(l map[string]string) { + for sys, level := range l { + if err := logging.SetLogLevel(sys, level); err != nil { + continue + } + } +} diff --git a/node/builder.go b/node/builder.go index 81de3890d..acda5a07a 100644 --- a/node/builder.go +++ b/node/builder.go @@ -33,6 +33,7 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/stores" "github.com/filecoin-project/lotus/journal" "github.com/filecoin-project/lotus/journal/alerting" + "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/lib/peermgr" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" @@ -249,6 +250,9 @@ func Base() Option { // Config sets up constructors based on the provided Config func ConfigCommon(cfg *config.Common, enableLibp2pNode bool) Option { + // setup logging early + lotuslog.SetLevelsFromConfig(cfg.Logging.SubsystemLevels) + return Options( func(s *Settings) error { s.Config = true; return nil }, Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) { diff --git a/node/config/def.go b/node/config/def.go index 233eccdd5..edc7ffef5 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -47,6 +47,11 @@ func defCommon() Common { ListenAddress: "/ip4/127.0.0.1/tcp/1234/http", Timeout: Duration(30 * time.Second), }, + Logging: Logging{ + SubsystemLevels: map[string]string{ + "example-subsystem": "INFO", + }, + }, Libp2p: Libp2p{ ListenAddresses: []string{ "/ip4/0.0.0.0/tcp/0", diff --git a/node/config/def_test.go b/node/config/def_test.go index a7a0e77ca..9601ee95b 100644 --- a/node/config/def_test.go +++ b/node/config/def_test.go @@ -32,6 +32,24 @@ func TestDefaultFullNodeRoundtrip(t *testing.T) { require.True(t, reflect.DeepEqual(c, c2)) } +func TestDefaultFullNodeCommentRoundtrip(t *testing.T) { + c := DefaultFullNode() + + var s string + { + c, err := ConfigComment(DefaultFullNode()) + require.NoError(t, err) + s = string(c) + } + + c2, err := FromReader(strings.NewReader(s), DefaultFullNode()) + require.NoError(t, err) + + fmt.Println(s) + + require.True(t, reflect.DeepEqual(c, c2)) +} + func TestDefaultMinerRoundtrip(t *testing.T) { c := DefaultStorageMiner() diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index ccee363b4..edb4cf892 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -127,6 +127,12 @@ of automatically performing on-chain operations.`, Comment: ``, }, + { + Name: "Logging", + Type: "Logging", + + Comment: ``, + }, { Name: "Libp2p", Type: "Libp2p", @@ -484,6 +490,14 @@ count towards this limit.`, closed by the connection manager.`, }, }, + "Logging": []DocField{ + { + Name: "SubsystemLevels", + Type: "map[string]string", + + Comment: `SubsystemLevels specify per-subsystem log levels`, + }, + }, "MinerAddressConfig": []DocField{ { Name: "PreCommitControl", diff --git a/node/config/doc_util.go b/node/config/doc_util.go index ee70a9cfd..b88333238 100644 --- a/node/config/doc_util.go +++ b/node/config/doc_util.go @@ -16,7 +16,7 @@ func findDoc(root interface{}, section, name string) *DocField { return findDocSect("Common", section, name) } -func findDocSect(root string, section, name string) *DocField { +func findDocSect(root, section, name string) *DocField { path := strings.Split(section, ".") docSection := Doc[root] diff --git a/node/config/load.go b/node/config/load.go index db3914b6b..a76db7caf 100644 --- a/node/config/load.go +++ b/node/config/load.go @@ -69,7 +69,7 @@ func ConfigUpdate(cfgCur, cfgDef interface{}, comment bool) ([]byte, error) { } if comment { - // create a map of default lines so we can comment those out later + // create a map of default lines, so we can comment those out later defLines := strings.Split(defStr, "\n") defaults := map[string]struct{}{} for i := range defLines { diff --git a/node/config/types.go b/node/config/types.go index 55f924f2a..8320aea7e 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -13,10 +13,11 @@ import ( // Common is common config between full node and miner type Common struct { - API API - Backup Backup - Libp2p Libp2p - Pubsub Pubsub + API API + Backup Backup + Logging Logging + Libp2p Libp2p + Pubsub Pubsub } // FullNode is a full node config @@ -39,6 +40,12 @@ type Backup struct { DisableMetadataLog bool } +// Logging is the logging system config +type Logging struct { + // SubsystemLevels specify per-subsystem log levels + SubsystemLevels map[string]string +} + // StorageMiner is a miner config type StorageMiner struct { Common