v0.28.0 option schema in struct tags, schema replacing plugin factory metadata, tui prep
This commit is contained in:
1 parent
a1648ce17b
commit
e8e5f05e47
43 files changed
+1345
-1211
No files matched your search
@@ -19,7 +19,6 @@ import (
|
||||
"github.com/lixenwraith/logwisp/internal/sink"
|
||||
|
||||
"github.com/lixenwraith/color"
|
||||
lconfig "github.com/lixenwraith/config"
|
||||
"github.com/lixenwraith/log"
|
||||
"github.com/lixenwraith/terminal/inline"
|
||||
"golang.org/x/term"
|
||||
@@ -61,14 +60,6 @@ type ConsoleSink struct {
|
||||
lastProcessed atomic.Value // time.Time
|
||||
}
|
||||
|
||||
const (
|
||||
// Defaults
|
||||
DefaultConsoleTarget = "stdout"
|
||||
DefaultConsoleBufferSize = 1000
|
||||
DefaultConsoleEscape = "auto"
|
||||
DefaultConsoleColor = "auto"
|
||||
)
|
||||
|
||||
// levelStyles colors the levels in ANSI 16, so the terminal's theme picks the
|
||||
// shades and a text console renders them; cyan, not blue, stays readable on black
|
||||
var levelStyles = map[string]inline.Style{
|
||||
@@ -86,21 +77,9 @@ func NewConsoleSinkPlugin(
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
opts := &config.ConsoleSinkOptions{Target: DefaultConsoleTarget, Escape: DefaultConsoleEscape, Color: DefaultConsoleColor}
|
||||
|
||||
// Scan config map into struct
|
||||
if err := config.Scan(configMap, opts); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
}
|
||||
|
||||
if err := lconfig.OneOf("stdout", "stderr")(opts.Target); err != nil {
|
||||
return nil, fmt.Errorf("target: %w", err)
|
||||
}
|
||||
if err := lconfig.OneOf("auto", "always", "never")(opts.Escape); err != nil {
|
||||
return nil, fmt.Errorf("escape: %w", err)
|
||||
}
|
||||
if err := lconfig.OneOf("auto", "always", "never")(opts.Color); err != nil {
|
||||
return nil, fmt.Errorf("color: %w", err)
|
||||
opts, err := config.Decode[config.ConsoleSinkOptions]("sink", "console", configMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output := os.Stdout
|
||||
@@ -108,10 +87,6 @@ func NewConsoleSinkPlugin(
|
||||
output = os.Stderr
|
||||
}
|
||||
|
||||
if opts.BufferSize <= 0 {
|
||||
opts.BufferSize = DefaultConsoleBufferSize
|
||||
}
|
||||
|
||||
// inline decides auto: a terminal, NO_COLOR unset, TERM not dumb. Paint
|
||||
// returns its text unchanged exactly when color is off.
|
||||
printer := inline.New(output)
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/lixenwraith/logwisp/internal/session"
|
||||
"github.com/lixenwraith/logwisp/internal/sink"
|
||||
|
||||
lconfig "github.com/lixenwraith/config"
|
||||
"github.com/lixenwraith/log"
|
||||
)
|
||||
|
||||
@@ -50,16 +49,6 @@ type FileSink struct {
|
||||
lastProcessed atomic.Value // time.Time
|
||||
}
|
||||
|
||||
const (
|
||||
// Defaults
|
||||
DefaultFileMaxSizeMB = 100
|
||||
DefaultFileMaxTotalSizeMB = 1000
|
||||
DefaultFileMinDiskFreeMB = 100
|
||||
DefaultFileRetentionHours = 168 // 7 days
|
||||
DefaultFileBufferSize = 1000
|
||||
DefaultFileFlushIntervalMs = 100
|
||||
)
|
||||
|
||||
// NewFileSinkPlugin creates a file sink through plugin factory
|
||||
func NewFileSinkPlugin(
|
||||
id string,
|
||||
@@ -68,42 +57,11 @@ func NewFileSinkPlugin(
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
// Create empty config struct
|
||||
opts := &config.FileSinkOptions{}
|
||||
|
||||
// Scan config map into struct
|
||||
if err := config.Scan(configMap, opts); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
opts, err := config.Decode[config.FileSinkOptions]("sink", "file", configMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate
|
||||
if err := lconfig.NonEmpty(opts.Directory); err != nil {
|
||||
return nil, fmt.Errorf("directory: %w", err)
|
||||
}
|
||||
if err := lconfig.NonEmpty(opts.Name); err != nil {
|
||||
return nil, fmt.Errorf("name: %w", err)
|
||||
}
|
||||
|
||||
// Defaults
|
||||
if opts.MaxSizeMB <= 0 {
|
||||
opts.MaxSizeMB = DefaultFileMaxSizeMB
|
||||
}
|
||||
if opts.MaxTotalSizeMB <= 0 {
|
||||
opts.MaxTotalSizeMB = DefaultFileMaxTotalSizeMB
|
||||
}
|
||||
if opts.MinDiskFreeMB < 0 {
|
||||
opts.MinDiskFreeMB = DefaultFileMinDiskFreeMB
|
||||
}
|
||||
if opts.RetentionHours <= 0 {
|
||||
opts.RetentionHours = DefaultFileRetentionHours
|
||||
}
|
||||
if opts.BufferSize <= 0 {
|
||||
opts.BufferSize = DefaultFileBufferSize
|
||||
}
|
||||
if opts.FlushIntervalMs <= 0 {
|
||||
opts.FlushIntervalMs = DefaultFileFlushIntervalMs
|
||||
}
|
||||
|
||||
// Create configuration for the internal log writer
|
||||
writerConfig := log.DefaultConfig()
|
||||
writerConfig.Directory = opts.Directory
|
||||
writerConfig.Name = opts.Name
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"maps"
|
||||
"net"
|
||||
"net/http"
|
||||
"path"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
"github.com/lixenwraith/logwisp/internal/tlsx"
|
||||
"github.com/lixenwraith/logwisp/internal/version"
|
||||
|
||||
lconfig "github.com/lixenwraith/config"
|
||||
"github.com/lixenwraith/log"
|
||||
)
|
||||
|
||||
@@ -39,14 +37,7 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultHTTPHost = "0.0.0.0"
|
||||
DefaultHTTPBufferSize = 1000
|
||||
DefaultHTTPClientBufferSize = 256
|
||||
DefaultHTTPStreamPath = "/stream"
|
||||
DefaultHTTPStatusPath = "/status"
|
||||
HTTPReadHeaderTimeout = 10 * time.Second
|
||||
)
|
||||
const HTTPReadHeaderTimeout = 10 * time.Second
|
||||
|
||||
// HTTPSink streams log entries via Server-Sent Events
|
||||
// Server.WriteTimeout is deliberately unset (it would terminate long-lived SSE streams)
|
||||
@@ -117,42 +108,13 @@ func NewHTTPSinkPlugin(
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
opts := &config.HTTPSinkOptions{
|
||||
Host: DefaultHTTPHost,
|
||||
WriteTimeoutMS: 0, // SSE indefinite streaming
|
||||
}
|
||||
if err := config.Scan(configMap, opts); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
}
|
||||
if err := lconfig.Port(opts.Port); err != nil {
|
||||
return nil, fmt.Errorf("port: %w", err)
|
||||
opts, err := config.Decode[config.HTTPSinkOptions]("sink", "http", configMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
network, err := core.Network(opts.Host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("host: %w", err)
|
||||
}
|
||||
if opts.StreamPath == "" {
|
||||
opts.StreamPath = DefaultHTTPStreamPath
|
||||
}
|
||||
if opts.StatusPath == "" {
|
||||
opts.StatusPath = DefaultHTTPStatusPath
|
||||
}
|
||||
for _, o := range []struct{ name, p string }{{"stream_path", opts.StreamPath}, {"status_path", opts.StatusPath}} {
|
||||
if !routable(o.p) {
|
||||
return nil, fmt.Errorf("%s %q: must start with '/', hold no '//', '.' or '..' segment, and none of '{', '}', '%%', '?', '#'", o.name, o.p)
|
||||
}
|
||||
if p := o.p; p == chain.AuthPath || strings.HasPrefix(p, chain.AuthPath+"/") {
|
||||
return nil, fmt.Errorf("%s and the paths under it are reserved for authentication", chain.AuthPath)
|
||||
}
|
||||
}
|
||||
if opts.StreamPath == opts.StatusPath {
|
||||
return nil, fmt.Errorf("stream_path and status_path must differ")
|
||||
}
|
||||
if opts.BufferSize <= 0 {
|
||||
opts.BufferSize = DefaultHTTPBufferSize
|
||||
}
|
||||
if opts.ClientBufferSize <= 0 {
|
||||
opts.ClientBufferSize = DefaultHTTPClientBufferSize
|
||||
return nil, err
|
||||
}
|
||||
tlsCfg, err := tlsx.Server(opts.TLS, opts.Host)
|
||||
if err != nil {
|
||||
@@ -166,16 +128,10 @@ func NewHTTPSinkPlugin(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, aclPolicy, authz.RoleListener, authz.HTTP)
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, aclPolicy, config.Listener, authz.HTTP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch {
|
||||
case (opts.LoginPage || opts.ViewerPage) && !authPolicy.BehindProxy():
|
||||
return nil, errors.New("login_page and viewer_page apply to scram behind auth.trusted_proxies, where browsers log in; without auth or under mtls the viewer is always served")
|
||||
case opts.ViewerPage && !opts.LoginPage:
|
||||
return nil, errors.New("viewer_page needs login_page, where it sends a signed-out viewer")
|
||||
}
|
||||
web, err := webHandlers(opts, authPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -705,13 +661,6 @@ func (h *HTTPSink) handleAuth(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// routable reports a path ServeMux and a URL take literally: clean, a trailing
|
||||
// '/' aside, without the braces of wildcards, an escape, a query or a fragment
|
||||
func routable(p string) bool {
|
||||
c := path.Clean(p)
|
||||
return strings.HasPrefix(p, "/") && !strings.ContainsAny(p, "{}%?#") && (c == p || c != "/" && c+"/" == p)
|
||||
}
|
||||
|
||||
// exact keeps a path ending in '/' from matching every path beneath it
|
||||
func exact(p string) string {
|
||||
if strings.HasSuffix(p, "/") {
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -26,7 +25,6 @@ import (
|
||||
"github.com/lixenwraith/logwisp/internal/sink"
|
||||
"github.com/lixenwraith/logwisp/internal/tlsx"
|
||||
|
||||
lconfig "github.com/lixenwraith/config"
|
||||
"github.com/lixenwraith/log"
|
||||
)
|
||||
|
||||
@@ -37,15 +35,7 @@ func init() {
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultHTTPChainSinkBufferSize = 1000
|
||||
DefaultHTTPChainSinkIngestPath = "/ingest"
|
||||
DefaultHTTPChainSinkMaxBatchCount = 100
|
||||
DefaultHTTPChainSinkMaxBatchBytes = 1024 * 1024
|
||||
DefaultHTTPChainSinkFlushIntervalMS = 1000
|
||||
DefaultHTTPChainSinkRequestTimeoutMS = 10000
|
||||
DefaultHTTPChainSinkBackoffMinMS = 500
|
||||
DefaultHTTPChainSinkBackoffMaxMS = 30000
|
||||
maxResponseDrain = 64 * 1024
|
||||
maxResponseDrain = 64 * 1024
|
||||
)
|
||||
|
||||
// HTTPChainSink batches structured entries and posts NDJSON to a downstream
|
||||
@@ -94,47 +84,13 @@ func NewHTTPChainSinkPlugin(
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
opts := &config.HTTPChainSinkOptions{}
|
||||
if err := config.Scan(configMap, opts); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
}
|
||||
if err := lconfig.NonEmpty(opts.Host); err != nil {
|
||||
return nil, fmt.Errorf("host: %w", err)
|
||||
}
|
||||
if err := lconfig.Port(opts.Port); err != nil {
|
||||
return nil, fmt.Errorf("port: %w", err)
|
||||
opts, err := config.Decode[config.HTTPChainSinkOptions]("sink", "http_chain", configMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
network, err := core.Network(opts.Host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("host: %w", err)
|
||||
}
|
||||
if opts.IngestPath == "" {
|
||||
opts.IngestPath = DefaultHTTPChainSinkIngestPath
|
||||
} else if !strings.HasPrefix(opts.IngestPath, "/") {
|
||||
return nil, fmt.Errorf("ingest_path: must start with '/'")
|
||||
} else if opts.IngestPath == chain.AuthPath {
|
||||
return nil, fmt.Errorf("ingest_path: %s is reserved for authentication", chain.AuthPath)
|
||||
}
|
||||
if opts.BufferSize <= 0 {
|
||||
opts.BufferSize = DefaultHTTPChainSinkBufferSize
|
||||
}
|
||||
if opts.MaxBatchCount <= 0 {
|
||||
opts.MaxBatchCount = DefaultHTTPChainSinkMaxBatchCount
|
||||
}
|
||||
if opts.MaxBatchBytes <= 0 {
|
||||
opts.MaxBatchBytes = DefaultHTTPChainSinkMaxBatchBytes
|
||||
}
|
||||
if opts.FlushIntervalMS <= 0 {
|
||||
opts.FlushIntervalMS = DefaultHTTPChainSinkFlushIntervalMS
|
||||
}
|
||||
if opts.RequestTimeoutMS <= 0 {
|
||||
opts.RequestTimeoutMS = DefaultHTTPChainSinkRequestTimeoutMS
|
||||
}
|
||||
if opts.BackoffMinMS <= 0 {
|
||||
opts.BackoffMinMS = DefaultHTTPChainSinkBackoffMinMS
|
||||
}
|
||||
if opts.BackoffMaxMS < opts.BackoffMinMS {
|
||||
opts.BackoffMaxMS = DefaultHTTPChainSinkBackoffMaxMS
|
||||
return nil, err
|
||||
}
|
||||
|
||||
node := opts.Node
|
||||
@@ -150,7 +106,7 @@ func NewHTTPChainSinkPlugin(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, nil, authz.RoleDialer, authz.HTTP)
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, nil, config.Dialer, authz.HTTP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func TestRefusedTokenLogsInAgainAndDeliversOnce(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serverTLS := &tls.Config{Certificates: []tls.Certificate{serverCert}}
|
||||
listener, err := authz.New(&config.AuthOptions{Type: authz.MethodSCRAM, CredentialsFile: creds}, serverTLS, nil, authz.RoleChainListener, authz.HTTP)
|
||||
listener, err := authz.New(&config.AuthOptions{Type: authz.MethodSCRAM, CredentialsFile: creds}, serverTLS, nil, config.ChainListener, authz.HTTP)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ func NewNullSinkPlugin(
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
if err := config.Scan(configMap, &config.NullSinkOptions{}); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
if _, err := config.Decode[config.NullSinkOptions]("sink", "null", configMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ns := &NullSink{
|
||||
id: id,
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/lixenwraith/logwisp/internal/sink"
|
||||
"github.com/lixenwraith/logwisp/internal/tlsx"
|
||||
|
||||
lconfig "github.com/lixenwraith/config"
|
||||
"github.com/lixenwraith/log"
|
||||
)
|
||||
|
||||
@@ -32,14 +31,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultTCPHost = "0.0.0.0"
|
||||
DefaultTCPBufferSize = 1000
|
||||
DefaultTCPClientBufferSize = 256
|
||||
DefaultTCPWriteTimeoutMS = 5000
|
||||
DefaultTCPKeepAlivePeriodMS = 30000
|
||||
)
|
||||
|
||||
// TCPSink streams formatted log entries to connected TCP clients
|
||||
// Concurrency model: one broadcast loop fans out into bounded per-client queues
|
||||
// each connection owns a writer goroutine (drains queue) and a reader goroutine (disconnect detection)
|
||||
@@ -117,31 +108,13 @@ func NewTCPSinkPlugin(
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
opts := &config.TCPSinkOptions{
|
||||
Host: DefaultTCPHost,
|
||||
KeepAlive: true,
|
||||
}
|
||||
if err := config.Scan(configMap, opts); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
}
|
||||
if err := lconfig.Port(opts.Port); err != nil {
|
||||
return nil, fmt.Errorf("port: %w", err)
|
||||
opts, err := config.Decode[config.TCPSinkOptions]("sink", "tcp", configMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
network, err := core.Network(opts.Host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("host: %w", err)
|
||||
}
|
||||
if opts.BufferSize <= 0 {
|
||||
opts.BufferSize = DefaultTCPBufferSize
|
||||
}
|
||||
if opts.ClientBufferSize <= 0 {
|
||||
opts.ClientBufferSize = DefaultTCPClientBufferSize
|
||||
}
|
||||
if opts.WriteTimeoutMS <= 0 {
|
||||
opts.WriteTimeoutMS = DefaultTCPWriteTimeoutMS
|
||||
}
|
||||
if opts.KeepAlivePeriodMS <= 0 {
|
||||
opts.KeepAlivePeriodMS = DefaultTCPKeepAlivePeriodMS
|
||||
return nil, err
|
||||
}
|
||||
tlsCfg, err := tlsx.Server(opts.TLS, opts.Host)
|
||||
if err != nil {
|
||||
@@ -151,7 +124,7 @@ func NewTCPSinkPlugin(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, aclPolicy, authz.RoleListener, authz.TCP)
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, aclPolicy, config.Listener, authz.TCP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -217,6 +190,8 @@ func (t *TCPSink) listen() (net.Listener, error) {
|
||||
Enable: true,
|
||||
Idle: time.Duration(t.config.KeepAlivePeriodMS) * time.Millisecond,
|
||||
}
|
||||
} else {
|
||||
lc.KeepAlive = -1 // zero would be Go's default, keep-alive every 15 s
|
||||
}
|
||||
ln, err := core.Listen(context.Background(), &lc, t.network, t.addr)
|
||||
if err != nil {
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"github.com/lixenwraith/logwisp/internal/sink"
|
||||
"github.com/lixenwraith/logwisp/internal/tlsx"
|
||||
|
||||
lconfig "github.com/lixenwraith/config"
|
||||
"github.com/lixenwraith/log"
|
||||
)
|
||||
|
||||
@@ -33,15 +32,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultChainSinkBufferSize = 1000
|
||||
DefaultChainSinkDialTimeoutMS = 5000
|
||||
DefaultChainSinkWriteTimeoutMS = 5000
|
||||
DefaultChainSinkBackoffMinMS = 500
|
||||
DefaultChainSinkBackoffMaxMS = 30000
|
||||
DefaultChainSinkKeepAlivePeriodMS = 30000
|
||||
)
|
||||
|
||||
// TCPChainSink forwards structured entries to a downstream tcp_chain source
|
||||
type TCPChainSink struct {
|
||||
id string
|
||||
@@ -89,40 +79,13 @@ func NewTCPChainSinkPlugin(
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
opts := &config.TCPChainSinkOptions{
|
||||
KeepAlive: true,
|
||||
}
|
||||
if err := config.Scan(configMap, opts); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config: %w", err)
|
||||
}
|
||||
if err := lconfig.NonEmpty(opts.Host); err != nil {
|
||||
return nil, fmt.Errorf("host: %w", err)
|
||||
}
|
||||
if err := lconfig.Port(opts.Port); err != nil {
|
||||
return nil, fmt.Errorf("port: %w", err)
|
||||
opts, err := config.Decode[config.TCPChainSinkOptions]("sink", "tcp_chain", configMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
network, err := core.Network(opts.Host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("host: %w", err)
|
||||
}
|
||||
|
||||
if opts.BufferSize <= 0 {
|
||||
opts.BufferSize = DefaultChainSinkBufferSize
|
||||
}
|
||||
if opts.DialTimeoutMS <= 0 {
|
||||
opts.DialTimeoutMS = DefaultChainSinkDialTimeoutMS
|
||||
}
|
||||
if opts.WriteTimeoutMS <= 0 {
|
||||
opts.WriteTimeoutMS = DefaultChainSinkWriteTimeoutMS
|
||||
}
|
||||
if opts.BackoffMinMS <= 0 {
|
||||
opts.BackoffMinMS = DefaultChainSinkBackoffMinMS
|
||||
}
|
||||
if opts.BackoffMaxMS < opts.BackoffMinMS {
|
||||
opts.BackoffMaxMS = DefaultChainSinkBackoffMaxMS
|
||||
}
|
||||
if opts.KeepAlivePeriodMS <= 0 {
|
||||
opts.KeepAlivePeriodMS = DefaultChainSinkKeepAlivePeriodMS
|
||||
return nil, err
|
||||
}
|
||||
|
||||
node := opts.Node
|
||||
@@ -138,7 +101,7 @@ func NewTCPChainSinkPlugin(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, nil, authz.RoleDialer, authz.TCP)
|
||||
authPolicy, err := authz.New(opts.Auth, tlsCfg, nil, config.Dialer, authz.TCP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -378,6 +341,8 @@ func (t *TCPChainSink) connect(ctx context.Context) error {
|
||||
Enable: true,
|
||||
Idle: time.Duration(t.config.KeepAlivePeriodMS) * time.Millisecond,
|
||||
}
|
||||
} else {
|
||||
nd.KeepAlive = -1 // zero would be Go's default, keep-alive every 15 s
|
||||
}
|
||||
|
||||
var conn net.Conn
|
||||
|
||||
Reference in new issue
Block a user