Skip to content

docs: Explain how to work with auto-generated keys; Restructure to clarify how to specify keys for authoritative fields. #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
May 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/src/user-guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ A guide to viewing log files in the log viewer.
:::

:::{grid-item-card}
:link: format-struct-logs-overview
Formatting structured logs
:link: struct-logs/index
Working with structured logs
^^^
A guide to formatting structured (e.g. JSON) logs as plain text.
Guides and reference docs for working with structured logs.
:::

:::{grid-item-card}
Expand All @@ -37,12 +37,12 @@ quick-start

:::{toctree}
:hidden:
:caption: Formatting structured logs
:caption: Working with structured logs
:glob:

format-struct-logs-overview
format-struct-logs-syntax
format-struct-logs-formatters
struct-logs/index
struct-logs/format/index
struct-logs/specifying-keys
:::

:::{toctree}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Overview
# Formatting as plain text

The log viewer can format structured (e.g. JSON) logs as plain text using a format string. The
format string allows you to select which fields to include and how they should be formatted. You can
Expand Down Expand Up @@ -33,5 +33,12 @@ The formatted log would appear as:
```

For reference docs, see:
* [Format string syntax](format-struct-logs-syntax)
* [Formatters](format-struct-logs-formatters)
* [Format string syntax](syntax)
* [Formatters](formatters)

:::{toctree}
:hidden:

syntax
formatters
:::
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,14 @@ backslash:
Each field placeholder is enclosed in braces (`{` and `}`) and has the following form, consisting of
three components:
```
{<field-name>[:<formatter-name>[:<formatter-options>]]}
{<field-key>[:<formatter-name>[:<formatter-options>]]}
```

### field-name (required)
### field-key (required)
Defines the key of the field whose value should replace the placeholder.

* Nested fields can be specified using periods (`.`) to denote hierarchy.
* E.g., the field `{"a:" {"b": 0}}` may be denoted by `a.b`.
* Field names can contain any character, except the following characters must be escaped with a
backslash:
* `.`
* `$`
* `{`
* `}`
* `:`
* `\`
:::{include} ../key-syntax.md
:::

### formatter-name (optional)
The name of the formatter to apply to the value before inserting it into the string.
Expand All @@ -43,6 +35,8 @@ The name of the formatter to apply to the value before inserting it into the str
* `:`
* `\`

For a list of currently supported formatters, see [Formatters](formatters).

### formatter-options (optional)
Defines any options for the formatter denoted by `formatter-name`.

Expand All @@ -63,28 +57,31 @@ Every format string contains an implicit trailing newline so that each formatted
a newline.

## Examples
Consider the following log event:
```

### Formatting JSON logs events

Consider the following JSON log event:
```json
{
"@timestamp": 1427153388942,
"ts": 1427153388942,
"level": "INFO",
"thread": 0,
"latency": {
"msecs": 56400,
"secs": 56.4,
"secs": 56.4
},
"an.odd.key{name}": "org.apache.hadoop.metrics2.impl.MetricsConfig: loaded properties from hadoop-metrics2.properties"
"@an.odd.key{name}": "org.apache.hadoop.metrics2.impl.MetricsConfig: loaded properties from hadoop-metrics2.properties"
}
```

We can format this using the following YScope format string:
We can format this using the following format string:

```
{@timestamp:timestamp:YYYY-MM-DD HH\:mm\:ss.SSS} {level} \{{thread}\} latency={latency.secs:round} {an\.odd\.key\{name\}}
{ts:timestamp:YYYY-MM-DD HH\:mm\:ss.SSS} {level} \{{thread}\} latency={latency.secs:round} {\@an\.odd\.key\{name\}}
```

* In the first placeholder, we have the field name `@timestamp`, a formatter called `timestamp`, and
the formatter's options which are a date format string.
* In the first placeholder, we have the field key `ts`, a formatter called `timestamp`, and the
formatter's options which are a date format string.
* The second and third placeholders simply stringify the values of the given fields.
* The fourth placeholder uses the `round` formatter to round a nested field's value; this
placeholder doesn't specify any formatter options, so the defaults will be used.
Expand All @@ -95,4 +92,40 @@ The formatted string will be:
2015-03-23 19:29:48.942 INFO {0} latency=56 org.apache.hadoop.metrics2.impl.MetricsConfig: loaded properties from hadoop-metrics2.properties
```

For a list of currently supported formatters, see [Formatters](format-struct-logs-formatters).
### Formatting kv-pair IR log events

Consider the following kv-pair IR log event:

:::{note}
In the example below, for simplicity, we render the log event as JSON with the auto-generated
kv-pairs under the `auto-generated` key, and the user-generated kv-pairs under the `user-generated`
key, but these keys don't exist in the log event.
:::

```json
{
"auto-generated": {
"ts": 1741371422000
},
"user-generated": {
"message": "Callback registered to fire in 5 seconds:",
"ts": 1741371427000
}
}
```

We can format this using the following format string:

```
{@ts:timestamp} {message} {ts:timestamp}
```

* In the first placeholder, we have the auto-generated field key `@ts`. The `@` prefix specifies
that the field is from the auto-generated namespace.
* The second and third placeholders refer to the `message` and `ts` fields in the user-generated
namespace.

The formatted string will be:
```
2025-03-07T18:17:02Z Callback registered to fire in 5 seconds: 2025-03-07T18:17:07Z
```
21 changes: 21 additions & 0 deletions docs/src/user-guide/struct-logs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Overview

The guides below describe how to configure the log viewer to work with structured logs.

::::{grid} 1 1 2 2
:gutter: 2

:::{grid-item-card}
:link: format/index
Formatting as plain text
^^^
How to format structured logs as plain text, using a format string.
:::

:::{grid-item-card}
:link: specifying-keys
Specifying keys
^^^
How to specify keys when configuring the log viewer.
:::
::::
14 changes: 14 additions & 0 deletions docs/src/user-guide/struct-logs/key-syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* Nested keys can be specified using periods (`.`) to denote hierarchy.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Add a top-level heading for consistency with Markdown style
As per markdownlint MD041, the first line should be a top-level heading. Consider adding:

# Key Syntax
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)

* E.g., the field `{"a:" {"b": 0}}` may be denoted by `a.b`.
Comment on lines +1 to +2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the JSON example syntax
The inline JSON in the example is missing a closing quote after the key. Update it to:

- * E.g., the field `{"a:" {"b": 0}}` may be denoted by `a.b`.
+ * E.g., the field `{"a": {"b": 0}}` may be denoted by `a.b`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* Nested keys can be specified using periods (`.`) to denote hierarchy.
* E.g., the field `{"a:" {"b": 0}}` may be denoted by `a.b`.
* Nested keys can be specified using periods (`.`) to denote hierarchy.
* E.g., the field `{"a": {"b": 0}}` may be denoted by `a.b`.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)

* Auto-generated keys in a [Key-Value Pair IR Stream][kv-pair-ir] can be specified by using `@` as
a prefix.
* E.g., the auto-generated key `ts` would be specified as `@ts`.
Comment on lines +3 to +5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Simplify the auto-generated keys bullet for clarity
Combine the wrapped lines into one concise sentence:

-* Auto-generated keys in a [Key-Value Pair IR Stream][kv-pair-ir] can be specified by using `@` as
-  a prefix.
+* Auto-generated keys in a [Key-Value Pair IR Stream][kv-pair-ir] can be specified by prefixing them with `@`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* Auto-generated keys in a [Key-Value Pair IR Stream][kv-pair-ir] can be specified by using `@` as
a prefix.
* E.g., the auto-generated key `ts` would be specified as `@ts`.
* Auto-generated keys in a [Key-Value Pair IR Stream][kv-pair-ir] can be specified by prefixing them with `@`.
* E.g., the auto-generated key `ts` would be specified as `@ts`.

* Keys can contain any character, except the following characters must be escaped with a backslash:
* `.`
* `@`
* `{`
* `}`
* `:`
* `\`
Comment on lines +6 to +12
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Improve wording and escape sequence formatting

  • Rephrase the sentence for better readability:
    -* Keys can contain any character, except the following characters must be escaped with a backslash:
    +* Keys can contain any character; however, the following characters must be escaped with a backslash:
  • Ensure the backslash itself is displayed correctly in Markdown by escaping it:
    -* `\`
    +* `\\`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* Keys can contain any character, except the following characters must be escaped with a backslash:
* `.`
* `@`
* `{`
* `}`
* `:`
* `\`
* Keys can contain any character; however, the following characters must be escaped with a backslash:
* `.`
* `@`
* `{`
* `}`
* `:`
* `\\`


[kv-pair-ir]: https://docs.yscope.com/clp/main/dev-guide/design-kv-ir-streams/auto-gen-kv-pairs.html
12 changes: 12 additions & 0 deletions docs/src/user-guide/struct-logs/specifying-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Specifying keys

Viewing structured logs requires specifying keys for:
* The format string
* Authoritative fields such as the log level and timestamp

Both options are found the settings dialog ({fas}`gear`).

## Syntax

:::{include} key-syntax.md
:::
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,19 @@ const getConfigFormFields = () => [
{
helperText: (
<span>
[JSON] Format string for formatting a JSON log event as plain text. See the
[Structured] Format string for formatting a structured log event as plain text.
Leave blank to display the entire log event. See
{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/format-struct-logs-overview.html"}
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/format/index.html"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
format string syntax docs
here
</Link>
{" "}
or leave this blank to display the entire log event.
for syntax.
Comment on lines +51 to +63
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Descriptive link text for accessibility.

The link text “here” is too generic and may not be clear for assistive technologies. Consider using more descriptive text, for example:

-                <Link
-                    href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/format/index.html"}
-                    level={"body-sm"}
-                    rel={"noopener"}
-                    target={"_blank"}
-                >
-                    here
-                </Link>
+                <Link
+                    href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/format/index.html"}
+                    level={"body-sm"}
+                    rel={"noopener"}
+                    target={"_blank"}
+                >
+                    structured logs formatting guide
+                </Link>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[Structured] Format string for formatting a structured log event as plain text.
Leave blank to display the entire log event. See
{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/format-struct-logs-overview.html"}
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/format/index.html"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
format string syntax docs
here
</Link>
{" "}
or leave this blank to display the entire log event.
for syntax.
[Structured] Format string for formatting a structured log event as plain text.
Leave blank to display the entire log event. See
{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/format/index.html"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
structured logs formatting guide
</Link>
{" "}
for syntax.

</span>
),
initialValue: getConfig(CONFIG_KEY.DECODER_OPTIONS).formatString,
Expand All @@ -68,14 +69,44 @@ const getConfigFormFields = () => [
type: "text",
},
{
helperText: "[JSON] Key to extract the log level from.",
helperText: (
<span>
[Structured] Key that maps to each log event&apos;s log level. See
{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
here
</Link>
{" "}
for syntax.
</span>
Comment on lines +72 to +86
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Enhance link clarity for log level key syntax.

Similarly, the link text “here” in the log level key helper text is not self-descriptive. Update it to a phrase that reflects its target, for example:

-                <Link
-                    href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
-                    level={"body-sm"}
-                    rel={"noopener"}
-                    target={"_blank"}
-                >
-                    here
-                </Link>
+                <Link
+                    href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
+                    level={"body-sm"}
+                    rel={"noopener"}
+                    target={"_blank"}
+                >
+                    structured logs key syntax guide
+                </Link>

),
initialValue: getConfig(CONFIG_KEY.DECODER_OPTIONS).logLevelKey,
key: LOCAL_STORAGE_KEY.DECODER_OPTIONS_LOG_LEVEL_KEY,
label: "Decoder: Log level key",
type: "text",
},
{
helperText: "[JSON] Key to extract the log timestamp from.",
helperText: (
<span>
[Structured] Key that maps to each log event&apos;s timestamp. See
{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
here
</Link>
{" "}
for syntax.
</span>
Comment on lines +94 to +108
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use meaningful link text for timestamp key syntax.

The helper text for the timestamp key also uses “here”, which offers no context. Consider a descriptive label:

-                <Link
-                    href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
-                    level={"body-sm"}
-                    rel={"noopener"}
-                    target={"_blank"}
-                >
-                    here
-                </Link>
+                <Link
+                    href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
+                    level={"body-sm"}
+                    rel={"noopener"}
+                    target={"_blank"}
+                >
+                    structured logs key syntax guide
+                </Link>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
helperText: (
<span>
[Structured] Key that maps to each log event&apos;s timestamp. See
{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
here
</Link>
{" "}
for syntax.
</span>
helperText: (
<span>
[Structured] Key that maps to each log event&apos;s timestamp. See{" "}
<Link
href={"https://docs.yscope.com/yscope-log-viewer/main/user-guide/struct-logs/specifying-keys.html#syntax"}
level={"body-sm"}
rel={"noopener"}
target={"_blank"}
>
structured logs key syntax guide
</Link>{" "}
for syntax.
</span>
)

),
initialValue: getConfig(CONFIG_KEY.DECODER_OPTIONS).timestampKey,
key: LOCAL_STORAGE_KEY.DECODER_OPTIONS_TIMESTAMP_KEY,
label: "Decoder: Timestamp key",
Expand Down