Skip to content

Commit 09ef0b3

Browse files
committed
x-pack/filebeat/input/httpjson: allow template termination without logging error
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.
1 parent 4cd817e commit 09ef0b3

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
@@ -498,6 +498,7 @@ otherwise no tag is added. {issue}42208[42208] {pull}42403[42403]
498498
- Improve CEL and Streaming input documentation of the `state` option. {pull}45616[45616]
499499
- Enhanced HTTPJSON input error logging with structured error metadata conforming to Elastic Common Schema (ECS) conventions. {pull}45653[45653]
500500
- Clarify behavior in logging for starting periodic evaluations and for exceeding the maximum execution budget. {pull}45633[45633]
501+
- Add mechanism to allow HTTP JSON templates to terminate without logging an error. {issue}45664[45664] {pull}45810[45810]
501502

502503
*Auditbeat*
503504

docs/reference/filebeat/filebeat-input-httpjson.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ Some built-in helper functions are provided to work with the input state inside
221221
* `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`.
222222
* `replaceAll(old, new, s)`: replaces all non-overlapping instances of `old` with `new` in `s`. Example: `[[ replaceAll "some" "my" "some value" ]]` returns `my value`.
223223
* `sprintf`: formats according to a format specifier and returns the resulting string. Refer to [the Go docs](https://pkg.go.dev/fmt#Sprintf) for usage. Example: `[[sprintf "%d:%q" 34 "quote this"]]`
224+
* `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.
224225
* `toInt`: converts a value of any type to an integer when possible. Returns 0 if the conversion fails.
225226
* `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 ]]`.
226227
* `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)