Skip to content

Commit 03faaee

Browse files
mergify[bot]efd6
andauthored
[8.19](backport #45810) x-pack/filebeat/input/httpjson: allow template termination without logging error (#45994)
* x-pack/filebeat/input/httpjson: allow template termination without logging error (#45810) This adds a terminate helper that can be used to signal that a template should terminate without an error. The termination can (should) be used to report the reason for the termination which will be logged at DEBUG level, but otherwise ignored. (cherry picked from commit f324f29) # Conflicts: # docs/reference/filebeat/filebeat-input-httpjson.md * remove markdown * add asciidoc documentation --------- Co-authored-by: Dan Kortschak <dan.kortschak@elastic.co>
1 parent 142d696 commit 03faaee

File tree

5 files changed

+30
-1
lines changed

5 files changed

+30
-1
lines changed

CHANGELOG.next.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
300300
- Log CEL single object evaluation results as ECS compliant documents where possible. {issue}45254[45254] {pull}45399[45399]
301301
- Enhanced HTTPJSON input error logging with structured error metadata conforming to Elastic Common Schema (ECS) conventions. {pull}45653[45653]19
302302
- Add status reporting support for AWS CloudWatch input. {pull}45679[45679]
303+
- Add mechanism to allow HTTP JSON templates to terminate without logging an error. {issue}45664[45664] {pull}45810[45810]
303304

304305
*Auditbeat*
305306

x-pack/filebeat/docs/inputs/input-httpjson.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ Some built-in helper functions are provided to work with the input state inside
230230
- `parseTimestamp`: parses a timestamp in seconds and returns a `time.Time` in UTC. Example: `[[parseTimestamp 1604582732]]` returns `2020-11-05 13:25:32 +0000 UTC`.
231231
- `replaceAll(old, new, s)`: replaces all non-overlapping instances of `old` with `new` in `s`. Example: `[[ replaceAll "some" "my" "some value" ]]` returns `my value`.
232232
- `sprintf`: formats according to a format specifier and returns the resulting string. Refer to https://pkg.go.dev/fmt#Sprintf[the Go docs] for usage. Example: `[[sprintf "%d:%q" 34 "quote this"]]`
233+
- `terminate`: exits the template without falling back to the default value and without causing an error. It takes a single string argument that is logged in debug logging.
233234
- `toInt`: converts a value of any type to an integer when possible. Returns 0 if the conversion fails.
234235
- `toJSON`: converts a value to a JSON string. This can be used with `value_type: json` to create an object from a template. Example: `[[ toJSON .last_response.body.pagingIdentifiers ]]`.
235236
- `urlEncode`: URL encodes the supplied string. Example `[[urlEncode "string1"]]`. Example `[[urlEncode "<string1>"]]` will return `%3Cstring1%3E`.

x-pack/filebeat/input/httpjson/request.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,11 @@ func evaluateResponse(expression *valueTpl, data []byte, stat status.StatusRepor
414414

415415
val, err := expression.Execute(paramCtx, tr, "response_evaluation", nil, stat, log)
416416
if err != nil {
417-
418417
return false, fmt.Errorf("error while evaluating expression: %w", err)
419418
}
419+
if val == "" {
420+
return false, nil
421+
}
420422
result, err := strconv.ParseBool(val)
421423
if err != nil {
422424
return false, fmt.Errorf("error while parsing boolean value of string: %w", err)

x-pack/filebeat/input/httpjson/value_tpl.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func (t *valueTpl) Unpack(in string) error {
8383
"urlEncode": urlEncode,
8484
"userAgent": userAgentString,
8585
"uuid": uuidString,
86+
"terminate": func(s string) (any, error) { return nil, &errTerminate{s} },
8687
}).
8788
Delims(leftDelim, rightDelim).
8889
Parse(in)
@@ -95,6 +96,17 @@ func (t *valueTpl) Unpack(in string) error {
9596
return nil
9697
}
9798

99+
type errTerminate struct {
100+
Reason string
101+
}
102+
103+
func (e *errTerminate) Error() string {
104+
if e.Reason != "" {
105+
return "terminated template: " + e.Reason
106+
}
107+
return "terminated template"
108+
}
109+
98110
func (t *valueTpl) Execute(trCtx *transformContext, tr transformable, targetName string, defaultVal *valueTpl, stat status.StatusReporter, log *logp.Logger) (val string, err error) {
99111
fallback := func(err error) (string, error) {
100112
if defaultVal != nil {
@@ -134,6 +146,11 @@ func (t *valueTpl) Execute(trCtx *transformContext, tr transformable, targetName
134146
}
135147

136148
if err := t.Template.Execute(buf, data); err != nil {
149+
var termErr *errTerminate
150+
if errors.As(err, &termErr) {
151+
log.Debugw("template execution terminated", "target", targetName, "reason", termErr.Reason)
152+
return "", nil
153+
}
137154
return fallback(err)
138155
}
139156

x-pack/filebeat/input/httpjson/value_tpl_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ func TestValueTpl(t *testing.T) {
7575
paramDefVal: "25",
7676
expectedVal: "25",
7777
},
78+
{
79+
name: "terminate",
80+
value: `[[if false]]ok[[else]][[terminate "because reasons"]][[end]]`,
81+
paramCtx: emptyTransformContext(),
82+
paramTr: transformable{},
83+
paramDefVal: "this should not be seen",
84+
expectedVal: "",
85+
},
7886
{
7987
name: "returns error if result is empty and no default is set",
8088
value: "",

0 commit comments

Comments
 (0)