mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Elasticsearch: Add log highlight processing on backend (#63924)
* Elasticsearch: Add highlight for logs * Fix running of queries trough backend only when shouldRunTroughBackend * Fix incorrect json in test string * Address feedback * Keep order of words same
This commit is contained in:
@@ -3,6 +3,7 @@ package elasticsearch
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -36,6 +37,8 @@ const (
|
||||
logsType = "logs"
|
||||
)
|
||||
|
||||
var searchWordsRegex = regexp.MustCompile(regexp.QuoteMeta(es.HighlightPreTagsString) + `(.*?)` + regexp.QuoteMeta(es.HighlightPostTagsString))
|
||||
|
||||
func parseResponse(responses []*es.SearchResponse, targets []*Query, configuredFields es.ConfiguredFields) (*backend.QueryDataResponse, error) {
|
||||
result := backend.QueryDataResponse{
|
||||
Responses: backend.Responses{},
|
||||
@@ -94,6 +97,7 @@ func parseResponse(responses []*es.SearchResponse, targets []*Query, configuredF
|
||||
func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields es.ConfiguredFields, queryRes *backend.DataResponse) error {
|
||||
propNames := make(map[string]bool)
|
||||
docs := make([]map[string]interface{}, len(res.Hits.Hits))
|
||||
searchWords := make(map[string]bool)
|
||||
|
||||
for hitIdx, hit := range res.Hits.Hits {
|
||||
var flattened map[string]interface{}
|
||||
@@ -121,7 +125,22 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields
|
||||
for key := range doc {
|
||||
propNames[key] = true
|
||||
}
|
||||
// TODO: Implement highlighting
|
||||
|
||||
// Process highlight to searchWords
|
||||
if highlights, ok := doc["highlight"].(map[string]interface{}); ok {
|
||||
for _, highlight := range highlights {
|
||||
if highlightList, ok := highlight.([]interface{}); ok {
|
||||
for _, highlightValue := range highlightList {
|
||||
str := fmt.Sprintf("%v", highlightValue)
|
||||
matches := searchWordsRegex.FindAllStringSubmatch(str, -1)
|
||||
|
||||
for _, v := range matches {
|
||||
searchWords[v[1]] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
docs[hitIdx] = doc
|
||||
}
|
||||
@@ -132,6 +151,7 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields
|
||||
frames := data.Frames{}
|
||||
frame := data.NewFrame("", fields...)
|
||||
setPreferredVisType(frame, "logs")
|
||||
setSearchWords(frame, searchWords)
|
||||
frames = append(frames, frame)
|
||||
|
||||
queryRes.Frames = frames
|
||||
@@ -1073,3 +1093,25 @@ func setPreferredVisType(frame *data.Frame, visType data.VisType) {
|
||||
|
||||
frame.Meta.PreferredVisualization = visType
|
||||
}
|
||||
|
||||
func setSearchWords(frame *data.Frame, searchWords map[string]bool) {
|
||||
i := 0
|
||||
searchWordsList := make([]string, len(searchWords))
|
||||
for searchWord := range searchWords {
|
||||
searchWordsList[i] = searchWord
|
||||
i++
|
||||
}
|
||||
sort.Strings(searchWordsList)
|
||||
|
||||
if frame.Meta == nil {
|
||||
frame.Meta = &data.FrameMeta{}
|
||||
}
|
||||
|
||||
if frame.Meta.Custom == nil {
|
||||
frame.Meta.Custom = map[string]interface{}{}
|
||||
}
|
||||
|
||||
frame.Meta.Custom = map[string]interface{}{
|
||||
"searchWords": searchWordsList,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user