From 17372cc05457cca5b474faefd50899187e5d0040 Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Tue, 1 Jul 2025 10:34:49 +0200 Subject: [PATCH 01/10] Add skeleton --- apl/scalar-functions/array-functions.mdx | 2 ++ .../array-functions/array-sort-asc.mdx | 0 .../array-functions/array-sort-desc.mdx | 0 apl/scalar-functions/string-functions.mdx | 20 ++++++++++++++++++- .../base64-decode-toarray.mdx | 0 .../base64-encode-fromarray.mdx | 0 docs.json | 2 ++ 7 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 apl/scalar-functions/array-functions/array-sort-asc.mdx create mode 100644 apl/scalar-functions/array-functions/array-sort-desc.mdx create mode 100644 apl/scalar-functions/string-functions/base64-decode-toarray.mdx create mode 100644 apl/scalar-functions/string-functions/base64-encode-fromarray.mdx diff --git a/apl/scalar-functions/array-functions.mdx b/apl/scalar-functions/array-functions.mdx index ad29f498..fa07d98f 100644 --- a/apl/scalar-functions/array-functions.mdx +++ b/apl/scalar-functions/array-functions.mdx @@ -21,6 +21,8 @@ The table summarizes the array functions available in APL. | [array_shift_left](/apl/scalar-functions/array-functions/array-shift-left) | Shifts the values inside a dynamic array to the left. | | [array_shift_right](/apl/scalar-functions/array-functions/array-shift-right) | Shifts values inside an array to the right. | | [array_slice](/apl/scalar-functions/array-functions/array-slice) | Extracts a slice of a dynamic array. | +| [array_sort_asc](/apl/scalar-functions/array-functions/array-sort-asc) | Sorts an array in ascending order. | +| [array_sort_desc](/apl/scalar-functions/array-functions/array-sort-desc) | Sorts an array in descending order. | | [array_split](/apl/scalar-functions/array-functions/array-split) | Splits an array to multiple arrays according to the split indices and packs the generated array in a dynamic array. | | [array_sum](/apl/scalar-functions/array-functions/array-sum) | Calculates the sum of elements in a dynamic array. | | [bag_has_key](/apl/scalar-functions/array-functions/bag-has-key) | Checks whether a dynamic property bag contains a specific key. | diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx new file mode 100644 index 00000000..e69de29b diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx new file mode 100644 index 00000000..e69de29b diff --git a/apl/scalar-functions/string-functions.mdx b/apl/scalar-functions/string-functions.mdx index b6d34a6c..79c76bce 100644 --- a/apl/scalar-functions/string-functions.mdx +++ b/apl/scalar-functions/string-functions.mdx @@ -10,8 +10,10 @@ tags: | **Function Name** | **Description** | | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| [base64_encode_tostring()](#base64-encode-tostring) | Encodes a string as base64 string. | +| [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray) | Decodes an array of base64 strings to UTF-8 strings. | | [base64_decode_tostring()](#base64-decode-tostring) | Decodes a base64 string to a UTF-8 string. | +| [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray) | Encodes an array of strings as base64 strings. | +| [base64_encode_tostring()](#base64-encode-tostring) | Encodes a string as base64 string. | | [countof()](#countof) | Counts occurrences of a substring in a string. | | [countof_regex()](#countof-regex) | Counts occurrences of a substring in a string. Regex matches don’t. | | [coalesce()](#coalesce) | Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression. | @@ -41,6 +43,7 @@ tags: | [substring()](#substring) | Extracts a substring from a source string. | | [toupper()](#toupper) | Converts a string to upper case. | | [tolower()](#tolower) | Converts a string to lower case. | +| [totitle()](#totitle) | Converts a string to title case. | | [trim()](#trim) | Removes all leading and trailing matches of the specified cutset. | | [trim_regex()](#trim-regex) | Removes all leading and trailing matches of the specified regular expression. | | [trim_end()](#trim-end) | Removes trailing match of the specified cutset. | @@ -1121,6 +1124,21 @@ tolower("AXIOM") == "axiom" [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20low%20%3D%20tolower%28body%29%22%7D) +## totitle() + +Converts a string to title case. + +```kusto +totitle("axiom") == "Axiom" +``` + +```kusto +['github-issues-event'] +| project low = totitle(body) +``` + +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20low%20%3D%20totitle%28body%29%22%7D) + ## trim() Removes all leading and trailing matches of the specified cutset. diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx new file mode 100644 index 00000000..e69de29b diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs.json b/docs.json index f56221cb..e6793c77 100644 --- a/docs.json +++ b/docs.json @@ -442,6 +442,8 @@ "group": "String functions", "pages": [ "apl/scalar-functions/string-functions", + "apl/scalar-functions/string-functions/base64-decode-toarray", + "apl/scalar-functions/string-functions/base64-encode-fromarray", "apl/scalar-functions/string-functions/indexof_regex", "apl/scalar-functions/string-functions/parse_path", "apl/scalar-functions/string-functions/regex_quote" From e7a90c3cb4df33194d0744751348a55ba3383f5c Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Tue, 1 Jul 2025 10:37:26 +0200 Subject: [PATCH 02/10] Remove () --- apl/scalar-functions/string-functions.mdx | 172 +++++++++++----------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/apl/scalar-functions/string-functions.mdx b/apl/scalar-functions/string-functions.mdx index 79c76bce..2ce4c33e 100644 --- a/apl/scalar-functions/string-functions.mdx +++ b/apl/scalar-functions/string-functions.mdx @@ -11,56 +11,56 @@ tags: | **Function Name** | **Description** | | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray) | Decodes an array of base64 strings to UTF-8 strings. | -| [base64_decode_tostring()](#base64-decode-tostring) | Decodes a base64 string to a UTF-8 string. | +| [base64_decode_tostring](#base64-decode-tostring) | Decodes a base64 string to a UTF-8 string. | | [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray) | Encodes an array of strings as base64 strings. | -| [base64_encode_tostring()](#base64-encode-tostring) | Encodes a string as base64 string. | -| [countof()](#countof) | Counts occurrences of a substring in a string. | -| [countof_regex()](#countof-regex) | Counts occurrences of a substring in a string. Regex matches don’t. | -| [coalesce()](#coalesce) | Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression. | -| [extract()](#extract) | Get a match for a regular expression from a text string. | -| [extract_all()](#extract-all) | Get all matches for a regular expression from a text string. | -| [format_bytes()](#format-bytes) | Formats a number of bytes as a string including bytes units | -| [format_url()](#format-url) | Formats an input string into a valid URL by adding the necessary protocol if it’s escaping illegal URL characters. | -| [indexof()](#indexof) | Function reports the zero-based index of the first occurrence of a specified string within input string. | -| [isempty()](#isempty) | Returns true if the argument is an empty string or is null. | -| [isnotempty()](#isnotempty) | Returns true if the argument isn’t an empty string or a null. | -| [isnotnull()](#isnotnull) | Returns true if the argument is not null. | -| [isnull()](#isnull) | Evaluates its sole argument and returns a bool value indicating if the argument evaluates to a null value. | -| [parse_bytes()](#parse-bytes) | Parses a string including byte size units and returns the number of bytes | -| [parse_json()](#parse-json) | Interprets a string as a JSON value) and returns the value as dynamic. | -| [parse_url()](#parse-url) | Parses an absolute URL string and returns a dynamic object contains all parts of the URL. | -| [parse_urlquery()](#parse-urlquery) | Parses a url query string and returns a dynamic object contains the Query parameters. | -| [replace()](#replace) | Replace all regex matches with another string. | -| [replace_regex()](#replace-regex) | Replaces all regex matches with another string. | -| [replace_string()](#replace-string) | Replaces all string matches with another string. | -| [reverse()](#reverse) | Function makes reverse of input string. | -| [split()](#split) | Splits a given string according to a given delimiter and returns a string array with the contained substrings. | -| [strcat()](#strcat) | Concatenates between 1 and 64 arguments. | -| [strcat_delim()](#strcat-delim) | Concatenates between 2 and 64 arguments, with delimiter, provided as first argument. | -| [strcmp()](#strcmp) | Compares two strings. | -| [strlen()](#strlen) | Returns the length, in characters, of the input string. | -| [strrep()](#strrep) | Repeats given string provided number of times (default = 1). | -| [substring()](#substring) | Extracts a substring from a source string. | -| [toupper()](#toupper) | Converts a string to upper case. | -| [tolower()](#tolower) | Converts a string to lower case. | -| [totitle()](#totitle) | Converts a string to title case. | -| [trim()](#trim) | Removes all leading and trailing matches of the specified cutset. | -| [trim_regex()](#trim-regex) | Removes all leading and trailing matches of the specified regular expression. | -| [trim_end()](#trim-end) | Removes trailing match of the specified cutset. | -| [trim_end_regex()](#trim-end-regex) | Removes trailing match of the specified regular expression. | -| [trim_start()](#trim-start) | Removes leading match of the specified cutset. | -| [trim_start_regex()](#trim-start-regex) | Removes leading match of the specified regular expression. | -| [url_decode()](#url-decode) | The function converts encoded URL into a regular URL representation. | -| [url_encode()](#url-encode) | The function converts characters of the input URL into a format that can be transmitted over the Internet. | -| [gettype()](#gettype) | Returns the runtime type of its single argument. | -| [parse_csv()](#parse-csv) | Splits a given string representing a single record of comma-separated values and returns a string array with these values. | +| [base64_encode_tostring](#base64-encode-tostring) | Encodes a string as base64 string. | +| [countof](#countof) | Counts occurrences of a substring in a string. | +| [countof_regex](#countof-regex) | Counts occurrences of a substring in a string. Regex matches don’t. | +| [coalesce](#coalesce) | Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression. | +| [extract](#extract) | Get a match for a regular expression from a text string. | +| [extract_all](#extract-all) | Get all matches for a regular expression from a text string. | +| [format_bytes](#format-bytes) | Formats a number of bytes as a string including bytes units | +| [format_url](#format-url) | Formats an input string into a valid URL by adding the necessary protocol if it’s escaping illegal URL characters. | +| [indexof](#indexof) | Function reports the zero-based index of the first occurrence of a specified string within input string. | +| [isempty](#isempty) | Returns true if the argument is an empty string or is null. | +| [isnotempty](#isnotempty) | Returns true if the argument isn’t an empty string or a null. | +| [isnotnull](#isnotnull) | Returns true if the argument is not null. | +| [isnull](#isnull) | Evaluates its sole argument and returns a bool value indicating if the argument evaluates to a null value. | +| [parse_bytes](#parse-bytes) | Parses a string including byte size units and returns the number of bytes | +| [parse_json](#parse-json) | Interprets a string as a JSON value) and returns the value as dynamic. | +| [parse_url](#parse-url) | Parses an absolute URL string and returns a dynamic object contains all parts of the URL. | +| [parse_urlquery](#parse-urlquery) | Parses a url query string and returns a dynamic object contains the Query parameters. | +| [replace](#replace) | Replace all regex matches with another string. | +| [replace_regex](#replace-regex) | Replaces all regex matches with another string. | +| [replace_string](#replace-string) | Replaces all string matches with another string. | +| [reverse](#reverse) | Function makes reverse of input string. | +| [split](#split) | Splits a given string according to a given delimiter and returns a string array with the contained substrings. | +| [strcat](#strcat) | Concatenates between 1 and 64 arguments. | +| [strcat_delim](#strcat-delim) | Concatenates between 2 and 64 arguments, with delimiter, provided as first argument. | +| [strcmp](#strcmp) | Compares two strings. | +| [strlen](#strlen) | Returns the length, in characters, of the input string. | +| [strrep](#strrep) | Repeats given string provided number of times (default = 1). | +| [substring](#substring) | Extracts a substring from a source string. | +| [toupper](#toupper) | Converts a string to upper case. | +| [tolower](#tolower) | Converts a string to lower case. | +| [totitle](#totitle) | Converts a string to title case. | +| [trim](#trim) | Removes all leading and trailing matches of the specified cutset. | +| [trim_regex](#trim-regex) | Removes all leading and trailing matches of the specified regular expression. | +| [trim_end](#trim-end) | Removes trailing match of the specified cutset. | +| [trim_end_regex](#trim-end-regex) | Removes trailing match of the specified regular expression. | +| [trim_start](#trim-start) | Removes leading match of the specified cutset. | +| [trim_start_regex](#trim-start-regex) | Removes leading match of the specified regular expression. | +| [url_decode](#url-decode) | The function converts encoded URL into a regular URL representation. | +| [url_encode](#url-encode) | The function converts characters of the input URL into a format that can be transmitted over the Internet. | +| [gettype](#gettype) | Returns the runtime type of its single argument. | +| [parse_csv](#parse-csv) | Splits a given string representing a single record of comma-separated values and returns a string array with these values. | Each argument has a **required** section which is denoted with `required` or `optional` - If it’s denoted by `required` it means the argument must be passed into that function before it'll work. - if it’s denoted by `optional` it means the function can work without passing the argument value. -## base64_encode_tostring() +## base64_encode_tostring Encodes a string as base64 string. @@ -74,7 +74,7 @@ Encodes a string as base64 string. Returns the string encoded as base64 string. -- To decode base64 strings to UTF-8 strings, see [base64_decode_tostring()](#base64-decode-tostring) +- To decode base64 strings to UTF-8 strings, see [base64_decode_tostring](#base64-decode-tostring) ### Examples @@ -89,7 +89,7 @@ base64_encode_tostring(string) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20encoded_base64_string%20%3D%20base64_encode_tostring(content_type)%22%7D) -## base64_decode_tostring() +## base64_decode_tostring Decodes a base64 string to a UTF-8 string. @@ -103,7 +103,7 @@ Decodes a base64 string to a UTF-8 string. Returns UTF-8 string decoded from base64 string. -- To encode strings to base64 string, see [base64_encode_tostring()](#base64-encode-tostring) +- To encode strings to base64 string, see [base64_encode_tostring](#base64-encode-tostring) ### Examples @@ -118,7 +118,7 @@ base64_decode_tostring(string) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20decoded_base64_string%20%3D%20base64_decode_tostring(%5C%22VGhpcyBpcyBhbiBlbmNvZGVkIG1lc3NhZ2Uu%5C%22)%22%7D) -## countof() +## countof Counts occurrences of a substring in a string. @@ -146,7 +146,7 @@ countof(search, text) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20count%20%3D%20countof(%5C%22con%5C%22%2C%20%5C%22content_type%5C%22)%22%7D) -## countof_regex() +## countof_regex Counts occurrences of a substring in a string. regex matches don’t. @@ -172,7 +172,7 @@ countof_regex(regex, text) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20count%20%3D%20countof_regex(%5C%22c.n%5C%22%2C%20%5C%22content_type%5C%22)%22%7D) -## coalesce() +## coalesce Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression. @@ -202,7 +202,7 @@ The value of the first argument whose value isn’t null (or not-empty for strin [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20req_duration_ms%2C%20server_datacenter%2C%20predicate%20%3D%20coalesce(content_type%2C%20method%2C%20status)%22%7D) -## extract() +## extract Retrieve the first substring matching a regular expression from a source string. @@ -239,7 +239,7 @@ extract("x=([0-9.]+)", 1, "axiom x=65.6|po") == "65.6" [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20extract_sub%20%3D%20%20extract(%5C%22x%3D(%5B0-9.%5D%2B)%5C%22%2C%201%2C%20%5C%22axiom%20x%3D65.6%7Cpo%5C%22)%20%3D%3D%20%5C%2265.6%5C%22%22%7D) -## extract_all() +## extract_all Retrieve all substrings matching a regular expression from a source string. Optionally, retrieve only a subset of the matching groups. @@ -282,7 +282,7 @@ extract_all(@"(\w)(\w+)(\w)", dynamic([1,3]), content_type) == [["t", "t"],["c", [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%5Cn%7C%20project%20extract_match%20%3D%20extract_all(%40%5C%22(%5C%5Cw)(%5C%5Cw%2B)(%5C%5Cw)%5C%22%2C%20pack_array()%2C%20content_type)%22%2C%22queryOptions%22%3A%7B%22quickRange%22%3A%2230d%22%7D%7D) -## format_bytes() +## format_bytes Formats a number as a string representing data size in bytes. @@ -320,7 +320,7 @@ format_bytes(8000000, 2, "MB", 10) == "8.00 MB" [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27github-issues-event%27%5D%5Cn%7C%20project%20formated_bytes%20%3D%20format_bytes(4783549035%2C%20number%2C%20%5C%22%5B%27id%27%5D%5C%22%2C%20num_comments)%22%7D) -## format_url() +## format_url Formats an input string into a valid URL. This function will return a string that is a properly formatted URL. @@ -352,7 +352,7 @@ Formats an input string into a valid URL. This function will return a string tha - These are all the supported keys when using the `format_url` function: scheme, host, port, fragment, user, password, query. -## indexof() +## indexof Reports the zero-based index of the first occurrence of a specified string within the input string. @@ -391,7 +391,7 @@ indexof () [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27github-issues-event%27%5D%5Cn%7C%20project%20occurrence%20%3D%20indexof%28%20body%2C%20%5B%27id%27%5D%2C%2023%2C%205%2C%20number%20%29%22%7D) -## isempty() +## isempty Returns `true` if the argument is an empty string or is null. @@ -416,7 +416,7 @@ isempty([value]) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20empty%20%3D%20isempty%28num_comments%29%22%7D) -## isnotempty() +## isnotempty Returns `true` if the argument isn’t an empty string, and it isn’t null. @@ -439,7 +439,7 @@ notempty([value]) -- alias of isnotempty [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20not_empty%20%3D%20isnotempty%28num_comments%29%22%7D) -## isnotnull() +## isnotnull Returns `true` if the argument is not null. @@ -462,7 +462,7 @@ notnull([value]) - alias for `isnotnull` [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20not_null%20%3D%20isnotnull%28num_comments%29%22%7D) -## isnull() +## isnull Evaluates its sole argument and returns a bool value indicating if the argument evaluates to a null value. @@ -483,7 +483,7 @@ isnull(Expr) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20is_null%20%3D%20isnull%28creator%29%22%7D) -## parse_bytes() +## parse_bytes Parses a string including byte size units and returns the number of bytes @@ -526,7 +526,7 @@ parse_bytes("bad data") == 0 [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20parsed_bytes%20%3D%20%20parse_bytes%28%5C%22300%20KB%5C%22%2C%2010%29%22%7D) -## parse_json() +## parse_json Interprets a string as a JSON value and returns the value as dynamic. @@ -563,7 +563,7 @@ parse_json(json) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20extend%20parsed%20%3D%20parse_json%28creator%29%5Cn%7C%20where%20isnotnull%28parsed%29%22%7D) -## parse_url() +## parse_url Parses an absolute URL `string` and returns an object contains `URL parts.` @@ -608,7 +608,7 @@ parse_url(url) } ``` -## parse_urlquery() +## parse_urlquery Returns a `dynamic` object contains the Query parameters. @@ -655,7 +655,7 @@ parse_urlquery(query) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20parsed%20%3D%20parse_urlquery%28%5C%22https%3A%2F%2Fplay.axiom.co%2Faxiom-play-qf1k%2Fexplorer%3Fqid%3DfUKgiQgLjKE-rd7wjy%5C%22%29%22%7D) -## replace() +## replace Replace all regex matches with another string. @@ -682,7 +682,7 @@ replace(regex, rewrite, source) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%5Cn%7C%20project%20content_type%2C%20Comment%20%3D%20replace%28%5C%22%5Bhtml%5D%5C%22%2C%20%5C%22%5Bcensored%5D%5C%22%2C%20method%29%22%7D) -## replace_regex() +## replace_regex Replaces all regex matches with another string. @@ -736,7 +736,7 @@ Backreferences match the same text as previously matched by a capturing group. W [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%20%7C%20project%20backreferences%20%3D%20replace_regex(%40'observability%3D(.%2B)'%2C%20'axiom%3D%241'%2C%20creator)%22%7D) -## replace_string() +## replace_string Replaces all string matches with another string. @@ -778,7 +778,7 @@ replace_string(lookup, rewrite, text) [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%20%22%5B%27sample-http-logs%27%5D%5Cn%7C%20extend%20replaced_string%20%3D%20replace_string%28%27github%27%2C%20%27axiom%27%2C%20%27The%20project%20is%20hosted%20on%20github%27%29%5Cn%7C%20project%20replaced_string%22%7D) -## reverse() +## reverse Function reverses the order of the input Field. @@ -810,7 +810,7 @@ project reversed = reverse("axiom") moixa ``` -## split() +## split Splits a given string according to a given delimiter and returns a string array with the contained substrings. @@ -845,7 +845,7 @@ project split_str = split("axiom_observability_monitoring", "_") } ``` -## strcat() +## strcat Concatenates between 1 and 64 arguments. @@ -889,7 +889,7 @@ strcat(argument1, argument2[, argumentN]) } ``` -## strcat_delim() +## strcat_delim Concatenates between 2 and 64 arguments, with delimiter, provided as first argument. @@ -931,7 +931,7 @@ project strcat = strcat_delim(":", "axiom", "monitoring") } ``` -## strcmp() +## strcmp Compares two strings. @@ -978,7 +978,7 @@ project cmp = strcmp( "axiom", "observability") } ``` -## strlen() +## strlen Returns the length, in characters, of the input string. @@ -1012,7 +1012,7 @@ project str_len = strlen("axiom") } ``` -## strrep() +## strrep Repeats given string provided amount of times. @@ -1057,7 +1057,7 @@ project repeat_string = strrep( "axiom", 3, "::" ) } ``` -## substring() +## substring Extracts a substring from a source string. @@ -1094,7 +1094,7 @@ project extract_string = substring( "axiom", 4, 5 ) } ``` -## toupper() +## toupper Converts a string to upper case. @@ -1109,7 +1109,7 @@ toupper("axiom") == "AXIOM" [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20upper%20%3D%20toupper(%20body%20)%22%7D) -## tolower() +## tolower Converts a string to lower case. @@ -1124,7 +1124,7 @@ tolower("AXIOM") == "axiom" [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20low%20%3D%20tolower%28body%29%22%7D) -## totitle() +## totitle Converts a string to title case. @@ -1139,7 +1139,7 @@ totitle("axiom") == "Axiom" [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20low%20%3D%20totitle%28body%29%22%7D) -## trim() +## trim Removes all leading and trailing matches of the specified cutset. @@ -1177,7 +1177,7 @@ project remove_leading_matches = trim( "axiom", "observability") } ``` -## trim_regex() +## trim_regex Removes all leading and trailing matches of the specified regular expression. @@ -1211,7 +1211,7 @@ trim_regex(regex, source) } ``` -## trim_end() +## trim_end Removes trailing match of the specified cutset. @@ -1245,7 +1245,7 @@ trim_end(source) } ``` -## trim_end_regex() +## trim_end_regex Removes trailing match of the specified regular expression. @@ -1279,7 +1279,7 @@ trim_end_regex(regex, source) } ``` -## trim_start() +## trim_start Removes leading match of the specified cutset. @@ -1312,7 +1312,7 @@ trim_start(source) } ``` -## trim_start_regex() +## trim_start_regex Removes leading match of the specified regular expression. @@ -1346,7 +1346,7 @@ trim_start_regex(regex, source) } ``` -## url_decode() +## url_decode The function converts encoded URL into a to regular URL representation. @@ -1379,7 +1379,7 @@ url_decode(encoded url) } ``` -## url_encode() +## url_encode The function converts characters of the input URL into a format that can be transmitted over the Internet. @@ -1412,7 +1412,7 @@ url_encode(url) } ``` -## gettype() +## gettype Returns the runtime type of its single argument. @@ -1439,7 +1439,7 @@ A string representing the runtime type of its single argument. | gettype(456.98) | **real** | | gettype(parse_json('')) | **null** | -## parse_csv() +## parse_csv Splits a given string representing a single record of comma-separated values and returns a string array with these values. From ad1f502e9279cd8af937f5f4db2a849c4094a977 Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Tue, 1 Jul 2025 10:43:58 +0200 Subject: [PATCH 03/10] Base --- .../array-functions/array-sort-asc.mdx | 313 ++++++++++++++++++ .../array-functions/array-sort-desc.mdx | 157 +++++++++ .../base64-decode-toarray.mdx | 148 +++++++++ .../base64-encode-fromarray.mdx | 162 +++++++++ docs.json | 2 + 5 files changed, 782 insertions(+) diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx index e69de29b..b09dfdf8 100644 --- a/apl/scalar-functions/array-functions/array-sort-asc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-asc.mdx @@ -0,0 +1,313 @@ +--- +title: array_sort_asc +description: 'This page explains how to use the array_sort_asc function in APL.' +--- + +Use the `array_sort_asc` function to return a new array that contains all the elements of the input array, sorted in ascending order. This function is useful when you want to normalize the order of array elements for comparison, presentation, or further processing—such as identifying patterns, comparing sequences, or selecting boundary values. + +You can apply `array_sort_asc` to arrays of numbers, strings, or dynamic objects, making it useful across many telemetry, logging, and security data scenarios. + +## For users of other query languages + +If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. + + + + +In Splunk SPL, arrays are typically handled through `mvsort`, which sorts multivalue fields in ascending order. In APL, `array_sort_asc` provides similar functionality but works on dynamic arrays and returns a new sorted array. + + +```sql Splunk example +| eval sorted_values = mvsort(multivalue_field) +```` + +```kusto APL equivalent +datatable(arr: dynamic) +[ + dynamic([4, 2, 5]) +] +| extend sorted_arr = array_sort_asc(arr) +``` + + + + + + +ANSI SQL does not directly support array data types or array sorting. You typically normalize arrays with `UNNEST` and sort the results using `ORDER BY`. In APL, you can sort arrays inline using `array_sort_asc`, which is more concise and expressive. + + +```sql SQL example +SELECT val +FROM UNNEST([4, 2, 5]) AS val +ORDER BY val ASC +``` + +```kusto APL equivalent +print sorted_arr = array_sort_asc(dynamic([4, 2, 5])) +``` + + + + + + +## Usage + +### Syntax + +```kusto +array_sort_asc(array) +``` + +### Parameters + +| Name | Type | Required | Description | +| ----- | ------- | -------- | ------------------------------------------------------------------------- | +| array | dynamic | ✔️ | An array of values to sort. Can be numbers, strings, or other primitives. | + +### Returns + +A new array that contains the same elements as the input array, sorted in ascending order. If the input is not an array, the function returns an empty array. + +## Use case examples + + + + +Sort request durations in ascending order to analyze latency distributions. + +**Query** + +```kusto +['sample-http-logs'] +| where isnotempty(req_duration_ms) +| summarize durations = make_list(req_duration_ms) +| extend sorted_durations = array_sort_asc(durations) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req\_duration\_ms) %7C summarize durations = make\_list(req\_duration\_ms) %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) + +**Output** + +| durations | sorted\_durations | +| ---------------- | ----------------- | +| \[200, 120, 350] | \[120, 200, 350] | + +The query collects request durations and returns a sorted version of the list to help with percentile or latency threshold analysis. + + + + +Sort span durations to observe timing patterns within a trace group. + +**Query** + +```kusto +['otel-demo-traces'] +| where isnotempty(duration) +| summarize durations = make_list(toint(duration)) by ['service.name'] +| extend sorted_durations = array_sort_asc(durations) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make\_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) + +**Output** + +| service.name | durations | sorted\_durations | +| ------------ | ------------------- | ------------------- | +| frontend | \[3100, 1200, 5600] | \[1200, 3100, 5600] | + +The query shows how span durations for each service are sorted to better analyze processing time distributions. + + + + +Sort HTTP status codes to detect frequency or anomalies in ordered responses. + +**Query** + +```kusto +['sample-http-logs'] +| summarize status_codes = make_list(tolong(status)) by id +| extend sorted_status_codes = array_sort_asc(status_codes) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status\_codes = make\_list(tolong(status)) by id %7C extend sorted\_status\_codes = array\_sort\_asc(status\_codes)%22%7D) + +**Output** + +| id | status\_codes | sorted\_status\_codes | +| ------- | ---------------- | --------------------- | +| user123 | \[500, 200, 404] | \[200, 404, 500] | + +This query helps security analysts quickly review the HTTP status patterns encountered by each user. + + + + +## List of related functions + +* [array\_sort\_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. +* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. +* [make\_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. +* [array\_index\_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. +* [array\_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. +````markdown +--- +title: array_sort_asc +description: 'This page explains how to use the array_sort_asc function in APL.' +--- + +## Introduction + +Use the `array_sort_asc` function to return a new array that contains all the elements of the input array, sorted in ascending order. This function is useful when you want to normalize the order of array elements for comparison, presentation, or further processing—such as identifying patterns, comparing sequences, or selecting boundary values. + +You can apply `array_sort_asc` to arrays of numbers, strings, or dynamic objects, making it useful across many telemetry, logging, and security data scenarios. + +## For users of other query languages + +If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. + + + + +In Splunk SPL, arrays are typically handled through `mvsort`, which sorts multivalue fields in ascending order. In APL, `array_sort_asc` provides similar functionality but works on dynamic arrays and returns a new sorted array. + + +```sql Splunk example +| eval sorted_values = mvsort(multivalue_field) +```` + +```kusto APL equivalent +datatable(arr: dynamic) +[ + dynamic([4, 2, 5]) +] +| extend sorted_arr = array_sort_asc(arr) +``` + + + + + + +ANSI SQL does not directly support array data types or array sorting. You typically normalize arrays with `UNNEST` and sort the results using `ORDER BY`. In APL, you can sort arrays inline using `array_sort_asc`, which is more concise and expressive. + + +```sql SQL example +SELECT val +FROM UNNEST([4, 2, 5]) AS val +ORDER BY val ASC +``` + +```kusto APL equivalent +print sorted_arr = array_sort_asc(dynamic([4, 2, 5])) +``` + + + + + + +## Usage + +### Syntax + +```kusto +array_sort_asc(array) +``` + +### Parameters + +| Name | Type | Required | Description | +| ----- | ------- | -------- | ------------------------------------------------------------------------- | +| array | dynamic | ✔️ | An array of values to sort. Can be numbers, strings, or other primitives. | + +### Returns + +A new array that contains the same elements as the input array, sorted in ascending order. If the input is not an array, the function returns an empty array. + +## Use case examples + + + + +Sort request durations in ascending order to analyze latency distributions. + +**Query** + +```kusto +['sample-http-logs'] +| where isnotempty(req_duration_ms) +| summarize durations = make_list(req_duration_ms) +| extend sorted_durations = array_sort_asc(durations) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req\_duration\_ms) %7C summarize durations = make\_list(req\_duration\_ms) %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) + +**Output** + +| durations | sorted\_durations | +| ---------------- | ----------------- | +| \[200, 120, 350] | \[120, 200, 350] | + +The query collects request durations and returns a sorted version of the list to help with percentile or latency threshold analysis. + + + + +Sort span durations to observe timing patterns within a trace group. + +**Query** + +```kusto +['otel-demo-traces'] +| where isnotempty(duration) +| summarize durations = make_list(toint(duration)) by ['service.name'] +| extend sorted_durations = array_sort_asc(durations) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make\_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) + +**Output** + +| service.name | durations | sorted\_durations | +| ------------ | ------------------- | ------------------- | +| frontend | \[3100, 1200, 5600] | \[1200, 3100, 5600] | + +The query shows how span durations for each service are sorted to better analyze processing time distributions. + + + + +Sort HTTP status codes to detect frequency or anomalies in ordered responses. + +**Query** + +```kusto +['sample-http-logs'] +| summarize status_codes = make_list(tolong(status)) by id +| extend sorted_status_codes = array_sort_asc(status_codes) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status\_codes = make\_list(tolong(status)) by id %7C extend sorted\_status\_codes = array\_sort\_asc(status\_codes)%22%7D) + +**Output** + +| id | status\_codes | sorted\_status\_codes | +| ------- | ---------------- | --------------------- | +| user123 | \[500, 200, 404] | \[200, 404, 500] | + +This query helps security analysts quickly review the HTTP status patterns encountered by each user. + + + + +## List of related functions + +* [array\_sort\_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. +* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. +* [make\_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. +* [array\_index\_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. +* [array\_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx index e69de29b..8d29dcb1 100644 --- a/apl/scalar-functions/array-functions/array-sort-desc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx @@ -0,0 +1,157 @@ +--- +title: array_sort_desc +description: 'This page explains how to use the array_sort_desc function in APL.' +--- + +Use the `array_sort_desc` function in APL to sort the elements of an array in descending order. This function is especially useful when working with numerical data or categorical data where you want to prioritize higher values first—such as showing the longest durations, highest response times, or most severe error codes at the top of an array. + +You can use `array_sort_desc` in scenarios where ordering matters within grouped aggregations, such as collecting response times per user or span durations per trace, and then sorting them to identify the highest or most impactful values. + +## For users of other query languages + +If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. + + + + +Splunk does not have a direct equivalent to `array_sort_desc`, but similar outcomes can be achieved using `mvsort` with a custom sort order (and sometimes `reverse`). In APL, `array_sort_desc` explicitly performs a descending sort on array elements, making it more straightforward. + + +```sql Splunk example +... | stats list(duration) as durations by id +... | eval durations=reverse(mvsort(durations)) +```` + +```kusto APL equivalent +['otel-demo-traces'] +| summarize durations=make_list(duration) by trace_id +| extend durations=array_sort_desc(durations) +``` + + + + + + +ANSI SQL does not support arrays or array functions natively. You typically use window functions or subqueries to order values. In APL, you can work with arrays directly and apply `array_sort_desc` to sort them. + + +```sql SQL example +SELECT trace_id, ARRAY_AGG(duration ORDER BY duration DESC) AS durations +FROM traces +GROUP BY trace_id; +``` + +```kusto APL equivalent +['otel-demo-traces'] +| summarize durations=make_list(duration) by trace_id +| extend durations=array_sort_desc(durations) +``` + + + + + + +## Usage + +### Syntax + +```kusto +array_sort_desc(array) +``` + +### Parameters + +| Name | Type | Required | Description | +| ----- | ----- | -------- | ----------------------------------------------------- | +| array | array | ✔️ | The input array whose elements are sorted descending. | + +### Returns + +If the input is a valid array, the function returns a new array with its elements sorted in descending order. If the array is empty or contains incompatible types, it returns an empty array. + +## Use case examples + + + + +Use this function to identify the slowest request durations per user from HTTP logs. + +**Query** + +```kusto +['sample-http-logs'] +| summarize durations=make_list(req_duration_ms) by id +| extend top_durations=array_sort_desc(durations) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize durations%3Dmake\_list(req\_duration\_ms) by id %7C extend top\_durations%3Darray\_sort\_desc(durations)%22%7D) + +**Output** + +| id | durations | top\_durations | +| ------ | ------------------- | ------------------- | +| user-1 | \[104, 87, 129, 46] | \[129, 104, 87, 46] | +| user-2 | \[80, 120, 98] | \[120, 98, 80] | + +The query collects request durations per user and then sorts them so the longest durations appear first. + + + + +Use this function to sort span durations per trace to find the slowest spans. + +**Query** + +```kusto +['otel-demo-traces'] +| summarize durations=make_list(duration) by trace_id +| extend sorted_durations=array_sort_desc(durations) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D) %7C summarize durations%3Dmake\_list(duration) by trace\_id %7C extend sorted\_durations%3Darray\_sort\_desc(durations)%22%7D) + +**Output** + +| trace\_id | durations | sorted\_durations | +| --------- | -------------------------- | -------------------------- | +| abcd1234 | \[120ms, 80ms, 300ms] | \[300ms, 120ms, 80ms] | +| efgh5678 | \[60ms, 45ms, 100ms, 30ms] | \[100ms, 60ms, 45ms, 30ms] | + +The query organizes span durations from highest to lowest for each trace to help detect performance bottlenecks. + + + + +Use this function to sort the status codes associated with user activity to identify abnormal patterns (e.g. many 500 errors). + +**Query** + +```kusto +['sample-http-logs'] +| summarize status_codes=make_list(tolong(status)) by id +| extend sorted_status=array_sort_desc(status_codes) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize status\_codes%3Dmake\_list(tolong(status)) by id %7C extend sorted\_status%3Darray\_sort\_desc(status\_codes)%22%7D) + +**Output** + +| id | status\_codes | sorted\_status | +| ------ | --------------------- | --------------------- | +| user-1 | \[200, 403, 500] | \[500, 403, 200] | +| user-2 | \[404, 200, 404, 401] | \[404, 404, 401, 200] | + +The query helps investigate accounts generating frequent errors or suspicious patterns based on HTTP status codes. + + + + +## List of related functions + +* [array\_sort\_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. +* [make\_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Use it to create arrays before applying `array_sort_desc`. +* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. +* [array\_slice](/apl/array-functions/array_slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. +* [array\_index\_of](/apl/array-functions/array_index_of): Returns the index of a value in an array. Useful after sorting to locate specific elements. diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx index e69de29b..9bc4a319 100644 --- a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx +++ b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx @@ -0,0 +1,148 @@ +--- +title: base64_decode_toarray +description: 'This page explains how to use the base64_decode_toarray function in APL.' +--- + +Use the `base64_decode_toarray` function to decode a Base64-encoded string into an array of bytes. This is especially useful when you need to extract raw binary data from encoded inputs, such as network payloads, authentication tokens, or structured log fields. You can then transform or analyze the resulting byte array using additional APL functions like `array_slice`, `array_length`, or `array_index`. + +This function is useful in scenarios where logs or telemetry data include fields that store binary data encoded as Base64, which is common for compact transmission or obfuscation. By decoding these values into byte arrays, you gain visibility into the underlying structure of the data. + +## For users of other query languages + +If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. + + + + +In Splunk SPL, decoding Base64 requires using `eval` with the `base64decode` function, which returns a string. If you need a byte array representation, you must manually transform it. In APL, `base64_decode_toarray` directly produces an array of bytes, allowing you to work with binary data more precisely. + + +```sql Splunk example +| eval decoded=base64decode(encodedField) +```` + +```kusto APL equivalent +['my-dataset'] +| extend decoded = base64_decode_toarray(encodedField) +``` + + + + + + +Standard ANSI SQL doesn’t include a native function to decode Base64 into byte arrays. You typically need to rely on a UDF or cast the result into `VARBINARY` if the engine supports it. APL provides a built-in function that directly yields an array of integers representing bytes. + + +```sql SQL example +SELECT CAST(FROM_BASE64(encodedField) AS BINARY) FROM my_table; +``` + +```kusto APL equivalent +['my-dataset'] +| extend decoded = base64_decode_toarray(encodedField) +``` + + + + + + +## Usage + +### Syntax + +```kusto +base64_decode_toarray(base64_input) +``` + +### Parameters + +| Name | Type | Required | Description | +| ------------- | ------ | -------- | --------------------------------------------------------------- | +| base64\_input | string | ✔️ | A Base64-encoded string. The input string must be valid Base64. | + +### Returns + +An array of integers representing the decoded byte values. If the input string is not valid Base64, the function returns an empty array. + +## Use case examples + + + + +You want to decode a Base64-encoded field in logs to inspect raw payloads for debugging or transformation. + +**Query** + +```kusto +['sample-http-logs'] +| extend raw = base64_decode_toarray('aGVsbG8gd29ybGQ=') +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C extend raw%20%3D%20base64\_decode\_toarray%28%27aGVsbG8gd29ybGQ%3D%27%29%22%7D) + +**Output** + +| raw | +| ------------------------------------------------------- | +| \[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] | + +This query decodes the Base64 string `'aGVsbG8gd29ybGQ='`, which represents the ASCII string `"hello world"`, into an array of byte values. + + + + +You receive Base64-encoded trace IDs from an external system and want to decode them for low-level correlation. + +**Query** + +```kusto +['otel-demo-traces'] +| extend trace_bytes = base64_decode_toarray(trace_id) +| project ['otel-demo-traces'], trace_id, trace_bytes +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C extend trace\_bytes%20%3D%20base64\_decode\_toarray%28trace\_id%29 %7C project%20%5B%27otel-demo-traces%27%5D%2C%20trace\_id%2C%20trace\_bytes%22%7D) + +**Output** + +| trace\_id | trace\_bytes | +| -------------------- | -------------------------------------------------------------- | +| dHJhY2UtaWQtZGVtbw== | \[116, 114, 97, 99, 101, 45, 105, 100, 45, 100, 101, 109, 111] | + +This query decodes the trace ID from Base64 into its byte-level representation for internal processing or fingerprinting. + + + + +A security event includes a Base64-encoded payload that you want to decode and inspect for signature verification. + +**Query** + +```kusto +['sample-http-logs'] +| where status == '401' +| extend payload = base64_decode_toarray(id) +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where%20status%20%3D%3D%20%27401%27 %7C extend%20payload%20%3D%20base64\_decode\_toarray%28id%29%22%7D) + +**Output** + +| id | payload | +| ------------ | ---------------------------------------- | +| ZHVtbXkgaWQ= | \[100, 117, 109, 109, 121, 32, 105, 100] | + +This query filters failed authorization attempts and decodes the `id` field, which is Base64-encoded, into its original byte array for forensic inspection. + + + + +## List of related functions + +* [base64\_decode\_tostring](/apl/string-functions/base64_decode_tostring): Decodes a Base64-encoded string into its UTF-8 text form. Use when you want a decoded string instead of raw bytes. +* [parse\_json](/apl/string-functions/parse_json): Converts a string containing JSON into a dynamic object. Use after decoding Base64 if the result is structured data. +* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use after decoding to validate payload length. +* [array\_index](/apl/array-functions/array_index): Retrieves a value at a specific index of an array. Use to inspect specific bytes after decoding. +* [array\_slice](/apl/array-functions/array_slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx index e69de29b..852438b9 100644 --- a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx +++ b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx @@ -0,0 +1,162 @@ +--- +title: base64_encode_fromarray +description: 'This page explains how to use the base64_encode_fromarray function in APL.' +--- + +Use the `base64_encode_fromarray` function to convert a sequence of bytes into a Base64-encoded string. This function is useful when you need to transform binary data into a textual representation for safe storage, logging, or transmission—especially over protocols that require plain-text formats. + +You can apply this function when working with IP addresses, file contents, or any byte array that needs to be encoded for use in logs or APIs. It accepts a byte array and returns the Base64-encoded string representation of that array. + +## For users of other query languages + +If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. + + + + +Splunk doesn’t provide a native function to directly encode an array of bytes into Base64 in SPL. You would typically write a custom script using an external command or use `eval` with a helper function in an app context. + + +```sql Splunk example +| eval encoded=custom_base64_encode(byte_array_field) +```` + +```kusto APL equivalent +datatable(bytes: dynamic) +[ + dynamic([192, 168, 1, 1]) +] +| extend encoded = base64_encode_fromarray(bytes) +``` + + + + + + +ANSI SQL doesn’t define a built-in standard for Base64 encoding from an array of bytes. This is usually handled via vendor-specific functions (e.g., `TO_BASE64()` in MySQL, or `encode()` in PostgreSQL). + + +```sql SQL example +SELECT TO_BASE64(BINARY 'data') AS encoded; +``` + +```kusto APL equivalent +datatable(bytes: dynamic) +[ + dynamic([192, 168, 1, 1]) +] +| extend encoded = base64_encode_fromarray(bytes) +``` + + + + + + +## Usage + +### Syntax + +```kusto +base64_encode_fromarray(array) +``` + +### Parameters + +| Name | Type | Required | Description | +| ----- | ------- | -------- | ----------------------------------------------------------------------- | +| array | dynamic | ✔️ | A dynamic array of integers between 0 and 255 representing byte values. | + +### Returns + +If successful, returns a string representing the Base64-encoded version of the input byte array. If the input is not a valid array of bytes, the result is an empty string. + +## Use case examples + + + + +Use this function to encode request metadata for logging or comparison with external systems that require Base64-encoded fields. + +**Query** + +```kusto +['sample-http-logs'] +| extend ip_bytes = dynamic([192, 168, 0, 1]) +| extend encoded_ip = base64_encode_fromarray(ip_bytes) +| project _time, id, method, uri, encoded_ip +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend ip\_bytes = dynamic(\[192, 168, 0, 1]) | extend encoded\_ip = base64\_encode\_fromarray(ip\_bytes) | project \_time, id, method, uri, encoded\_ip%22%7D) + +**Output** + +| \_time | id | method | uri | encoded\_ip | +| -------------------- | ------- | ------ | --------- | ----------- | +| 2025-06-25T08:00:00Z | user123 | GET | /api/data | wKgA | + +Encodes a hardcoded byte representation of an IP address into Base64 for easy string-based comparison or logging. + + + + +Encode trace identifiers or service-specific byte arrays into Base64 for downstream ingestion or correlation. + +**Query** + +```kusto +['otel-demo-traces'] +| extend trace_id_bytes = extract_all(@'..', trace_id) +| extend trace_id_array = range(0, strlen(trace_id)-1) + | extend val = toint(strcat('0x', substring(trace_id, index*2, 2))) + | summarize make_list(val) +| extend encoded_trace_id = base64_encode_fromarray(trace_id_array) +| project _time, trace_id, ['service.name'], encoded_trace_id +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) | extend trace\_id\_bytes = extract\_all(@%27..%27, trace\_id) | extend trace\_id\_array = range(0, strlen(trace\_id)-1) | extend val = toint(strcat(%270x%27, substring(trace\_id, index\*2, 2))) | summarize make\_list(val) | extend encoded\_trace\_id = base64\_encode\_fromarray(trace\_id\_array) | project \_time, trace\_id, \['service.name'], encoded\_trace\_id%22%7D) + +**Output** + +| \_time | trace\_id | \['service.name'] | encoded\_trace\_id | +| -------------------- | -------------------------------- | ----------------- | ------------------------ | +| 2025-06-25T08:00:00Z | f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6 | checkoutservice | 8aKyxNXm96i5wNHi86S1xg== | + +Transforms a trace ID into a Base64-encoded string to support interop with telemetry pipelines or identifiers stored in external formats. + + + + +Encode sensitive session IDs or IP addresses before storing them in logs or comparing across systems that use Base64 formats. + +**Query** + +```kusto +['sample-http-logs'] +| extend session_bytes = dynamic([10, 20, 30, 40]) +| extend session_token = base64_encode_fromarray(session_bytes) +| where status == '403' +| project _time, id, uri, session_token +``` + +\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend session\_bytes = dynamic(\[10, 20, 30, 40]) | extend session\_token = base64\_encode\_fromarray(session\_bytes) | where status == %27403%27 | project \_time, id, uri, session\_token%22%7D) + +**Output** + +| \_time | id | uri | session\_token | +| -------------------- | ------- | ------------ | -------------- | +| 2025-06-25T09:12:00Z | user456 | /admin/panel | ChQeKA== | + +Encodes a mock session ID into Base64 format before logging it, helping to anonymize sensitive information while preserving structure. + + + + +## List of related functions + +* [base64\_decode\_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. +* [format\_ipv4\_mask](/apl/ip-functions/format_ipv4_mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. +* [tostring](/apl/type-functions/tostring): Converts a dynamic value into a string. Use it for general-purpose conversions, but not for Base64 encoding. +* [parse\_ipv4](/apl/ip-functions/parse_ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. +* [array\_concat](/apl/array-functions/array_concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. diff --git a/docs.json b/docs.json index e6793c77..7a9a5d72 100644 --- a/docs.json +++ b/docs.json @@ -368,6 +368,8 @@ "apl/scalar-functions/array-functions/array-shift-left", "apl/scalar-functions/array-functions/array-shift-right", "apl/scalar-functions/array-functions/array-slice", + "apl/scalar-functions/array-functions/array-sort-asc", + "apl/scalar-functions/array-functions/array-sort-desc", "apl/scalar-functions/array-functions/array-split", "apl/scalar-functions/array-functions/array-sum", "apl/scalar-functions/array-functions/bag-has-key", From 3960f7c0803cd8097b02f6e74b5cd67b5b384de5 Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Tue, 1 Jul 2025 10:45:02 +0200 Subject: [PATCH 04/10] Remove \ --- .../array-functions/array-sort-asc.mdx | 56 +++++++++---------- .../array-functions/array-sort-desc.mdx | 34 +++++------ .../base64-decode-toarray.mdx | 26 ++++----- .../base64-encode-fromarray.mdx | 20 +++---- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx index b09dfdf8..8a6f2d15 100644 --- a/apl/scalar-functions/array-functions/array-sort-asc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-asc.mdx @@ -86,13 +86,13 @@ Sort request durations in ascending order to analyze latency distributions. | extend sorted_durations = array_sort_asc(durations) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req\_duration\_ms) %7C summarize durations = make\_list(req\_duration\_ms) %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req_duration_ms) %7C summarize durations = make_list(req_duration_ms) %7C extend sorted_durations = array_sort_asc(durations)%22%7D) **Output** -| durations | sorted\_durations | +| durations | sorted_durations | | ---------------- | ----------------- | -| \[200, 120, 350] | \[120, 200, 350] | +| [200, 120, 350] | [120, 200, 350] | The query collects request durations and returns a sorted version of the list to help with percentile or latency threshold analysis. @@ -110,13 +110,13 @@ Sort span durations to observe timing patterns within a trace group. | extend sorted_durations = array_sort_asc(durations) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make\_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted_durations = array_sort_asc(durations)%22%7D) **Output** -| service.name | durations | sorted\_durations | +| service.name | durations | sorted_durations | | ------------ | ------------------- | ------------------- | -| frontend | \[3100, 1200, 5600] | \[1200, 3100, 5600] | +| frontend | [3100, 1200, 5600] | [1200, 3100, 5600] | The query shows how span durations for each service are sorted to better analyze processing time distributions. @@ -133,13 +133,13 @@ Sort HTTP status codes to detect frequency or anomalies in ordered responses. | extend sorted_status_codes = array_sort_asc(status_codes) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status\_codes = make\_list(tolong(status)) by id %7C extend sorted\_status\_codes = array\_sort\_asc(status\_codes)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status_codes = make_list(tolong(status)) by id %7C extend sorted_status_codes = array_sort_asc(status_codes)%22%7D) **Output** -| id | status\_codes | sorted\_status\_codes | +| id | status_codes | sorted_status_codes | | ------- | ---------------- | --------------------- | -| user123 | \[500, 200, 404] | \[200, 404, 500] | +| user123 | [500, 200, 404] | [200, 404, 500] | This query helps security analysts quickly review the HTTP status patterns encountered by each user. @@ -148,11 +148,11 @@ This query helps security analysts quickly review the HTTP status patterns encou ## List of related functions -* [array\_sort\_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. -* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. -* [make\_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. -* [array\_index\_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. -* [array\_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. +* [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. +* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. +* [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. +* [array_index_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. +* [array_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. ````markdown --- title: array_sort_asc @@ -244,13 +244,13 @@ Sort request durations in ascending order to analyze latency distributions. | extend sorted_durations = array_sort_asc(durations) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req\_duration\_ms) %7C summarize durations = make\_list(req\_duration\_ms) %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req_duration_ms) %7C summarize durations = make_list(req_duration_ms) %7C extend sorted_durations = array_sort_asc(durations)%22%7D) **Output** -| durations | sorted\_durations | +| durations | sorted_durations | | ---------------- | ----------------- | -| \[200, 120, 350] | \[120, 200, 350] | +| [200, 120, 350] | [120, 200, 350] | The query collects request durations and returns a sorted version of the list to help with percentile or latency threshold analysis. @@ -268,13 +268,13 @@ Sort span durations to observe timing patterns within a trace group. | extend sorted_durations = array_sort_asc(durations) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make\_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted\_durations = array\_sort\_asc(durations)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted_durations = array_sort_asc(durations)%22%7D) **Output** -| service.name | durations | sorted\_durations | +| service.name | durations | sorted_durations | | ------------ | ------------------- | ------------------- | -| frontend | \[3100, 1200, 5600] | \[1200, 3100, 5600] | +| frontend | [3100, 1200, 5600] | [1200, 3100, 5600] | The query shows how span durations for each service are sorted to better analyze processing time distributions. @@ -291,13 +291,13 @@ Sort HTTP status codes to detect frequency or anomalies in ordered responses. | extend sorted_status_codes = array_sort_asc(status_codes) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status\_codes = make\_list(tolong(status)) by id %7C extend sorted\_status\_codes = array\_sort\_asc(status\_codes)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status_codes = make_list(tolong(status)) by id %7C extend sorted_status_codes = array_sort_asc(status_codes)%22%7D) **Output** -| id | status\_codes | sorted\_status\_codes | +| id | status_codes | sorted_status_codes | | ------- | ---------------- | --------------------- | -| user123 | \[500, 200, 404] | \[200, 404, 500] | +| user123 | [500, 200, 404] | [200, 404, 500] | This query helps security analysts quickly review the HTTP status patterns encountered by each user. @@ -306,8 +306,8 @@ This query helps security analysts quickly review the HTTP status patterns encou ## List of related functions -* [array\_sort\_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. -* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. -* [make\_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. -* [array\_index\_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. -* [array\_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. +* [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. +* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. +* [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. +* [array_index_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. +* [array_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx index 8d29dcb1..f7ef1d72 100644 --- a/apl/scalar-functions/array-functions/array-sort-desc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx @@ -86,14 +86,14 @@ Use this function to identify the slowest request durations per user from HTTP l | extend top_durations=array_sort_desc(durations) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize durations%3Dmake\_list(req\_duration\_ms) by id %7C extend top\_durations%3Darray\_sort\_desc(durations)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize durations%3Dmake_list(req_duration_ms) by id %7C extend top_durations%3Darray_sort_desc(durations)%22%7D) **Output** -| id | durations | top\_durations | +| id | durations | top_durations | | ------ | ------------------- | ------------------- | -| user-1 | \[104, 87, 129, 46] | \[129, 104, 87, 46] | -| user-2 | \[80, 120, 98] | \[120, 98, 80] | +| user-1 | [104, 87, 129, 46] | [129, 104, 87, 46] | +| user-2 | [80, 120, 98] | [120, 98, 80] | The query collects request durations per user and then sorts them so the longest durations appear first. @@ -110,14 +110,14 @@ Use this function to sort span durations per trace to find the slowest spans. | extend sorted_durations=array_sort_desc(durations) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D) %7C summarize durations%3Dmake\_list(duration) by trace\_id %7C extend sorted\_durations%3Darray\_sort\_desc(durations)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D) %7C summarize durations%3Dmake_list(duration) by trace_id %7C extend sorted_durations%3Darray_sort_desc(durations)%22%7D) **Output** -| trace\_id | durations | sorted\_durations | +| trace_id | durations | sorted_durations | | --------- | -------------------------- | -------------------------- | -| abcd1234 | \[120ms, 80ms, 300ms] | \[300ms, 120ms, 80ms] | -| efgh5678 | \[60ms, 45ms, 100ms, 30ms] | \[100ms, 60ms, 45ms, 30ms] | +| abcd1234 | [120ms, 80ms, 300ms] | [300ms, 120ms, 80ms] | +| efgh5678 | [60ms, 45ms, 100ms, 30ms] | [100ms, 60ms, 45ms, 30ms] | The query organizes span durations from highest to lowest for each trace to help detect performance bottlenecks. @@ -134,14 +134,14 @@ Use this function to sort the status codes associated with user activity to iden | extend sorted_status=array_sort_desc(status_codes) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize status\_codes%3Dmake\_list(tolong(status)) by id %7C extend sorted\_status%3Darray\_sort\_desc(status\_codes)%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize status_codes%3Dmake_list(tolong(status)) by id %7C extend sorted_status%3Darray_sort_desc(status_codes)%22%7D) **Output** -| id | status\_codes | sorted\_status | +| id | status_codes | sorted_status | | ------ | --------------------- | --------------------- | -| user-1 | \[200, 403, 500] | \[500, 403, 200] | -| user-2 | \[404, 200, 404, 401] | \[404, 404, 401, 200] | +| user-1 | [200, 403, 500] | [500, 403, 200] | +| user-2 | [404, 200, 404, 401] | [404, 404, 401, 200] | The query helps investigate accounts generating frequent errors or suspicious patterns based on HTTP status codes. @@ -150,8 +150,8 @@ The query helps investigate accounts generating frequent errors or suspicious pa ## List of related functions -* [array\_sort\_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. -* [make\_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Use it to create arrays before applying `array_sort_desc`. -* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. -* [array\_slice](/apl/array-functions/array_slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. -* [array\_index\_of](/apl/array-functions/array_index_of): Returns the index of a value in an array. Useful after sorting to locate specific elements. +* [array_sort_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. +* [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Use it to create arrays before applying `array_sort_desc`. +* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. +* [array_slice](/apl/array-functions/array_slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. +* [array_index_of](/apl/array-functions/array_index_of): Returns the index of a value in an array. Useful after sorting to locate specific elements. diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx index 9bc4a319..e40e49d6 100644 --- a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx +++ b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx @@ -60,7 +60,7 @@ base64_decode_toarray(base64_input) | Name | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------- | -| base64\_input | string | ✔️ | A Base64-encoded string. The input string must be valid Base64. | +| base64_input | string | ✔️ | A Base64-encoded string. The input string must be valid Base64. | ### Returns @@ -80,13 +80,13 @@ You want to decode a Base64-encoded field in logs to inspect raw payloads for de | extend raw = base64_decode_toarray('aGVsbG8gd29ybGQ=') ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C extend raw%20%3D%20base64\_decode\_toarray%28%27aGVsbG8gd29ybGQ%3D%27%29%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C extend raw%20%3D%20base64_decode_toarray%28%27aGVsbG8gd29ybGQ%3D%27%29%22%7D) **Output** | raw | | ------------------------------------------------------- | -| \[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] | +| [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] | This query decodes the Base64 string `'aGVsbG8gd29ybGQ='`, which represents the ASCII string `"hello world"`, into an array of byte values. @@ -103,13 +103,13 @@ You receive Base64-encoded trace IDs from an external system and want to decode | project ['otel-demo-traces'], trace_id, trace_bytes ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C extend trace\_bytes%20%3D%20base64\_decode\_toarray%28trace\_id%29 %7C project%20%5B%27otel-demo-traces%27%5D%2C%20trace\_id%2C%20trace\_bytes%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C extend trace_bytes%20%3D%20base64_decode_toarray%28trace_id%29 %7C project%20%5B%27otel-demo-traces%27%5D%2C%20trace_id%2C%20trace_bytes%22%7D) **Output** -| trace\_id | trace\_bytes | +| trace_id | trace_bytes | | -------------------- | -------------------------------------------------------------- | -| dHJhY2UtaWQtZGVtbw== | \[116, 114, 97, 99, 101, 45, 105, 100, 45, 100, 101, 109, 111] | +| dHJhY2UtaWQtZGVtbw== | [116, 114, 97, 99, 101, 45, 105, 100, 45, 100, 101, 109, 111] | This query decodes the trace ID from Base64 into its byte-level representation for internal processing or fingerprinting. @@ -126,13 +126,13 @@ A security event includes a Base64-encoded payload that you want to decode and i | extend payload = base64_decode_toarray(id) ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where%20status%20%3D%3D%20%27401%27 %7C extend%20payload%20%3D%20base64\_decode\_toarray%28id%29%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where%20status%20%3D%3D%20%27401%27 %7C extend%20payload%20%3D%20base64_decode_toarray%28id%29%22%7D) **Output** | id | payload | | ------------ | ---------------------------------------- | -| ZHVtbXkgaWQ= | \[100, 117, 109, 109, 121, 32, 105, 100] | +| ZHVtbXkgaWQ= | [100, 117, 109, 109, 121, 32, 105, 100] | This query filters failed authorization attempts and decodes the `id` field, which is Base64-encoded, into its original byte array for forensic inspection. @@ -141,8 +141,8 @@ This query filters failed authorization attempts and decodes the `id` field, whi ## List of related functions -* [base64\_decode\_tostring](/apl/string-functions/base64_decode_tostring): Decodes a Base64-encoded string into its UTF-8 text form. Use when you want a decoded string instead of raw bytes. -* [parse\_json](/apl/string-functions/parse_json): Converts a string containing JSON into a dynamic object. Use after decoding Base64 if the result is structured data. -* [array\_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use after decoding to validate payload length. -* [array\_index](/apl/array-functions/array_index): Retrieves a value at a specific index of an array. Use to inspect specific bytes after decoding. -* [array\_slice](/apl/array-functions/array_slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. +* [base64_decode_tostring](/apl/string-functions/base64_decode_tostring): Decodes a Base64-encoded string into its UTF-8 text form. Use when you want a decoded string instead of raw bytes. +* [parse_json](/apl/string-functions/parse_json): Converts a string containing JSON into a dynamic object. Use after decoding Base64 if the result is structured data. +* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use after decoding to validate payload length. +* [array_index](/apl/array-functions/array_index): Retrieves a value at a specific index of an array. Use to inspect specific bytes after decoding. +* [array_slice](/apl/array-functions/array_slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx index 852438b9..b69c2b1f 100644 --- a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx +++ b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx @@ -88,11 +88,11 @@ Use this function to encode request metadata for logging or comparison with exte | project _time, id, method, uri, encoded_ip ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend ip\_bytes = dynamic(\[192, 168, 0, 1]) | extend encoded\_ip = base64\_encode\_fromarray(ip\_bytes) | project \_time, id, method, uri, encoded\_ip%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend ip_bytes = dynamic([192, 168, 0, 1]) | extend encoded_ip = base64_encode_fromarray(ip_bytes) | project _time, id, method, uri, encoded_ip%22%7D) **Output** -| \_time | id | method | uri | encoded\_ip | +| _time | id | method | uri | encoded_ip | | -------------------- | ------- | ------ | --------- | ----------- | | 2025-06-25T08:00:00Z | user123 | GET | /api/data | wKgA | @@ -115,11 +115,11 @@ Encode trace identifiers or service-specific byte arrays into Base64 for downstr | project _time, trace_id, ['service.name'], encoded_trace_id ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) | extend trace\_id\_bytes = extract\_all(@%27..%27, trace\_id) | extend trace\_id\_array = range(0, strlen(trace\_id)-1) | extend val = toint(strcat(%270x%27, substring(trace\_id, index\*2, 2))) | summarize make\_list(val) | extend encoded\_trace\_id = base64\_encode\_fromarray(trace\_id\_array) | project \_time, trace\_id, \['service.name'], encoded\_trace\_id%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) | extend trace_id_bytes = extract_all(@%27..%27, trace_id) | extend trace_id_array = range(0, strlen(trace_id)-1) | extend val = toint(strcat(%270x%27, substring(trace_id, index*2, 2))) | summarize make_list(val) | extend encoded_trace_id = base64_encode_fromarray(trace_id_array) | project _time, trace_id, ['service.name'], encoded_trace_id%22%7D) **Output** -| \_time | trace\_id | \['service.name'] | encoded\_trace\_id | +| _time | trace_id | ['service.name'] | encoded_trace_id | | -------------------- | -------------------------------- | ----------------- | ------------------------ | | 2025-06-25T08:00:00Z | f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6 | checkoutservice | 8aKyxNXm96i5wNHi86S1xg== | @@ -140,11 +140,11 @@ Encode sensitive session IDs or IP addresses before storing them in logs or comp | project _time, id, uri, session_token ``` -\[Run in Playground]\([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend session\_bytes = dynamic(\[10, 20, 30, 40]) | extend session\_token = base64\_encode\_fromarray(session\_bytes) | where status == %27403%27 | project \_time, id, uri, session\_token%22%7D) +[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend session_bytes = dynamic([10, 20, 30, 40]) | extend session_token = base64_encode_fromarray(session_bytes) | where status == %27403%27 | project _time, id, uri, session_token%22%7D) **Output** -| \_time | id | uri | session\_token | +| _time | id | uri | session_token | | -------------------- | ------- | ------------ | -------------- | | 2025-06-25T09:12:00Z | user456 | /admin/panel | ChQeKA== | @@ -155,8 +155,8 @@ Encodes a mock session ID into Base64 format before logging it, helping to anony ## List of related functions -* [base64\_decode\_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. -* [format\_ipv4\_mask](/apl/ip-functions/format_ipv4_mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. +* [base64_decode_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. +* [format_ipv4_mask](/apl/ip-functions/format_ipv4_mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. * [tostring](/apl/type-functions/tostring): Converts a dynamic value into a string. Use it for general-purpose conversions, but not for Base64 encoding. -* [parse\_ipv4](/apl/ip-functions/parse_ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. -* [array\_concat](/apl/array-functions/array_concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. +* [parse_ipv4](/apl/ip-functions/parse_ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. +* [array_concat](/apl/array-functions/array_concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. From 750f53668896f6e631876889c26b3cd5400380ba Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Tue, 1 Jul 2025 10:46:14 +0200 Subject: [PATCH 05/10] Remove * --- .../array-functions/array-sort-asc.mdx | 168 +----------------- .../array-functions/array-sort-desc.mdx | 10 +- .../base64-decode-toarray.mdx | 10 +- .../base64-encode-fromarray.mdx | 10 +- 4 files changed, 20 insertions(+), 178 deletions(-) diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx index 8a6f2d15..80632835 100644 --- a/apl/scalar-functions/array-functions/array-sort-asc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-asc.mdx @@ -148,166 +148,8 @@ This query helps security analysts quickly review the HTTP status patterns encou ## List of related functions -* [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. -* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. -* [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. -* [array_index_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. -* [array_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. -````markdown ---- -title: array_sort_asc -description: 'This page explains how to use the array_sort_asc function in APL.' ---- - -## Introduction - -Use the `array_sort_asc` function to return a new array that contains all the elements of the input array, sorted in ascending order. This function is useful when you want to normalize the order of array elements for comparison, presentation, or further processing—such as identifying patterns, comparing sequences, or selecting boundary values. - -You can apply `array_sort_asc` to arrays of numbers, strings, or dynamic objects, making it useful across many telemetry, logging, and security data scenarios. - -## For users of other query languages - -If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. - - - - -In Splunk SPL, arrays are typically handled through `mvsort`, which sorts multivalue fields in ascending order. In APL, `array_sort_asc` provides similar functionality but works on dynamic arrays and returns a new sorted array. - - -```sql Splunk example -| eval sorted_values = mvsort(multivalue_field) -```` - -```kusto APL equivalent -datatable(arr: dynamic) -[ - dynamic([4, 2, 5]) -] -| extend sorted_arr = array_sort_asc(arr) -``` - - - - - - -ANSI SQL does not directly support array data types or array sorting. You typically normalize arrays with `UNNEST` and sort the results using `ORDER BY`. In APL, you can sort arrays inline using `array_sort_asc`, which is more concise and expressive. - - -```sql SQL example -SELECT val -FROM UNNEST([4, 2, 5]) AS val -ORDER BY val ASC -``` - -```kusto APL equivalent -print sorted_arr = array_sort_asc(dynamic([4, 2, 5])) -``` - - - - - - -## Usage - -### Syntax - -```kusto -array_sort_asc(array) -``` - -### Parameters - -| Name | Type | Required | Description | -| ----- | ------- | -------- | ------------------------------------------------------------------------- | -| array | dynamic | ✔️ | An array of values to sort. Can be numbers, strings, or other primitives. | - -### Returns - -A new array that contains the same elements as the input array, sorted in ascending order. If the input is not an array, the function returns an empty array. - -## Use case examples - - - - -Sort request durations in ascending order to analyze latency distributions. - -**Query** - -```kusto -['sample-http-logs'] -| where isnotempty(req_duration_ms) -| summarize durations = make_list(req_duration_ms) -| extend sorted_durations = array_sort_asc(durations) -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req_duration_ms) %7C summarize durations = make_list(req_duration_ms) %7C extend sorted_durations = array_sort_asc(durations)%22%7D) - -**Output** - -| durations | sorted_durations | -| ---------------- | ----------------- | -| [200, 120, 350] | [120, 200, 350] | - -The query collects request durations and returns a sorted version of the list to help with percentile or latency threshold analysis. - - - - -Sort span durations to observe timing patterns within a trace group. - -**Query** - -```kusto -['otel-demo-traces'] -| where isnotempty(duration) -| summarize durations = make_list(toint(duration)) by ['service.name'] -| extend sorted_durations = array_sort_asc(durations) -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted_durations = array_sort_asc(durations)%22%7D) - -**Output** - -| service.name | durations | sorted_durations | -| ------------ | ------------------- | ------------------- | -| frontend | [3100, 1200, 5600] | [1200, 3100, 5600] | - -The query shows how span durations for each service are sorted to better analyze processing time distributions. - - - - -Sort HTTP status codes to detect frequency or anomalies in ordered responses. - -**Query** - -```kusto -['sample-http-logs'] -| summarize status_codes = make_list(tolong(status)) by id -| extend sorted_status_codes = array_sort_asc(status_codes) -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status_codes = make_list(tolong(status)) by id %7C extend sorted_status_codes = array_sort_asc(status_codes)%22%7D) - -**Output** - -| id | status_codes | sorted_status_codes | -| ------- | ---------------- | --------------------- | -| user123 | [500, 200, 404] | [200, 404, 500] | - -This query helps security analysts quickly review the HTTP status patterns encountered by each user. - - - - -## List of related functions - -* [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. -* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. -* [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. -* [array_index_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. -* [array_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. +- [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. +- [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. +- [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. +- [array_index_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. +- [array_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx index f7ef1d72..d6aaa8cb 100644 --- a/apl/scalar-functions/array-functions/array-sort-desc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx @@ -150,8 +150,8 @@ The query helps investigate accounts generating frequent errors or suspicious pa ## List of related functions -* [array_sort_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. -* [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Use it to create arrays before applying `array_sort_desc`. -* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. -* [array_slice](/apl/array-functions/array_slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. -* [array_index_of](/apl/array-functions/array_index_of): Returns the index of a value in an array. Useful after sorting to locate specific elements. +- [array_sort_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. +- [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Use it to create arrays before applying `array_sort_desc`. +- [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. +- [array_slice](/apl/array-functions/array_slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. +- [array_index_of](/apl/array-functions/array_index_of): Returns the index of a value in an array. Useful after sorting to locate specific elements. diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx index e40e49d6..de47b970 100644 --- a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx +++ b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx @@ -141,8 +141,8 @@ This query filters failed authorization attempts and decodes the `id` field, whi ## List of related functions -* [base64_decode_tostring](/apl/string-functions/base64_decode_tostring): Decodes a Base64-encoded string into its UTF-8 text form. Use when you want a decoded string instead of raw bytes. -* [parse_json](/apl/string-functions/parse_json): Converts a string containing JSON into a dynamic object. Use after decoding Base64 if the result is structured data. -* [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use after decoding to validate payload length. -* [array_index](/apl/array-functions/array_index): Retrieves a value at a specific index of an array. Use to inspect specific bytes after decoding. -* [array_slice](/apl/array-functions/array_slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. +- [base64_decode_tostring](/apl/string-functions/base64_decode_tostring): Decodes a Base64-encoded string into its UTF-8 text form. Use when you want a decoded string instead of raw bytes. +- [parse_json](/apl/string-functions/parse_json): Converts a string containing JSON into a dynamic object. Use after decoding Base64 if the result is structured data. +- [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use after decoding to validate payload length. +- [array_index](/apl/array-functions/array_index): Retrieves a value at a specific index of an array. Use to inspect specific bytes after decoding. +- [array_slice](/apl/array-functions/array_slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx index b69c2b1f..9697ebcb 100644 --- a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx +++ b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx @@ -155,8 +155,8 @@ Encodes a mock session ID into Base64 format before logging it, helping to anony ## List of related functions -* [base64_decode_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. -* [format_ipv4_mask](/apl/ip-functions/format_ipv4_mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. -* [tostring](/apl/type-functions/tostring): Converts a dynamic value into a string. Use it for general-purpose conversions, but not for Base64 encoding. -* [parse_ipv4](/apl/ip-functions/parse_ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. -* [array_concat](/apl/array-functions/array_concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. +- [base64_decode_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. +- [format_ipv4_mask](/apl/ip-functions/format_ipv4_mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. +- [tostring](/apl/type-functions/tostring): Converts a dynamic value into a string. Use it for general-purpose conversions, but not for Base64 encoding. +- [parse_ipv4](/apl/ip-functions/parse_ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. +- [array_concat](/apl/array-functions/array_concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. From 167ccc297a4377bd345de384aa121219a35b74df Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Tue, 1 Jul 2025 11:03:49 +0200 Subject: [PATCH 06/10] Start fixing --- apl/scalar-functions/string-functions.mdx | 4 +-- .../base64-decode-toarray.mdx | 29 ++----------------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/apl/scalar-functions/string-functions.mdx b/apl/scalar-functions/string-functions.mdx index 2ce4c33e..e5c5d379 100644 --- a/apl/scalar-functions/string-functions.mdx +++ b/apl/scalar-functions/string-functions.mdx @@ -10,9 +10,9 @@ tags: | **Function Name** | **Description** | | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray) | Decodes an array of base64 strings to UTF-8 strings. | +| [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray) | Decode a Base64-encoded string into an array of bytes. | | [base64_decode_tostring](#base64-decode-tostring) | Decodes a base64 string to a UTF-8 string. | -| [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray) | Encodes an array of strings as base64 strings. | +| [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray) | Convert a sequence of bytes into a Base64-encoded string. | | [base64_encode_tostring](#base64-encode-tostring) | Encodes a string as base64 string. | | [countof](#countof) | Counts occurrences of a substring in a string. | | [countof_regex](#countof-regex) | Counts occurrences of a substring in a string. Regex matches don’t. | diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx index de47b970..dc5151da 100644 --- a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx +++ b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx @@ -80,7 +80,7 @@ You want to decode a Base64-encoded field in logs to inspect raw payloads for de | extend raw = base64_decode_toarray('aGVsbG8gd29ybGQ=') ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C extend raw%20%3D%20base64_decode_toarray%28%27aGVsbG8gd29ybGQ%3D%27%29%22%7D) +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20raw%20%3D%20base64_decode_toarray('aGVsbG8gd29ybGQ%3D')%22%7D) **Output** @@ -100,10 +100,10 @@ You receive Base64-encoded trace IDs from an external system and want to decode ```kusto ['otel-demo-traces'] | extend trace_bytes = base64_decode_toarray(trace_id) -| project ['otel-demo-traces'], trace_id, trace_bytes +| project trace_id, trace_bytes ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C extend trace_bytes%20%3D%20base64_decode_toarray%28trace_id%29 %7C project%20%5B%27otel-demo-traces%27%5D%2C%20trace_id%2C%20trace_bytes%22%7D) +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20extend%20trace_bytes%20%3D%20base64_decode_toarray(trace_id)%20%7C%20project%20trace_id%2C%20trace_bytes%22%7D) **Output** @@ -113,29 +113,6 @@ You receive Base64-encoded trace IDs from an external system and want to decode This query decodes the trace ID from Base64 into its byte-level representation for internal processing or fingerprinting. - - - -A security event includes a Base64-encoded payload that you want to decode and inspect for signature verification. - -**Query** - -```kusto -['sample-http-logs'] -| where status == '401' -| extend payload = base64_decode_toarray(id) -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where%20status%20%3D%3D%20%27401%27 %7C extend%20payload%20%3D%20base64_decode_toarray%28id%29%22%7D) - -**Output** - -| id | payload | -| ------------ | ---------------------------------------- | -| ZHVtbXkgaWQ= | [100, 117, 109, 109, 121, 32, 105, 100] | - -This query filters failed authorization attempts and decodes the `id` field, which is Base64-encoded, into its original byte array for forensic inspection. - From 238a61dbac04bc4bf78250cf113a0056221705ba Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Wed, 2 Jul 2025 10:11:37 +0200 Subject: [PATCH 07/10] Fixes --- .../array-functions/array-sort-asc.mdx | 77 ++++-------------- .../array-functions/array-sort-desc.mdx | 78 ++++--------------- 2 files changed, 26 insertions(+), 129 deletions(-) diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx index 80632835..13ac64d6 100644 --- a/apl/scalar-functions/array-functions/array-sort-asc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-asc.mdx @@ -70,82 +70,31 @@ array_sort_asc(array) A new array that contains the same elements as the input array, sorted in ascending order. If the input is not an array, the function returns an empty array. -## Use case examples - - - - -Sort request durations in ascending order to analyze latency distributions. +## Example **Query** ```kusto ['sample-http-logs'] -| where isnotempty(req_duration_ms) -| summarize durations = make_list(req_duration_ms) -| extend sorted_durations = array_sort_asc(durations) +| project sort = array_sort_asc(dynamic(['x', 'a', 'm', 'o', 'i'])) ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C where isnotempty(req_duration_ms) %7C summarize durations = make_list(req_duration_ms) %7C extend sorted_durations = array_sort_asc(durations)%22%7D) +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20project%20sort%20%3D%20array_sort_asc(dynamic(%5B'x'%2C%20'a'%2C%20'm'%2C%20'o'%2C%20'i'%5D))%22%7D) **Output** -| durations | sorted_durations | -| ---------------- | ----------------- | -| [200, 120, 350] | [120, 200, 350] | - -The query collects request durations and returns a sorted version of the list to help with percentile or latency threshold analysis. - - - - -Sort span durations to observe timing patterns within a trace group. - -**Query** - -```kusto -['otel-demo-traces'] -| where isnotempty(duration) -| summarize durations = make_list(toint(duration)) by ['service.name'] -| extend sorted_durations = array_sort_asc(durations) -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) %7C where isnotempty(duration) %7C summarize durations = make_list(toint(duration)) by %5B%27service.name%27%5D %7C extend sorted_durations = array_sort_asc(durations)%22%7D) - -**Output** - -| service.name | durations | sorted_durations | -| ------------ | ------------------- | ------------------- | -| frontend | [3100, 1200, 5600] | [1200, 3100, 5600] | - -The query shows how span durations for each service are sorted to better analyze processing time distributions. - - - - -Sort HTTP status codes to detect frequency or anomalies in ordered responses. - -**Query** - -```kusto -['sample-http-logs'] -| summarize status_codes = make_list(tolong(status)) by id -| extend sorted_status_codes = array_sort_asc(status_codes) +```json +[ + [ + "a", + "i", + "m", + "o", + "x" + ] +] ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) %7C summarize status_codes = make_list(tolong(status)) by id %7C extend sorted_status_codes = array_sort_asc(status_codes)%22%7D) - -**Output** - -| id | status_codes | sorted_status_codes | -| ------- | ---------------- | --------------------- | -| user123 | [500, 200, 404] | [200, 404, 500] | - -This query helps security analysts quickly review the HTTP status patterns encountered by each user. - - - - ## List of related functions - [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx index d6aaa8cb..46541e1d 100644 --- a/apl/scalar-functions/array-functions/array-sort-desc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx @@ -71,83 +71,31 @@ array_sort_desc(array) If the input is a valid array, the function returns a new array with its elements sorted in descending order. If the array is empty or contains incompatible types, it returns an empty array. -## Use case examples - - - - -Use this function to identify the slowest request durations per user from HTTP logs. +## Example **Query** ```kusto ['sample-http-logs'] -| summarize durations=make_list(req_duration_ms) by id -| extend top_durations=array_sort_desc(durations) -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize durations%3Dmake_list(req_duration_ms) by id %7C extend top_durations%3Darray_sort_desc(durations)%22%7D) - -**Output** - -| id | durations | top_durations | -| ------ | ------------------- | ------------------- | -| user-1 | [104, 87, 129, 46] | [129, 104, 87, 46] | -| user-2 | [80, 120, 98] | [120, 98, 80] | - -The query collects request durations per user and then sorts them so the longest durations appear first. - - - - -Use this function to sort span durations per trace to find the slowest spans. - -**Query** - -```kusto -['otel-demo-traces'] -| summarize durations=make_list(duration) by trace_id -| extend sorted_durations=array_sort_desc(durations) +| project sort = array_sort_desc(dynamic(['x', 'a', 'm', 'o', 'i'])) ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D) %7C summarize durations%3Dmake_list(duration) by trace_id %7C extend sorted_durations%3Darray_sort_desc(durations)%22%7D) +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20project%20sort%20%3D%20array_sort_desc(dynamic(%5B'x'%2C%20'a'%2C%20'm'%2C%20'o'%2C%20'i'%5D))%22%7D) **Output** -| trace_id | durations | sorted_durations | -| --------- | -------------------------- | -------------------------- | -| abcd1234 | [120ms, 80ms, 300ms] | [300ms, 120ms, 80ms] | -| efgh5678 | [60ms, 45ms, 100ms, 30ms] | [100ms, 60ms, 45ms, 30ms] | - -The query organizes span durations from highest to lowest for each trace to help detect performance bottlenecks. - - - - -Use this function to sort the status codes associated with user activity to identify abnormal patterns (e.g. many 500 errors). - -**Query** - -```kusto -['sample-http-logs'] -| summarize status_codes=make_list(tolong(status)) by id -| extend sorted_status=array_sort_desc(status_codes) +```json +[ + [ + "x", + "o", + "m", + "i", + "a" + ] +] ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D) %7C summarize status_codes%3Dmake_list(tolong(status)) by id %7C extend sorted_status%3Darray_sort_desc(status_codes)%22%7D) - -**Output** - -| id | status_codes | sorted_status | -| ------ | --------------------- | --------------------- | -| user-1 | [200, 403, 500] | [500, 403, 200] | -| user-2 | [404, 200, 404, 401] | [404, 404, 401, 200] | - -The query helps investigate accounts generating frequent errors or suspicious patterns based on HTTP status codes. - - - - ## List of related functions - [array_sort_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. From d3057786dd2e75db8be6eb7a1bfa9f90f780b4cb Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Wed, 2 Jul 2025 10:53:49 +0200 Subject: [PATCH 08/10] Fixes --- .../base64-encode-fromarray.mdx | 64 +------------------ 1 file changed, 3 insertions(+), 61 deletions(-) diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx index 9697ebcb..2c76d3d1 100644 --- a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx +++ b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx @@ -72,10 +72,7 @@ base64_encode_fromarray(array) If successful, returns a string representing the Base64-encoded version of the input byte array. If the input is not a valid array of bytes, the result is an empty string. -## Use case examples - - - +## Example Use this function to encode request metadata for logging or comparison with external systems that require Base64-encoded fields. @@ -88,71 +85,16 @@ Use this function to encode request metadata for logging or comparison with exte | project _time, id, method, uri, encoded_ip ``` -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend ip_bytes = dynamic([192, 168, 0, 1]) | extend encoded_ip = base64_encode_fromarray(ip_bytes) | project _time, id, method, uri, encoded_ip%22%7D) +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20ip_bytes%20%3D%20dynamic(%5B192%2C%20168%2C%200%2C%201%5D)%20%7C%20extend%20encoded_ip%20%3D%20base64_encode_fromarray(ip_bytes)%20%7C%20project%20_time%2C%20id%2C%20method%2C%20uri%2C%20encoded_ip%22%7D) **Output** | _time | id | method | uri | encoded_ip | | -------------------- | ------- | ------ | --------- | ----------- | -| 2025-06-25T08:00:00Z | user123 | GET | /api/data | wKgA | +| 2025-06-25T08:00:00Z | user123 | GET | /api/data | wKgAAQ== | Encodes a hardcoded byte representation of an IP address into Base64 for easy string-based comparison or logging. - - - -Encode trace identifiers or service-specific byte arrays into Base64 for downstream ingestion or correlation. - -**Query** - -```kusto -['otel-demo-traces'] -| extend trace_id_bytes = extract_all(@'..', trace_id) -| extend trace_id_array = range(0, strlen(trace_id)-1) - | extend val = toint(strcat('0x', substring(trace_id, index*2, 2))) - | summarize make_list(val) -| extend encoded_trace_id = base64_encode_fromarray(trace_id_array) -| project _time, trace_id, ['service.name'], encoded_trace_id -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D) | extend trace_id_bytes = extract_all(@%27..%27, trace_id) | extend trace_id_array = range(0, strlen(trace_id)-1) | extend val = toint(strcat(%270x%27, substring(trace_id, index*2, 2))) | summarize make_list(val) | extend encoded_trace_id = base64_encode_fromarray(trace_id_array) | project _time, trace_id, ['service.name'], encoded_trace_id%22%7D) - -**Output** - -| _time | trace_id | ['service.name'] | encoded_trace_id | -| -------------------- | -------------------------------- | ----------------- | ------------------------ | -| 2025-06-25T08:00:00Z | f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6 | checkoutservice | 8aKyxNXm96i5wNHi86S1xg== | - -Transforms a trace ID into a Base64-encoded string to support interop with telemetry pipelines or identifiers stored in external formats. - - - - -Encode sensitive session IDs or IP addresses before storing them in logs or comparing across systems that use Base64 formats. - -**Query** - -```kusto -['sample-http-logs'] -| extend session_bytes = dynamic([10, 20, 30, 40]) -| extend session_token = base64_encode_fromarray(session_bytes) -| where status == '403' -| project _time, id, uri, session_token -``` - -[Run in Playground]([https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D) | extend session_bytes = dynamic([10, 20, 30, 40]) | extend session_token = base64_encode_fromarray(session_bytes) | where status == %27403%27 | project _time, id, uri, session_token%22%7D) - -**Output** - -| _time | id | uri | session_token | -| -------------------- | ------- | ------------ | -------------- | -| 2025-06-25T09:12:00Z | user456 | /admin/panel | ChQeKA== | - -Encodes a mock session ID into Base64 format before logging it, helping to anonymize sensitive information while preserving structure. - - - - ## List of related functions - [base64_decode_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. From 3d5c26db31b107b719ffd3c83ab17cfd1db88e14 Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Wed, 2 Jul 2025 11:01:17 +0200 Subject: [PATCH 09/10] Fix links --- apl/scalar-functions/array-functions/array-sort-asc.mdx | 9 ++++----- apl/scalar-functions/array-functions/array-sort-desc.mdx | 9 ++++----- .../string-functions/base64-decode-toarray.mdx | 8 +++----- .../string-functions/base64-encode-fromarray.mdx | 9 ++++----- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx index 13ac64d6..b904e8a9 100644 --- a/apl/scalar-functions/array-functions/array-sort-asc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-asc.mdx @@ -97,8 +97,7 @@ A new array that contains the same elements as the input array, sorted in ascend ## List of related functions -- [array_sort_desc](/apl/array-functions/array_sort_desc): Sorts array elements in descending order. Use when you need reverse ordering. -- [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use to understand array size before or after sorting. -- [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Often used before applying `array_sort_asc`. -- [array_index_of](/apl/array-functions/array_index_of): Returns the position of an element in an array. Use after sorting to find where values fall. -- [array_slice](/apl/array-functions/array_slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. +- [array_index_of](/apl/scalar-functions/array-functions/array-index-of): Returns the position of an element in an array. Use after sorting to find where values fall. +- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Use to understand array size before or after sorting. +- [array_slice](/apl/scalar-functions/array-functions/array-slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements. +- [array_sort_desc](/apl/scalar-functions/array-functions/array-sort-desc): Sorts array elements in descending order. Use when you need reverse ordering. diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx index 46541e1d..015d9e7b 100644 --- a/apl/scalar-functions/array-functions/array-sort-desc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx @@ -98,8 +98,7 @@ If the input is a valid array, the function returns a new array with its element ## List of related functions -- [array_sort_asc](/apl/array-functions/array_sort_asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. -- [make_list](/apl/aggregation-functions/make_list): Aggregates values into an array. Use it to create arrays before applying `array_sort_desc`. -- [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. -- [array_slice](/apl/array-functions/array_slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. -- [array_index_of](/apl/array-functions/array_index_of): Returns the index of a value in an array. Useful after sorting to locate specific elements. +- [array_index_of](/apl/scalar-functions/array-functions/array-index-of): Returns the index of a value in an array. Useful after sorting to locate specific elements. +- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting. +- [array_slice](/apl/scalar-functions/array-functions/array-slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values. +- [array_sort_asc](/apl/scalar-functions/array-functions/array-sort-asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first. diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx index dc5151da..80da66b1 100644 --- a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx +++ b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx @@ -118,8 +118,6 @@ This query decodes the trace ID from Base64 into its byte-level representation f ## List of related functions -- [base64_decode_tostring](/apl/string-functions/base64_decode_tostring): Decodes a Base64-encoded string into its UTF-8 text form. Use when you want a decoded string instead of raw bytes. -- [parse_json](/apl/string-functions/parse_json): Converts a string containing JSON into a dynamic object. Use after decoding Base64 if the result is structured data. -- [array_length](/apl/array-functions/array_length): Returns the number of elements in an array. Use after decoding to validate payload length. -- [array_index](/apl/array-functions/array_index): Retrieves a value at a specific index of an array. Use to inspect specific bytes after decoding. -- [array_slice](/apl/array-functions/array_slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. +- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Use after decoding to validate payload length. +- [array_slice](/apl/scalar-functions/array-functions/array-slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding. +- [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray): Converts a sequence of bytes into a Base64-encoded string. diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx index 2c76d3d1..4effb618 100644 --- a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx +++ b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx @@ -97,8 +97,7 @@ Encodes a hardcoded byte representation of an IP address into Base64 for easy st ## List of related functions -- [base64_decode_tobytes](/apl/string-functions/base64_decode_tobytes): Converts a Base64-encoded string back into a byte array. Use this when decoding data received from external sources. -- [format_ipv4_mask](/apl/ip-functions/format_ipv4_mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. -- [tostring](/apl/type-functions/tostring): Converts a dynamic value into a string. Use it for general-purpose conversions, but not for Base64 encoding. -- [parse_ipv4](/apl/ip-functions/parse_ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. -- [array_concat](/apl/array-functions/array_concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. +- [array_concat](/apl/scalar-functions/array-functions/array-concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding. +- [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray): Decode a Base64-encoded string into an array of bytes. Use this when decoding data received from external sources. +- [format_ipv4_mask](/apl/scalar-functions/ip-functions/format-ipv4-mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations. +- [parse_ipv4](/apl/scalar-functions/ip-functions/parse-ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses. From 82f9a1a3b06b065e253ee313fc5a2922363a961a Mon Sep 17 00:00:00 2001 From: Mano Toth Date: Wed, 2 Jul 2025 11:05:26 +0200 Subject: [PATCH 10/10] Fixes --- apl/scalar-functions/array-functions/array-sort-desc.mdx | 2 +- vale/styles/config/vocabularies/docs/accept.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx index 015d9e7b..5e02efcf 100644 --- a/apl/scalar-functions/array-functions/array-sort-desc.mdx +++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx @@ -14,7 +14,7 @@ If you come from other query languages, this section explains how to adjust your -Splunk does not have a direct equivalent to `array_sort_desc`, but similar outcomes can be achieved using `mvsort` with a custom sort order (and sometimes `reverse`). In APL, `array_sort_desc` explicitly performs a descending sort on array elements, making it more straightforward. +Splunk doesn’t have a direct equivalent to `array_sort_desc`, but similar outcomes can be achieved using `mvsort` with a custom sort order (and sometimes `reverse`). In APL, `array_sort_desc` explicitly performs a descending sort on array elements, making it more straightforward. ```sql Splunk example diff --git a/vale/styles/config/vocabularies/docs/accept.txt b/vale/styles/config/vocabularies/docs/accept.txt index 12e65d0e..c3fccb3f 100644 --- a/vale/styles/config/vocabularies/docs/accept.txt +++ b/vale/styles/config/vocabularies/docs/accept.txt @@ -56,4 +56,5 @@ Axiom Processing Language subpath [Dd]atastore [Tt]ooltip -[Vv]iewport \ No newline at end of file +[Vv]iewport +functionality \ No newline at end of file