public class KvOperator extends Object
The kv (key value) operator extracts key value sequences from a String. By default it uses the '=' to split keys from values, and spaces to delimit the key value pairs form each other.
In short it will work by default with input string likes this:
"name=bob age=22"
Here is an example of using the kv operator:
kv().on("name=bob age=22").into([result]);
produces :
"result": {
"name": "bob",
"age": "22"
}
This operator is subtle and can accommodate complex patterns. In particular
if you give something like
"city=New Delhi country=India"
You will get:
"result": {
"country": "India",
"city": "New Delhi"
},
That is, the match of values does not stop after the first delimiter
encountered, but at the last before the next key. You can change that using
the left()
method.
kv().left().on("city=New Delhi country=India").into([result]);
"result": {
"country": "India",
"city": "New"
}
Also, '"' and ''' are taken care of.
kv().on("city="New Dehli" message="this is a tricky message with = inside").into([result]);
"result" : {
"city" : "New Dehli" ,
"message" : "this is a tricky message with = inside"
}
Make sure you are aware of the escapeJson()
, inferTypes()
, multiKeys()
methods.
Each provides a few advanced but useful capabilities.
name="hello" value=3"
name="hello\" value=3"
name="hello value=3
The second log is ambiguous: the second quote looks like it is escaped. But if it is,
there is a missing quote and the kv operator should fail. The third log is clearly not correct.
The kv strategy consists of accepting the second logs as long as there is a way to isolate each part.
Internally a reverse scan is performed to automatically detect valid escaped regions.
That is the parsing of the second log will yield to
"result" : {
"name" : "hello\" ,
"value" : 3
}
Instead of performing a kv scan and store the result where you need it, you can use the kv operator to simply check that a string has some key value structure. That is useful for dynamically discovering log types.
The match()
, combined with the hasKey(String) or hasKeyWithValue(String, String...) methods.
lets you do that.
Here is an example:
if (kv()
.on([message])
.hasKeyWithValue(\"vendor\", \"cisco\")
.match()) {
// this is a cisco log
}
Modifier and Type | Field and Description |
---|---|
protected static String |
REPLACEMENT
A replacement pattern to be used when escaping.
|
Constructor and Description |
---|
KvOperator()
you can create a KvOperator on the fly, but it is less efficient than
creating one at punchlet activation.
|
KvOperator(String valueSplit,
String fieldSplit)
you can create a Kv operator on the fly, but it is less efficient than
creating one at punchlet activation.
|
Modifier and Type | Method and Description |
---|---|
KvOperator |
debug()
Make the operator print to standard output how the input string is
processed.
|
KvOperator |
disableEscaping()
Disable the escaping that is performed as part of the key value
conversion.
|
KvOperator |
enclosingDelim(String enclosing)
Change the enclosing character.
|
KvOperator |
escapeCharacter(char escapeCharacter)
Allows to escape enclosing delimiters.
|
KvOperator |
escapeJson()
Enable the escaping of json objects and arrays
|
KvOperator |
fieldSplit(String delimiter)
Reset the regex used to delimit key values from each others.
|
KvOperator |
hasKey(String key)
Make the operator work in evaluation mode.
|
KvOperator |
hasKeyWithValue(String key,
String... value)
Make the operator work in evaluation mode.
|
KvOperator |
ignoreEmpty()
Keys with an empty value will not be put into the final Tuple.
|
KvOperator |
inferTypes()
Activate type inference.
|
boolean |
into(Tuple tuple)
Registers a tuple to hold the operator results.
|
KvOperator |
left()
Activate the left search behavior
|
boolean |
match()
This method evaluates many substrings before it gives up.
|
KvOperator |
multiKeys()
Enable a treatment with multiple keys by stacking them in an array
|
KvOperator |
on(String input)
Set the input data for running this operator.
|
KvOperator |
on(Tuple input)
Set the input data for running this operator.
|
KvOperator |
replaceAllKeys(String regex,
String replacement)
Apply a replacement to all generated keys matching substrings.
|
KvOperator |
replaceAllKeyValues(String regex,
String replacement)
|
KvOperator |
replaceAllValues(String regex,
String replacement)
Apply a replacement to all generated keys matching substrings.
|
static String |
restore(String value,
List<KvPortion> portions)
Input strings like "a=\"hello\" b=2" are transformed into "a=@PUNCH@ b=2 in the first
escaping step.
|
KvOperator |
sanitize(String regex)
Sanitize the input string before being submitted to the operator.
|
KvOperator |
trim()
Trim the values, removing starting and trailing '"'
|
KvOperator |
valueSplit(String delimiter)
Reset the regex used to delimit key from values.
|
protected static final String REPLACEMENT
public KvOperator()
public KvOperator(String valueSplit, String fieldSplit)
valueSplit
- the regex used to delimit key from valuesfieldSplit
- the regex used to delimit key value pairs from each other.public KvOperator debug()
public KvOperator left()
public KvOperator disableEscaping()
public KvOperator escapeJson()
public KvOperator ignoreEmpty()
a=b c= d=e
will be returned as (without "c" key):
{ "a": "b", "d": "e" }
public KvOperator multiKeys()
a="hello" a=2 b="world !" a=false
will be converted to{ "a": ["hello", 2, false], "b": "world !" }
public KvOperator inferTypes()
public KvOperator replaceAllKeys(String regex, String replacement)
For example if you have
Tuple result;
kv().replaceAllKeys(" ", "").on("a b"=3 "a c"="hello world").into(result);
You will get result as follows
{ "ab"=3, "ac"="hello world" }
regex
- the regex for matching substringsreplacement
- the replacement stringpublic KvOperator replaceAllValues(String regex, String replacement)
For example if you have
Tuple result;
kv().replaceAllValues(" ", "").on("a b"=3 "a c"="hello world").into(result);
You will get result as follows
{ "a b"=3, "a c"="hello world" }
regex
- the regex to match key substrings to replacereplacement
- the replacement stringpublic KvOperator replaceAllKeyValues(String regex, String replacement)
regex
- the regex for matching substringsreplacement
- the replacement stringpublic KvOperator valueSplit(String delimiter)
I.e. if you have "a==10 b==11', you should use. Remember punch uses java syntax, you must escape your special characters. I.e "\\s" instead of "\s".
kv().valueSplit("==")...
delimiter
- the new delimiter, it must be a valid regex.public KvOperator sanitize(String regex)
kv().on("a='1 b=2'").sanitize("'").into([kv]);
// kv is { "a" : "1 b=2" }
By default, only double quote are considered. That is, the two following statement :
kv().on([message]).sanitize("\"").into([kv]);
is equivalent to :
kv().on([message]).into([kv]);
regex
- the regex used to match delimiterpublic KvOperator trim()
public KvOperator fieldSplit(String delimiter)
I.e. if you have "a=10;b=11', you should use.
kv().fieldSplit(";")...
Remember punch uses java syntax, you must escape your special characters. I.e "\\s" instead of "\s".
delimiter
- the new delimiter, it must be a valid regex.public KvOperator enclosingDelim(String enclosing)
a="hello" b="world !"
enclosing
- the new enclosing characterpublic KvOperator escapeCharacter(char escapeCharacter)
escapeCharacter
- Character to use.public KvOperator on(String input)
input
- the data as a String.public KvOperator on(Tuple input)
input
- the data as a Tuple.public KvOperator hasKeyWithValue(String key, String... value)
key
- the key you look forvalue
- the value(s) you want to match.public KvOperator hasKey(String key)
key
- the key you look forpublic boolean match()
Use in conjunction with hasKey(String) or hasKeyWithValue(String, String...) methods.
public boolean into(Tuple tuple)
tuple
- the tuple for holding resultpublic static String restore(String value, List<KvPortion> portions)
Now it is time to restore the original value from the provided portions.
value
- the provided value, possibly equal to or containing the "@PUNCH@" replacement string.portions
- the list of portions computed in the previous step.Copyright © 2023. All rights reserved.