feat(common.http): Add support for connecting over unix-socket (#14103)

This commit is contained in:
Rajiv Kushwaha 2023-10-18 18:14:36 +05:30 committed by GitHub
parent 3d34c41154
commit 37ef23fb7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 6 deletions

View File

@ -281,6 +281,7 @@ following works:
- github.com/opentracing/opentracing-go [Apache License 2.0](https://github.com/opentracing/opentracing-go/blob/master/LICENSE) - github.com/opentracing/opentracing-go [Apache License 2.0](https://github.com/opentracing/opentracing-go/blob/master/LICENSE)
- github.com/p4lang/p4runtime [Apache License 2.0](https://github.com/p4lang/p4runtime/blob/main/LICENSE) - github.com/p4lang/p4runtime [Apache License 2.0](https://github.com/p4lang/p4runtime/blob/main/LICENSE)
- github.com/pborman/ansi [BSD 3-Clause "New" or "Revised" License](https://github.com/pborman/ansi/blob/master/LICENSE) - github.com/pborman/ansi [BSD 3-Clause "New" or "Revised" License](https://github.com/pborman/ansi/blob/master/LICENSE)
- github.com/peterbourgon/unixtransport [Apache License 2.0](https://github.com/peterbourgon/unixtransport/blob/main/LICENSE)
- github.com/philhofer/fwd [MIT License](https://github.com/philhofer/fwd/blob/master/LICENSE.md) - github.com/philhofer/fwd [MIT License](https://github.com/philhofer/fwd/blob/master/LICENSE.md)
- github.com/pierrec/lz4 [BSD 3-Clause "New" or "Revised" License](https://github.com/pierrec/lz4/blob/master/LICENSE) - github.com/pierrec/lz4 [BSD 3-Clause "New" or "Revised" License](https://github.com/pierrec/lz4/blob/master/LICENSE)
- github.com/pion/dtls [MIT License](https://github.com/pion/dtls/blob/master/LICENSES/MIT.txt) - github.com/pion/dtls [MIT License](https://github.com/pion/dtls/blob/master/LICENSES/MIT.txt)

1
go.mod
View File

@ -147,6 +147,7 @@ require (
github.com/openzipkin/zipkin-go v0.4.1 github.com/openzipkin/zipkin-go v0.4.1
github.com/p4lang/p4runtime v1.3.0 github.com/p4lang/p4runtime v1.3.0
github.com/pborman/ansi v1.0.0 github.com/pborman/ansi v1.0.0
github.com/peterbourgon/unixtransport v0.0.3
github.com/pion/dtls/v2 v2.2.7 github.com/pion/dtls/v2 v2.2.7
github.com/prometheus-community/pro-bing v0.3.0 github.com/prometheus-community/pro-bing v0.3.0
github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_golang v1.16.0

7
go.sum
View File

@ -1094,6 +1094,7 @@ github.com/microsoft/go-mssqldb v1.5.0/go.mod h1:lmWsjHD8XX/Txr0f8ZqgbEZSC+BZjmE
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
@ -1181,6 +1182,7 @@ github.com/nwaples/tacplus v0.0.3/go.mod h1:y5ZA9N5V2JbmwO766S+ET9zuu5FtL1OtdfBC
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4=
github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U= github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U=
@ -1252,6 +1254,10 @@ github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterbourgon/ff/v3 v3.3.1/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ=
github.com/peterbourgon/unixtransport v0.0.3 h1:NmGkSb+OOIeN2rNR+fF+F5kymwRy9VignywyDdtRrpc=
github.com/peterbourgon/unixtransport v0.0.3/go.mod h1:o8aUkOCa8W/BIXpi15uKvbSabjtBh0JhSOJGSfoOhAU=
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@ -1927,6 +1933,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=

View File

@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/benbjohnson/clock" "github.com/benbjohnson/clock"
"github.com/peterbourgon/unixtransport"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config" "github.com/influxdata/telegraf/config"
@ -48,6 +49,9 @@ func (h *HTTPClientConfig) CreateClient(ctx context.Context, log telegraf.Logger
MaxIdleConnsPerHost: h.MaxIdleConnsPerHost, MaxIdleConnsPerHost: h.MaxIdleConnsPerHost,
} }
// Register "http+unix" and "https+unix" protocol handler.
unixtransport.Register(transport)
timeout := h.Timeout timeout := h.Timeout
if timeout == 0 { if timeout == 0 {
timeout = config.Duration(time.Second * 5) timeout = config.Duration(time.Second * 5)

View File

@ -29,9 +29,10 @@ to use them.
```toml @sample.conf ```toml @sample.conf
# Read formatted metrics from one or more HTTP endpoints # Read formatted metrics from one or more HTTP endpoints
[[inputs.http]] [[inputs.http]]
## One or more URLs from which to read formatted metrics ## One or more URLs from which to read formatted metrics.
urls = [ urls = [
"http://localhost/metrics" "http://localhost/metrics",
"http+unix:///run/user/420/podman/podman.sock:/d/v4.0.0/libpod/pods/json"
] ]
## HTTP method ## HTTP method
@ -105,6 +106,17 @@ to use them.
``` ```
HTTP requests over Unix domain sockets can be specified via the "http+unix" or
"https+unix" schemes.
Request URLs should have the following form:
```text
http+unix:///path/to/service.sock:/api/endpoint
```
Note: The path to the Unix domain socket and the request endpoint are separated
by a colon (":").
## Example Output ## Example Output
This example output was taken from [this instructional article][1]. This example output was taken from [this instructional article][1].

View File

@ -4,9 +4,14 @@ import (
"compress/gzip" "compress/gzip"
"fmt" "fmt"
"io" "io"
"math/rand"
"net"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"os"
"path/filepath"
"strings"
"testing" "testing"
"time" "time"
@ -446,3 +451,74 @@ func TestHTTPWithCSVFormat(t *testing.T) {
require.NoError(t, acc.GatherError(plugin.Gather)) require.NoError(t, acc.GatherError(plugin.Gather))
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime()) testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
} }
const (
httpOverUnixScheme = "http+unix"
)
func TestConnectionOverUnixSocket(t *testing.T) {
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/data" {
w.Header().Set("Content-Type", "text/csv")
_, _ = w.Write([]byte(simpleCSVWithHeader))
} else {
w.WriteHeader(http.StatusNotFound)
}
}))
unixListenAddr := filepath.Join(os.TempDir(), fmt.Sprintf("httptestserver.%d.sock", rand.Intn(1_000_000)))
t.Cleanup(func() { os.Remove(unixListenAddr) })
unixListener, err := net.Listen("unix", unixListenAddr)
require.NoError(t, err)
ts.Listener = unixListener
ts.Start()
defer ts.Close()
// NOTE: Remove ":" from windows filepath and replace all "\" with "/".
// This is *required* so that the unix socket path plays well with unixtransport.
replacer := strings.NewReplacer(":", "", "\\", "/")
sockPath := replacer.Replace(unixListenAddr)
address := fmt.Sprintf("%s://%s:/data", httpOverUnixScheme, sockPath)
plugin := &httpplugin.HTTP{
URLs: []string{address},
Log: testutil.Logger{},
}
plugin.SetParserFunc(func() (telegraf.Parser, error) {
parser := &csv.Parser{
MetricName: "metricName",
SkipRows: 3,
ColumnNames: []string{"a", "b", "c"},
TagColumns: []string{"c"},
}
err := parser.Init()
return parser, err
})
expected := []telegraf.Metric{
testutil.MustMetric("metricName",
map[string]string{
"url": address,
"c": "ok",
},
map[string]interface{}{
"a": 1.2,
"b": 3.1415,
},
time.Unix(22000, 0),
),
}
var acc testutil.Accumulator
require.NoError(t, plugin.Init())
require.NoError(t, acc.GatherError(plugin.Gather))
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
// Run the parser a second time to test for correct stateful handling
acc.ClearMetrics()
require.NoError(t, acc.GatherError(plugin.Gather))
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
}

View File

@ -1,8 +1,9 @@
# Read formatted metrics from one or more HTTP endpoints # Read formatted metrics from one or more HTTP endpoints
[[inputs.http]] [[inputs.http]]
## One or more URLs from which to read formatted metrics ## One or more URLs from which to read formatted metrics.
urls = [ urls = [
"http://localhost/metrics" "http://localhost/metrics",
"http+unix:///run/user/420/podman/podman.sock:/d/v4.0.0/libpod/pods/json"
] ]
## HTTP method ## HTTP method

View File

@ -1,8 +1,9 @@
# Read formatted metrics from one or more HTTP endpoints # Read formatted metrics from one or more HTTP endpoints
[[inputs.http]] [[inputs.http]]
## One or more URLs from which to read formatted metrics ## One or more URLs from which to read formatted metrics.
urls = [ urls = [
"http://localhost/metrics" "http://localhost/metrics",
"http+unix:///run/user/420/podman/podman.sock:/d/v4.0.0/libpod/pods/json"
] ]
## HTTP method ## HTTP method