feat(common.http): Add support for connecting over unix-socket (#14103)
This commit is contained in:
parent
3d34c41154
commit
37ef23fb7f
|
|
@ -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/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/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/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)
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -147,6 +147,7 @@ require (
|
|||
github.com/openzipkin/zipkin-go v0.4.1
|
||||
github.com/p4lang/p4runtime v1.3.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/prometheus-community/pro-bing v0.3.0
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
|
|
|
|||
7
go.sum
7
go.sum
|
|
@ -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.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.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
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/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.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
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/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=
|
||||
|
|
@ -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/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.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/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
||||
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.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/benbjohnson/clock"
|
||||
"github.com/peterbourgon/unixtransport"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
|
|
@ -48,6 +49,9 @@ func (h *HTTPClientConfig) CreateClient(ctx context.Context, log telegraf.Logger
|
|||
MaxIdleConnsPerHost: h.MaxIdleConnsPerHost,
|
||||
}
|
||||
|
||||
// Register "http+unix" and "https+unix" protocol handler.
|
||||
unixtransport.Register(transport)
|
||||
|
||||
timeout := h.Timeout
|
||||
if timeout == 0 {
|
||||
timeout = config.Duration(time.Second * 5)
|
||||
|
|
|
|||
|
|
@ -29,9 +29,10 @@ to use them.
|
|||
```toml @sample.conf
|
||||
# Read formatted metrics from one or more HTTP endpoints
|
||||
[[inputs.http]]
|
||||
## One or more URLs from which to read formatted metrics
|
||||
## One or more URLs from which to read formatted metrics.
|
||||
urls = [
|
||||
"http://localhost/metrics"
|
||||
"http://localhost/metrics",
|
||||
"http+unix:///run/user/420/podman/podman.sock:/d/v4.0.0/libpod/pods/json"
|
||||
]
|
||||
|
||||
## 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
|
||||
|
||||
This example output was taken from [this instructional article][1].
|
||||
|
|
|
|||
|
|
@ -4,9 +4,14 @@ import (
|
|||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -446,3 +451,74 @@ func TestHTTPWithCSVFormat(t *testing.T) {
|
|||
require.NoError(t, acc.GatherError(plugin.Gather))
|
||||
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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
# Read formatted metrics from one or more HTTP endpoints
|
||||
[[inputs.http]]
|
||||
## One or more URLs from which to read formatted metrics
|
||||
## One or more URLs from which to read formatted metrics.
|
||||
urls = [
|
||||
"http://localhost/metrics"
|
||||
"http://localhost/metrics",
|
||||
"http+unix:///run/user/420/podman/podman.sock:/d/v4.0.0/libpod/pods/json"
|
||||
]
|
||||
|
||||
## HTTP method
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
# Read formatted metrics from one or more HTTP endpoints
|
||||
[[inputs.http]]
|
||||
## One or more URLs from which to read formatted metrics
|
||||
## One or more URLs from which to read formatted metrics.
|
||||
urls = [
|
||||
"http://localhost/metrics"
|
||||
"http://localhost/metrics",
|
||||
"http+unix:///run/user/420/podman/podman.sock:/d/v4.0.0/libpod/pods/json"
|
||||
]
|
||||
|
||||
## HTTP method
|
||||
|
|
|
|||
Loading…
Reference in New Issue