Skip to content

Commit

Permalink
x-pack/filebeat : Sanitize trace log filename to support multiple OS (#…
Browse files Browse the repository at this point in the history
…35143)

* Sanitize trace log filename for multiple OS

* Fix PR comments

(cherry picked from commit b47e4fd)
  • Loading branch information
bhapas authored and mergify[bot] committed Apr 20, 2023
1 parent e2dade6 commit 7e611f7
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ https://github.com/elastic/beats/compare/v8.2.0\...main[Check the HEAD diff]
- Fix panic in TCP and UDP inputs on Linux when collecting socket metrics from OS. {issue}35064[35064]
- Correctly collect TCP and UDP metrics for unspecified address values. {pull}35111[35111]
- Fix base for UDP and TCP queue metrics and UDP drops metric. {pull}35123[35123]
- Sanitize filenames for request tracer in httpjson and cel inputs. {pull}35143[35143]

*Heartbeat*

Expand Down
14 changes: 13 additions & 1 deletion x-pack/filebeat/input/httpjson/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net"
"net/http"
"net/url"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -113,7 +114,8 @@ func run(
stdCtx := ctxtool.FromCanceller(ctx.Cancelation)

if config.Request.Tracer != nil {
config.Request.Tracer.Filename = strings.ReplaceAll(config.Request.Tracer.Filename, "*", ctx.ID)
id := sanitizeFileName(ctx.ID)
config.Request.Tracer.Filename = strings.ReplaceAll(config.Request.Tracer.Filename, "*", id)
}

httpClient, err := newHTTPClient(stdCtx, config, log)
Expand Down Expand Up @@ -159,6 +161,16 @@ func run(
return nil
}

// The Request.Tracer.Filename may have ":" when a httpjson input has cursor config
// The MacOs Finder will treat this as path-separator and causes to show up strange filepaths.
// This function will sanitize characters like ":" and "/" to replace them with "_" just to be
// safe on all operating systems.
func sanitizeFileName(name string) string {
name = strings.ReplaceAll(name, ":", string(filepath.Separator))
name = filepath.Clean(name)
return strings.ReplaceAll(name, string(filepath.Separator), "_")
}

func newHTTPClient(ctx context.Context, config config, log *logp.Logger) (*httpClient, error) {
// Make retryable HTTP client
netHTTPClient, err := config.Request.Transport.Client(clientOptions(config.Request.URL.URL, config.Request.KeepAlive.settings())...)
Expand Down
53 changes: 52 additions & 1 deletion x-pack/filebeat/input/httpjson/input_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"math/rand"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"

Expand Down Expand Up @@ -292,6 +293,49 @@ func TestInput(t *testing.T) {
`{"@timestamp":"2002-10-02T15:00:02Z","foo":"bar"}`,
},
},
{
name: "Test filename truncation",
setupServer: func(t *testing.T, h http.HandlerFunc, config map[string]interface{}) {
registerRequestTransforms()
t.Cleanup(func() { registeredTransforms = newRegistry() })
// mock timeNow func to return a fixed value
timeNow = func() time.Time {
t, _ := time.Parse(time.RFC3339, "2002-10-02T15:00:00Z")
return t
}

server := httptest.NewServer(h)
config["request.url"] = server.URL
t.Cleanup(server.Close)
t.Cleanup(func() { timeNow = time.Now })
},
baseConfig: map[string]interface{}{
"interval": 1,
"request.method": http.MethodGet,
"request.transforms": []interface{}{
map[string]interface{}{
"set": map[string]interface{}{
"target": "url.params.$filter",
"value": "alertCreationTime ge [[.cursor.timestamp]]",
"default": `alertCreationTime ge [[formatDate (now (parseDuration "-10m")) "2006-01-02T15:04:05Z"]]`,
},
},
},
"cursor": map[string]interface{}{
"timestamp": map[string]interface{}{
"value": `[[index .last_response.body "@timestamp"]]`,
},
},
"request.tracer.filename": "../../logs/httpjson/http-request-trace-*.ndjson",
"verifyfilepath": true,
},
handler: dateCursorHandler(),
expected: []string{
`{"@timestamp":"2002-10-02T15:00:00Z","foo":"bar"}`,
`{"@timestamp":"2002-10-02T15:00:01Z","foo":"bar"}`,
`{"@timestamp":"2002-10-02T15:00:02Z","foo":"bar"}`,
},
},
{
name: "Test pagination",
setupServer: func(t *testing.T, h http.HandlerFunc, config map[string]interface{}) {
Expand Down Expand Up @@ -1191,6 +1235,13 @@ func TestInput(t *testing.T) {
}
}
}
if tc.baseConfig["verifyfilepath"] != nil {
if _, err := os.Stat("../../logs/httpjson/http-request-trace-httpjson-foo-eb837d4c-5ced-45ed-b05c-de658135e248_https_somesource_someapi.ndjson"); err == nil {
assert.NoError(t, g.Wait())
} else {
t.Errorf("Expected log filename not found")
}
}
assert.NoError(t, g.Wait())
})
}
Expand Down Expand Up @@ -1257,7 +1308,7 @@ func newV2Context() (v2.Context, func()) {
ctx, cancel := context.WithCancel(context.Background())
return v2.Context{
Logger: logp.NewLogger("httpjson_test"),
ID: "test_id",
ID: "httpjson-foo-eb837d4c-5ced-45ed-b05c-de658135e248::https://somesource/someapi",
Cancelation: ctx,
}, cancel
}
Expand Down

0 comments on commit 7e611f7

Please sign in to comment.