Skip to content
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

feat: return the jsonpath of json detected fields #16861

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

trevorwhitney
Copy link
Collaborator

@trevorwhitney trevorwhitney commented Mar 21, 2025

What this PR does / why we need it:

This PR modifies the /detected_fields response to include the jsonpath of fields that were parsed from JSON objects. Since we use the _ character to represent both property nesting, as well as to escaped illegal characters from the label, there is no deterministic way to reverse engineer the jsonpath of the property from the label. Knowing the property is required to support a new JSON view for Logs Drilldown that will let users drilldown into certain JSON property, as we will be re-writing the query with arguments to the json parser to change the root key to the property the user has chosen to drill into, and we will need to know the correct path to that key.

Benchmarks:

goos: darwin
goarch: arm64
pkg: github.com/grafana/loki/v3/pkg/logql/log
cpu: Apple M3 Pro
                                │ bench_results_20250321_171738/main_parser_bench.txt │ bench_results_20250321_171738/feature_parser_bench.txt │
                                │                       sec/op                        │             sec/op              vs base                │
_Parser/json/no_labels_hints-11                                          3.837µ ± ∞ ¹                     3.533µ ± ∞ ¹       ~ (p=1.000 n=1) ²
_Parser/json/labels_hints-11                                             2.423µ ± ∞ ¹                     2.318µ ± ∞ ¹       ~ (p=1.000 n=1) ²
_Parser/json/inline_stages-11                                           1033.0n ± ∞ ¹                     870.3n ± ∞ ¹       ~ (p=1.000 n=1) ²
geomean                                                                  2.126µ                           1.924µ        -9.46%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05

                                │ bench_results_20250321_171738/main_parser_bench.txt │ bench_results_20250321_171738/feature_parser_bench.txt │
                                │                        B/op                         │              B/op               vs base                │
_Parser/json/no_labels_hints-11                                           280.0 ± ∞ ¹                      304.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
_Parser/json/labels_hints-11                                              176.0 ± ∞ ¹                      192.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
_Parser/json/inline_stages-11                                             64.00 ± ∞ ¹                      64.00 ± ∞ ¹       ~ (p=1.000 n=1) ³
geomean                                                                   146.7                            155.2        +5.80%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05
³ all samples are equal

                                │ bench_results_20250321_171738/main_parser_bench.txt │ bench_results_20250321_171738/feature_parser_bench.txt │
                                │                      allocs/op                      │           allocs/op             vs base                │
_Parser/json/no_labels_hints-11                                           18.00 ± ∞ ¹                      20.00 ± ∞ ¹       ~ (p=1.000 n=1) ²
_Parser/json/labels_hints-11                                              12.00 ± ∞ ¹                      14.00 ± ∞ ¹       ~ (p=1.000 n=1) ²
_Parser/json/inline_stages-11                                             4.000 ± ∞ ¹                      4.000 ± ∞ ¹       ~ (p=1.000 n=1) ³
geomean                                                                   9.524                            10.38        +9.04%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05
³ all samples are equal

Which issue(s) this PR fixes:
Fixes #16816

Special notes for your reviewer:

Checklist

  • Reviewed the CONTRIBUTING.md guide (required)
  • Documentation added
  • Tests updated
  • Title matches the required conventional commits format, see here
    • Note that Promtail is considered to be feature complete, and future development for logs collection will be in Grafana Alloy. As such, feat PRs are unlikely to be accepted unless a case can be made for the feature actually being a bug fix to existing behavior.
  • Changes that require user attention or interaction to upgrade are documented in docs/sources/setup/upgrade/_index.md
  • If the change is deprecating or removing a configuration option, update the deprecated-config.yaml and deleted-config.yaml files respectively in the tools/deprecated-config-checker directory. Example PR

@trevorwhitney trevorwhitney force-pushed the detected-fields-json-path branch from 15ce780 to 9f86d57 Compare March 21, 2025 17:19
@trevorwhitney trevorwhitney marked this pull request as ready for review March 21, 2025 18:46
@trevorwhitney trevorwhitney requested a review from a team as a code owner March 21, 2025 18:46
func (j *JSONParser) buildJSONPathFromPrefixBuffer() []string {
jsonPath := make([]string, 0, len(j.prefixBuffer))
for _, part := range j.prefixBuffer {
partStr := unsafe.String(unsafe.SliceData(part), len(part)) // #nosec G103 -- we know the string is not mutated
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the parts of the path will not change, so I've optimized this to use unsafe.String, which saves ~20% in terms of allocations.

@periklis periklis self-requested a review March 24, 2025 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

detected_fields: Add "path" for nested json
1 participant