bt: filter anacrolix logs to errors so warnings don't corrupt the readout
webseed/peer/tracker warnings (the 403/429 chatter) go through slog, the rest through the legacy analog logger; both default to Warning, which interleaves with and corrupts the live progress block. Filter both to Error and above so only genuine errors reach stderr. quietSlogger is a small testable helper; anacrolix/log becomes a direct dependency.
This commit is contained in:
17
bt/bt.go
17
bt/bt.go
@@ -9,12 +9,16 @@ package bt
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
alog "github.com/anacrolix/log"
|
||||||
missinggo "github.com/anacrolix/missinggo/v2"
|
missinggo "github.com/anacrolix/missinggo/v2"
|
||||||
"github.com/anacrolix/torrent"
|
"github.com/anacrolix/torrent"
|
||||||
"github.com/anacrolix/torrent/metainfo"
|
"github.com/anacrolix/torrent/metainfo"
|
||||||
@@ -73,6 +77,14 @@ func ParsePorts(spec string) []int {
|
|||||||
return ports
|
return ports
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// quietSlogger filters anacrolix's structured logging down to Error and above,
|
||||||
|
// so the routine webseed/peer/tracker warning chatter (the 403/429 noise) no
|
||||||
|
// longer interleaves with — and corrupts — the live progress display. Genuine
|
||||||
|
// errors still reach w.
|
||||||
|
func quietSlogger(w io.Writer) *slog.Logger {
|
||||||
|
return slog.New(slog.NewTextHandler(w, &slog.HandlerOptions{Level: slog.LevelError}))
|
||||||
|
}
|
||||||
|
|
||||||
// NewClient builds the shared anacrolix client from the run-wide config. When a
|
// NewClient builds the shared anacrolix client from the run-wide config. When a
|
||||||
// listen-port spec is given it tries each candidate port in turn, advancing past
|
// listen-port spec is given it tries each candidate port in turn, advancing past
|
||||||
// any that is already in use, and falls back to an OS-chosen port if none bind,
|
// any that is already in use, and falls back to an OS-chosen port if none bind,
|
||||||
@@ -91,6 +103,11 @@ func ParsePorts(spec string) []int {
|
|||||||
// prevention must come from a run-wide setting (e.g. --enable-dht=false).
|
// prevention must come from a run-wide setting (e.g. --enable-dht=false).
|
||||||
func NewClient(cfg ClientConfig) (*torrent.Client, error) {
|
func NewClient(cfg ClientConfig) (*torrent.Client, error) {
|
||||||
c := torrent.NewDefaultClientConfig()
|
c := torrent.NewDefaultClientConfig()
|
||||||
|
// Keep the library's own logging out of the readout. Webseed/peer warnings go
|
||||||
|
// through slog, the rest through the legacy analog logger, so filter both to
|
||||||
|
// Error and above (the analog default is Warning, which is what leaks today).
|
||||||
|
c.Slogger = quietSlogger(os.Stderr)
|
||||||
|
c.Logger = alog.Default.FilterLevel(alog.Error)
|
||||||
c.DataDir = cfg.Dir
|
c.DataDir = cfg.Dir
|
||||||
if c.DataDir == "" {
|
if c.DataDir == "" {
|
||||||
c.DataDir = "."
|
c.DataDir = "."
|
||||||
|
|||||||
@@ -1,10 +1,38 @@
|
|||||||
package bt
|
package bt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"log/slog"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TestQuietSloggerDropsWarnings: the library's warning chatter (the webseed
|
||||||
|
// 403/429 noise) is filtered out so it can't corrupt the live display, while a
|
||||||
|
// genuine error still gets through.
|
||||||
|
func TestQuietSloggerDropsWarnings(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
lg := quietSlogger(&buf)
|
||||||
|
|
||||||
|
lg.Warn("webseed request error", "err", "429 Too Many Requests")
|
||||||
|
if buf.Len() != 0 {
|
||||||
|
t.Errorf("warning leaked into output: %q", buf.String())
|
||||||
|
}
|
||||||
|
// anacrolix's webseed code logs via Log(ctx, level, ...); confirm that path is
|
||||||
|
// filtered too, not just the Warn helper.
|
||||||
|
lg.Log(context.Background(), slog.LevelWarn, "another warning")
|
||||||
|
if buf.Len() != 0 {
|
||||||
|
t.Errorf("Log-at-Warn leaked: %q", buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
lg.Error("real failure")
|
||||||
|
if !strings.Contains(buf.String(), "real failure") {
|
||||||
|
t.Errorf("error was suppressed, want it kept: %q", buf.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParsePorts(t *testing.T) {
|
func TestParsePorts(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
spec string
|
spec string
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -3,6 +3,7 @@ module github.com/hanbok/got
|
|||||||
go 1.25
|
go 1.25
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/anacrolix/log v0.17.1-0.20251118025802-918f1157b7bb
|
||||||
github.com/anacrolix/missinggo/v2 v2.10.0
|
github.com/anacrolix/missinggo/v2 v2.10.0
|
||||||
github.com/anacrolix/torrent v1.61.0
|
github.com/anacrolix/torrent v1.61.0
|
||||||
golang.org/x/sys v0.38.0
|
golang.org/x/sys v0.38.0
|
||||||
@@ -19,7 +20,6 @@ require (
|
|||||||
github.com/anacrolix/envpprof v1.4.0 // indirect
|
github.com/anacrolix/envpprof v1.4.0 // indirect
|
||||||
github.com/anacrolix/generics v0.1.1-0.20251125230353-15d98d46693b // indirect
|
github.com/anacrolix/generics v0.1.1-0.20251125230353-15d98d46693b // indirect
|
||||||
github.com/anacrolix/go-libutp v1.3.2 // indirect
|
github.com/anacrolix/go-libutp v1.3.2 // indirect
|
||||||
github.com/anacrolix/log v0.17.1-0.20251118025802-918f1157b7bb // indirect
|
|
||||||
github.com/anacrolix/missinggo v1.3.0 // indirect
|
github.com/anacrolix/missinggo v1.3.0 // indirect
|
||||||
github.com/anacrolix/missinggo/perf v1.0.0 // indirect
|
github.com/anacrolix/missinggo/perf v1.0.0 // indirect
|
||||||
github.com/anacrolix/mmsg v1.0.1 // indirect
|
github.com/anacrolix/mmsg v1.0.1 // indirect
|
||||||
|
|||||||
Reference in New Issue
Block a user