-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
fix: skipping label if it contains special symbol #14068
Conversation
1623da3
to
11b0ac0
Compare
Hey @ravishankar15 . Here the code I used in the benchmark
package stringreplacement
import (
"bytes"
"strings"
"testing"
"unicode/utf8"
)
func replaceNoop(source string) string {
return source
}
var removeInvalidUtf = func(r rune) rune {
if r == utf8.RuneError {
return -1
}
return r
}
func replaceContainsAndStringsMap(source string) string {
if strings.ContainsRune(source, utf8.RuneError) {
strings.Map(removeInvalidUtf, source)
}
return source
}
func replaceStringsMap(source string) string {
return strings.Map(removeInvalidUtf, source)
}
func replaceContainsAndBytesMap(source []byte) []byte {
if bytes.ContainsRune(source, utf8.RuneError) {
bytes.Map(removeInvalidUtf, source)
}
return source
}
func replaceBytesMap(source []byte) []byte {
return bytes.Map(removeInvalidUtf, source)
}
func Benchmark_runeReplacement(b *testing.B) {
scenarios := map[string]string{
"with error rune": "hello�world",
"without error rune": "hello world",
}
for name, source := range scenarios {
b.Run(name, func(b *testing.B) {
b.Run("noop", func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
replaceNoop(source)
}
})
b.Run("contains and strings.Map()", func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
replaceContainsAndStringsMap(source)
}
})
b.Run("strings.Map()", func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
replaceStringsMap(source)
}
})
b.Run("contains and bytes.Map()", func(b *testing.B) {
bytesSource := []byte(source)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
replaceContainsAndBytesMap(bytesSource)
}
})
b.Run("bytes.Map()", func(b *testing.B) {
bytesSource := []byte(source)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
replaceBytesMap(bytesSource)
}
})
})
}
} here are the results of the benchmark
If you check the results, we can see that if we add the check if the value contains
and
Also, you can see that
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great, however, we need to address some small things to get it merged
pkg/logql/log/parser.go
Outdated
if r == utf8.RuneError { | ||
return "" | ||
return -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's necessary to replace it with
(whitespace) instead of skipping it
pkg/logql/log/parser.go
Outdated
} | ||
res = strings.Map(removeInvalidUtf, res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see: #14068 (comment)
res = strings.Map(removeInvalidUtf, res) | |
if strings.ContainsRune(source, utf8.RuneError) { | |
res = strings.Map(removeInvalidUtf, res) | |
} |
pkg/logql/log/parser.go
Outdated
for _, r := range res { | ||
|
||
// rune error is rejected by Prometheus hence replacing them with space | ||
removeInvalidUtf := func(r rune) rune { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: please move this function outside of unescapeJSONString
function to re-use it in logfmt parser ...
pkg/logql/log/parser.go
Outdated
val = nil | ||
|
||
// the rune error replacement is rejected by Prometheus hence skiping them. | ||
removeInvalidUtf := func(r rune) rune { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can be re-used from json parse
pkg/logql/log/parser.go
Outdated
} | ||
val = bytes.Map(removeInvalidUtf, val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see: #14068 (comment)
val = bytes.Map(removeInvalidUtf, val) | |
if bytes.ContainsRune(source, utf8.RuneError) { | |
val = bytes.Map(removeInvalidUtf, val) | |
} |
281976f
to
6d75586
Compare
@vlad-diachenko Thanks for the insights :) I have made the suggestion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks awesome 💎 🥇 huge thanks for the contribution @ravishankar15
What this PR does / why we need it:
Which issue(s) this PR fixes:
Fixes #13963
Special notes for your reviewer:
Checklist
CONTRIBUTING.md
guide (required)feat
PRs are unlikely to be accepted unless a case can be made for the feature actually being a bug fix to existing behavior.docs/sources/setup/upgrade/_index.md
production/helm/loki/Chart.yaml
and updateproduction/helm/loki/CHANGELOG.md
andproduction/helm/loki/README.md
. Example PRdeprecated-config.yaml
anddeleted-config.yaml
files respectively in thetools/deprecated-config-checker
directory. Example PR