@@ -25,13 +25,14 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/log"
|
||||
es "kubesphere.io/kubesphere/pkg/simple/client/elasticsearch"
|
||||
fb "kubesphere.io/kubesphere/pkg/simple/client/fluentbit"
|
||||
"kubesphere.io/kubesphere/pkg/utils/stringutils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func LoggingQueryCluster(request *restful.Request, response *restful.Response) {
|
||||
res := logQuery(log.QueryLevelCluster, request)
|
||||
|
||||
if res.Status != http.StatusOK {
|
||||
response.WriteHeaderAndEntity(res.Status, errors.New(res.Error))
|
||||
return
|
||||
@@ -42,7 +43,6 @@ func LoggingQueryCluster(request *restful.Request, response *restful.Response) {
|
||||
|
||||
func LoggingQueryWorkspace(request *restful.Request, response *restful.Response) {
|
||||
res := logQuery(log.QueryLevelWorkspace, request)
|
||||
|
||||
if res.Status != http.StatusOK {
|
||||
response.WriteHeaderAndEntity(res.Status, errors.New(res.Error))
|
||||
return
|
||||
@@ -53,7 +53,6 @@ func LoggingQueryWorkspace(request *restful.Request, response *restful.Response)
|
||||
|
||||
func LoggingQueryNamespace(request *restful.Request, response *restful.Response) {
|
||||
res := logQuery(log.QueryLevelNamespace, request)
|
||||
|
||||
if res.Status != http.StatusOK {
|
||||
response.WriteHeaderAndEntity(res.Status, errors.New(res.Error))
|
||||
return
|
||||
@@ -160,79 +159,66 @@ func LoggingDeleteFluentbitOutput(request *restful.Request, response *restful.Re
|
||||
}
|
||||
|
||||
func logQuery(level log.LogQueryLevel, request *restful.Request) *es.QueryResult {
|
||||
var param es.QueryParameters
|
||||
|
||||
param.Operation = request.QueryParameter("operation")
|
||||
var param es.QueryParameters
|
||||
|
||||
switch level {
|
||||
case log.QueryLevelCluster:
|
||||
{
|
||||
param.NamespaceFilled, param.Namespaces = log.QueryWorkspace(request.QueryParameter("workspaces"), request.QueryParameter("workspace_query"))
|
||||
param.NamespaceFilled, param.Namespaces = log.MatchNamespace(request.QueryParameter("namespaces"), param.NamespaceFilled, param.Namespaces)
|
||||
param.NamespaceFilled, param.NamespaceWithCreationTime = log.GetNamespaceCreationTimeMap(param.Namespaces)
|
||||
param.NamespaceQuery = request.QueryParameter("namespace_query")
|
||||
param.PodFilled, param.Pods = log.QueryWorkload(request.QueryParameter("workloads"), request.QueryParameter("workload_query"), param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.MatchPod(request.QueryParameter("pods"), param.PodFilled, param.Pods)
|
||||
param.PodQuery = request.QueryParameter("pod_query")
|
||||
param.ContainerFilled, param.Containers = log.MatchContainer(request.QueryParameter("containers"))
|
||||
param.ContainerQuery = request.QueryParameter("container_query")
|
||||
}
|
||||
var namespaces []string
|
||||
param.NamespaceNotFound, namespaces = log.MatchNamespace(stringutils.Split(request.QueryParameter("namespaces"), ","),
|
||||
stringutils.Split(strings.ToLower(request.QueryParameter("namespace_query")), ","), // case-insensitive
|
||||
stringutils.Split(request.QueryParameter("workspaces"), ","),
|
||||
stringutils.Split(strings.ToLower(request.QueryParameter("workspace_query")), ",")) // case-insensitive
|
||||
param.NamespaceWithCreationTime = log.MakeNamespaceCreationTimeMap(namespaces)
|
||||
param.WorkloadNotFound, param.WorkloadFilter = log.MatchWorkload(request.QueryParameter("workloads"), request.QueryParameter("workload_query"), namespaces)
|
||||
param.PodFilter = stringutils.Split(request.QueryParameter("pods"), ",")
|
||||
param.PodQuery = stringutils.Split(request.QueryParameter("pod_query"), ",")
|
||||
param.ContainerFilter = stringutils.Split(request.QueryParameter("containers"), ",")
|
||||
param.ContainerQuery = stringutils.Split(request.QueryParameter("container_query"), ",")
|
||||
case log.QueryLevelWorkspace:
|
||||
{
|
||||
param.NamespaceFilled, param.Namespaces = log.QueryWorkspace(request.PathParameter("workspace"), "")
|
||||
param.NamespaceFilled, param.Namespaces = log.MatchNamespace(request.QueryParameter("namespaces"), param.NamespaceFilled, param.Namespaces)
|
||||
param.NamespaceFilled, param.NamespaceWithCreationTime = log.GetNamespaceCreationTimeMap(param.Namespaces)
|
||||
param.NamespaceQuery = request.QueryParameter("namespace_query")
|
||||
param.PodFilled, param.Pods = log.QueryWorkload(request.QueryParameter("workloads"), request.QueryParameter("workload_query"), param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.MatchPod(request.QueryParameter("pods"), param.PodFilled, param.Pods)
|
||||
param.PodQuery = request.QueryParameter("pod_query")
|
||||
param.ContainerFilled, param.Containers = log.MatchContainer(request.QueryParameter("containers"))
|
||||
param.ContainerQuery = request.QueryParameter("container_query")
|
||||
}
|
||||
var namespaces []string
|
||||
param.NamespaceNotFound, namespaces = log.MatchNamespace(stringutils.Split(request.QueryParameter("namespaces"), ","),
|
||||
stringutils.Split(strings.ToLower(request.QueryParameter("namespace_query")), ","), // case-insensitive
|
||||
stringutils.Split(request.PathParameter("workspace"), ","), nil) // case-insensitive
|
||||
param.NamespaceWithCreationTime = log.MakeNamespaceCreationTimeMap(namespaces)
|
||||
param.WorkloadNotFound, param.WorkloadFilter = log.MatchWorkload(request.QueryParameter("workloads"), request.QueryParameter("workload_query"), namespaces)
|
||||
param.PodFilter = stringutils.Split(request.QueryParameter("pods"), ",")
|
||||
param.PodQuery = stringutils.Split(request.QueryParameter("pod_query"), ",")
|
||||
param.ContainerFilter = stringutils.Split(request.QueryParameter("containers"), ",")
|
||||
param.ContainerQuery = stringutils.Split(request.QueryParameter("container_query"), ",")
|
||||
case log.QueryLevelNamespace:
|
||||
{
|
||||
param.NamespaceFilled, param.Namespaces = log.MatchNamespace(request.PathParameter("namespace"), false, nil)
|
||||
param.NamespaceFilled, param.NamespaceWithCreationTime = log.GetNamespaceCreationTimeMap(param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.QueryWorkload(request.QueryParameter("workloads"), request.QueryParameter("workload_query"), param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.MatchPod(request.QueryParameter("pods"), param.PodFilled, param.Pods)
|
||||
param.PodQuery = request.QueryParameter("pod_query")
|
||||
param.ContainerFilled, param.Containers = log.MatchContainer(request.QueryParameter("containers"))
|
||||
param.ContainerQuery = request.QueryParameter("container_query")
|
||||
}
|
||||
namespaces := []string{request.PathParameter("namespace")}
|
||||
param.NamespaceWithCreationTime = log.MakeNamespaceCreationTimeMap(namespaces)
|
||||
param.WorkloadNotFound, param.WorkloadFilter = log.MatchWorkload(request.QueryParameter("workloads"), request.QueryParameter("workload_query"), namespaces)
|
||||
param.PodFilter = stringutils.Split(request.QueryParameter("pods"), ",")
|
||||
param.PodQuery = stringutils.Split(request.QueryParameter("pod_query"), ",")
|
||||
param.ContainerFilter = stringutils.Split(request.QueryParameter("containers"), ",")
|
||||
param.ContainerQuery = stringutils.Split(request.QueryParameter("container_query"), ",")
|
||||
case log.QueryLevelWorkload:
|
||||
{
|
||||
param.NamespaceFilled, param.Namespaces = log.MatchNamespace(request.PathParameter("namespace"), false, nil)
|
||||
param.NamespaceFilled, param.NamespaceWithCreationTime = log.GetNamespaceCreationTimeMap(param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.QueryWorkload(request.PathParameter("workload"), "", param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.MatchPod(request.QueryParameter("pods"), param.PodFilled, param.Pods)
|
||||
param.PodQuery = request.QueryParameter("pod_query")
|
||||
param.ContainerFilled, param.Containers = log.MatchContainer(request.QueryParameter("containers"))
|
||||
param.ContainerQuery = request.QueryParameter("container_query")
|
||||
}
|
||||
namespaces := []string{request.PathParameter("namespace")}
|
||||
param.NamespaceWithCreationTime = log.MakeNamespaceCreationTimeMap(namespaces)
|
||||
param.WorkloadNotFound, param.WorkloadFilter = log.MatchWorkload(request.PathParameter("workload"), "", namespaces)
|
||||
param.PodFilter = stringutils.Split(request.QueryParameter("pods"), ",")
|
||||
param.PodQuery = stringutils.Split(request.QueryParameter("pod_query"), ",")
|
||||
param.ContainerFilter = stringutils.Split(request.QueryParameter("containers"), ",")
|
||||
param.ContainerQuery = stringutils.Split(request.QueryParameter("container_query"), ",")
|
||||
case log.QueryLevelPod:
|
||||
{
|
||||
param.NamespaceFilled, param.Namespaces = log.MatchNamespace(request.PathParameter("namespace"), false, nil)
|
||||
param.NamespaceFilled, param.NamespaceWithCreationTime = log.GetNamespaceCreationTimeMap(param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.MatchPod(request.PathParameter("pod"), false, nil)
|
||||
param.ContainerFilled, param.Containers = log.MatchContainer(request.QueryParameter("containers"))
|
||||
param.ContainerQuery = request.QueryParameter("container_query")
|
||||
}
|
||||
namespaces := []string{request.PathParameter("namespace")}
|
||||
param.NamespaceWithCreationTime = log.MakeNamespaceCreationTimeMap(namespaces)
|
||||
param.PodFilter = []string{request.PathParameter("pod")}
|
||||
param.ContainerFilter = stringutils.Split(request.QueryParameter("containers"), ",")
|
||||
param.ContainerQuery = stringutils.Split(request.QueryParameter("container_query"), ",")
|
||||
case log.QueryLevelContainer:
|
||||
{
|
||||
param.NamespaceFilled, param.Namespaces = log.MatchNamespace(request.PathParameter("namespace"), false, nil)
|
||||
param.NamespaceFilled, param.NamespaceWithCreationTime = log.GetNamespaceCreationTimeMap(param.Namespaces)
|
||||
param.PodFilled, param.Pods = log.MatchPod(request.PathParameter("pod"), false, nil)
|
||||
param.ContainerFilled, param.Containers = log.MatchContainer(request.PathParameter("container"))
|
||||
}
|
||||
namespaces := []string{request.PathParameter("namespace")}
|
||||
param.NamespaceWithCreationTime = log.MakeNamespaceCreationTimeMap(namespaces)
|
||||
param.PodFilter = []string{request.PathParameter("pod")}
|
||||
param.ContainerFilter = []string{request.PathParameter("container")}
|
||||
}
|
||||
|
||||
if len(param.Namespaces) == 1 {
|
||||
param.Workspace = log.GetWorkspaceOfNamesapce(param.Namespaces[0])
|
||||
}
|
||||
param.LogQuery = stringutils.Split(request.QueryParameter("log_query"), ",")
|
||||
|
||||
param.Operation = request.QueryParameter("operation")
|
||||
param.Interval = request.QueryParameter("interval")
|
||||
|
||||
param.LogQuery = request.QueryParameter("log_query")
|
||||
param.StartTime = request.QueryParameter("start_time")
|
||||
param.EndTime = request.QueryParameter("end_time")
|
||||
param.Sort = request.QueryParameter("sort")
|
||||
|
||||
@@ -23,40 +23,13 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/utils/stringutils"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func intersection(s1, s2 []string) (inter []string) {
|
||||
hash := make(map[string]bool)
|
||||
for _, e := range s1 {
|
||||
hash[e] = true
|
||||
}
|
||||
for _, e := range s2 {
|
||||
// If elements present in the hashmap then append intersection list.
|
||||
if hash[e] {
|
||||
inter = append(inter, e)
|
||||
}
|
||||
}
|
||||
//Remove dups from slice.
|
||||
inter = removeDups(inter)
|
||||
return
|
||||
}
|
||||
|
||||
//Remove dups from slice.
|
||||
func removeDups(elements []string) (nodups []string) {
|
||||
encountered := make(map[string]bool)
|
||||
for _, element := range elements {
|
||||
if !encountered[element] {
|
||||
nodups = append(nodups, element)
|
||||
encountered[element] = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func in(value interface{}, container interface{}) int {
|
||||
if container == nil {
|
||||
return -1
|
||||
@@ -116,105 +89,68 @@ func queryLabel(label string, labelsQuery []string) bool {
|
||||
return result
|
||||
}
|
||||
|
||||
func QueryWorkspace(workspaceMatch string, workspaceQuery string) (bool, []string) {
|
||||
if workspaceMatch == "" && workspaceQuery == "" {
|
||||
return false, nil
|
||||
}
|
||||
// list namespaces that match search conditions
|
||||
func MatchNamespace(nsFilter []string, nsQuery []string, wsFilter []string, wsQuery []string) (bool, []string) {
|
||||
|
||||
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
nsList, err := nsLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
glog.Error("failed to list namespace, error: ", err)
|
||||
glog.Errorf("failed to list namespace, error: %s", err)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var namespaces []string
|
||||
|
||||
var hasMatch = false
|
||||
var workspacesMatch []string
|
||||
if workspaceMatch != "" {
|
||||
workspacesMatch = strings.Split(strings.Replace(workspaceMatch, ",", " ", -1), " ")
|
||||
hasMatch = true
|
||||
}
|
||||
|
||||
var hasQuery = false
|
||||
var workspacesQuery []string
|
||||
if workspaceQuery != "" {
|
||||
workspacesQuery = strings.Split(strings.ToLower(strings.Replace(workspaceQuery, ",", " ", -1)), " ")
|
||||
hasQuery = true
|
||||
// if no search condition is set on both namespace and workspace,
|
||||
// then return all namespaces
|
||||
if nsQuery == nil && nsFilter == nil && wsQuery == nil && wsFilter == nil {
|
||||
for _, ns := range nsList {
|
||||
namespaces = append(namespaces, ns.Name)
|
||||
}
|
||||
return false, namespaces
|
||||
}
|
||||
|
||||
for _, ns := range nsList {
|
||||
labels := ns.GetLabels()
|
||||
_, ok := labels[constants.WorkspaceLabelKey]
|
||||
if ok {
|
||||
var namespaceCanAppend = true
|
||||
if hasMatch {
|
||||
if !matchLabel(labels[constants.WorkspaceLabelKey], workspacesMatch) {
|
||||
namespaceCanAppend = false
|
||||
}
|
||||
}
|
||||
if hasQuery {
|
||||
if !queryLabel(strings.ToLower(labels[constants.WorkspaceLabelKey]), workspacesQuery) {
|
||||
namespaceCanAppend = false
|
||||
}
|
||||
}
|
||||
|
||||
if namespaceCanAppend {
|
||||
namespaces = append(namespaces, ns.GetName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true, namespaces
|
||||
}
|
||||
|
||||
func MatchNamespace(namespaceMatch string, namespaceFilled bool, namespaces []string) (bool, []string) {
|
||||
if namespaceMatch == "" {
|
||||
return namespaceFilled, namespaces
|
||||
}
|
||||
|
||||
namespacesMatch := strings.Split(strings.Replace(namespaceMatch, ",", " ", -1), " ")
|
||||
|
||||
if namespaceFilled {
|
||||
return true, intersection(namespacesMatch, namespaces)
|
||||
}
|
||||
|
||||
return true, namespacesMatch
|
||||
}
|
||||
|
||||
func GetNamespaceCreationTimeMap(namespaces []string) (bool, map[string]string) {
|
||||
|
||||
namespaceWithCreationTime := make(map[string]string)
|
||||
|
||||
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
|
||||
if len(namespaces) == 0 {
|
||||
nsList, err := nsLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
glog.Error("failed to list namespace, error: ", err)
|
||||
return true, namespaceWithCreationTime
|
||||
}
|
||||
|
||||
for _, ns := range nsList {
|
||||
if stringutils.StringIn(ns.Name, nsFilter) ||
|
||||
stringutils.StringIn(ns.Annotations[constants.WorkspaceLabelKey], wsFilter) ||
|
||||
containsIn(ns.Name, nsQuery) ||
|
||||
containsIn(ns.Annotations[constants.WorkspaceLabelKey], wsQuery) {
|
||||
namespaces = append(namespaces, ns.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// if namespaces is equal to nil, indicates no namespace matched
|
||||
// it causes the query to return no result
|
||||
return namespaces == nil, namespaces
|
||||
}
|
||||
|
||||
func containsIn(str string, subStrs []string) bool {
|
||||
for _, sub := range subStrs {
|
||||
if strings.Contains(str, sub) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func MakeNamespaceCreationTimeMap(namespaces []string) map[string]string {
|
||||
|
||||
namespaceWithCreationTime := make(map[string]string)
|
||||
|
||||
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
for _, item := range namespaces {
|
||||
ns, err := nsLister.Get(item)
|
||||
if err != nil {
|
||||
glog.Error("failed to get namespace, error: ", err)
|
||||
// the ns doesn't exist
|
||||
continue
|
||||
}
|
||||
|
||||
namespaceWithCreationTime[ns.Name] = strconv.FormatInt(ns.CreationTimestamp.UnixNano()/int64(time.Millisecond), 10)
|
||||
}
|
||||
|
||||
return true, namespaceWithCreationTime
|
||||
return namespaceWithCreationTime
|
||||
}
|
||||
|
||||
func QueryWorkload(workloadMatch string, workloadQuery string, namespaces []string) (bool, []string) {
|
||||
func MatchWorkload(workloadMatch string, workloadQuery string, namespaces []string) (bool, []string) {
|
||||
if workloadMatch == "" && workloadQuery == "" {
|
||||
return false, nil
|
||||
}
|
||||
@@ -292,51 +228,7 @@ func QueryWorkload(workloadMatch string, workloadQuery string, namespaces []stri
|
||||
}
|
||||
}
|
||||
|
||||
return true, pods
|
||||
}
|
||||
|
||||
func MatchPod(podMatch string, podFilled bool, pods []string) (bool, []string) {
|
||||
if podMatch == "" {
|
||||
return podFilled, pods
|
||||
}
|
||||
|
||||
podsMatch := strings.Split(strings.Replace(podMatch, ",", " ", -1), " ")
|
||||
|
||||
if podFilled {
|
||||
return true, intersection(podsMatch, pods)
|
||||
}
|
||||
|
||||
return true, podsMatch
|
||||
}
|
||||
|
||||
func MatchContainer(containerMatch string) (bool, []string) {
|
||||
if containerMatch == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, strings.Split(strings.Replace(containerMatch, ",", " ", -1), " ")
|
||||
}
|
||||
|
||||
func GetWorkspaceOfNamesapce(namespace string) string {
|
||||
var workspace string
|
||||
workspace = ""
|
||||
|
||||
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
nsList, err := nsLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
glog.Error("failed to list namespace, error: ", err)
|
||||
return workspace
|
||||
}
|
||||
|
||||
for _, ns := range nsList {
|
||||
if ns.GetName() == namespace {
|
||||
labels := ns.GetLabels()
|
||||
_, ok := labels[constants.WorkspaceLabelKey]
|
||||
if ok {
|
||||
workspace = labels[constants.WorkspaceLabelKey]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return workspace
|
||||
// if workloads is equal to nil, indicates no workload matched
|
||||
// it causes the query to return no result
|
||||
return pods == nil, pods
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@ import (
|
||||
"github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
const (
|
||||
matchPhrase = iota
|
||||
matchPhrasePrefix
|
||||
|
||||
fieldNamespaceName = "kubernetes.namespace_name"
|
||||
fieldPodName = "kubernetes.pod_name"
|
||||
fieldContainerName = "kubernetes.container_name"
|
||||
fieldLog = "log"
|
||||
)
|
||||
|
||||
var jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
var (
|
||||
@@ -73,11 +83,20 @@ type Order struct {
|
||||
}
|
||||
|
||||
type BoolQuery struct {
|
||||
BoolMusts BoolMusts `json:"bool"`
|
||||
Bool interface{} `json:"bool"`
|
||||
}
|
||||
|
||||
type BoolMusts struct {
|
||||
Musts []interface{} `json:"must"`
|
||||
type FilterContext struct {
|
||||
Filter []interface{} `json:"must"`
|
||||
}
|
||||
|
||||
type BoolMust struct {
|
||||
Must []interface{} `json:"must"`
|
||||
}
|
||||
|
||||
type BoolShould struct {
|
||||
Should []interface{} `json:"should"`
|
||||
MinimumShouldMatch int64 `json:"minimum_should_match"`
|
||||
}
|
||||
|
||||
type RangeQuery struct {
|
||||
@@ -93,25 +112,12 @@ type TimeRange struct {
|
||||
Lte string `json:"lte,omitempty"`
|
||||
}
|
||||
|
||||
type BoolShouldMatchPhrase struct {
|
||||
ShouldMatchPhrase ShouldMatchPhrase `json:"bool"`
|
||||
}
|
||||
|
||||
type ShouldMatchPhrase struct {
|
||||
Shoulds []interface{} `json:"should"`
|
||||
MinimumShouldMatch int64 `json:"minimum_should_match"`
|
||||
}
|
||||
|
||||
type MatchPhrase struct {
|
||||
MatchPhrase interface{} `json:"match_phrase"`
|
||||
MatchPhrase map[string]string `json:"match_phrase"`
|
||||
}
|
||||
|
||||
type Match struct {
|
||||
Match interface{} `json:"match"`
|
||||
}
|
||||
|
||||
type QueryWord struct {
|
||||
Word string `json:"query"`
|
||||
type MatchPhrasePrefix struct {
|
||||
MatchPhrasePrefix interface{} `json:"match_phrase_prefix"`
|
||||
}
|
||||
|
||||
type MainHighLight struct {
|
||||
@@ -166,78 +172,52 @@ type DateHistogram struct {
|
||||
|
||||
func createQueryRequest(param QueryParameters) (int, []byte, error) {
|
||||
var request Request
|
||||
var mainBoolQuery BoolMusts
|
||||
var mainBoolQuery FilterContext
|
||||
|
||||
if param.NamespaceFilled {
|
||||
var shouldMatchPhrase ShouldMatchPhrase
|
||||
if len(param.NamespaceWithCreationTime) == 0 {
|
||||
matchPhrase := MatchPhrase{map[string]interface{}{"kubernetes.namespace_name.key_word": QueryWord{""}}}
|
||||
shouldMatchPhrase.Shoulds = append(shouldMatchPhrase.Shoulds, matchPhrase)
|
||||
} else {
|
||||
for namespace, creationTime := range param.NamespaceWithCreationTime {
|
||||
var boolQuery BoolQuery
|
||||
if len(param.NamespaceWithCreationTime) != 0 {
|
||||
var boolShoulds BoolShould
|
||||
for namespace, creationTime := range param.NamespaceWithCreationTime {
|
||||
var boolMusts BoolMust
|
||||
|
||||
matchPhrase := MatchPhrase{map[string]interface{}{"kubernetes.namespace_name.keyword": QueryWord{namespace}}}
|
||||
rangeQuery := RangeQuery{RangeSpec{TimeRange{creationTime, ""}}}
|
||||
matchPhrase := MatchPhrase{MatchPhrase: map[string]string{fieldNamespaceName: namespace}}
|
||||
rangeQuery := RangeQuery{RangeSpec{TimeRange{creationTime, ""}}}
|
||||
|
||||
boolQuery.BoolMusts.Musts = append(boolQuery.BoolMusts.Musts, matchPhrase)
|
||||
boolQuery.BoolMusts.Musts = append(boolQuery.BoolMusts.Musts, rangeQuery)
|
||||
boolMusts.Must = append(boolMusts.Must, matchPhrase)
|
||||
boolMusts.Must = append(boolMusts.Must, rangeQuery)
|
||||
|
||||
shouldMatchPhrase.Shoulds = append(shouldMatchPhrase.Shoulds, boolQuery)
|
||||
}
|
||||
boolShoulds.Should = append(boolShoulds.Should, BoolQuery{Bool: boolMusts})
|
||||
}
|
||||
shouldMatchPhrase.MinimumShouldMatch = 1
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, BoolShouldMatchPhrase{shouldMatchPhrase})
|
||||
boolShoulds.MinimumShouldMatch = 1
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, BoolQuery{Bool: boolShoulds})
|
||||
}
|
||||
if param.PodFilled {
|
||||
var shouldMatchPhrase ShouldMatchPhrase
|
||||
if len(param.Pods) == 0 {
|
||||
matchPhrase := MatchPhrase{map[string]interface{}{"kubernetes.pod_name.key_word": QueryWord{""}}}
|
||||
shouldMatchPhrase.Shoulds = append(shouldMatchPhrase.Shoulds, matchPhrase)
|
||||
} else {
|
||||
for _, pod := range param.Pods {
|
||||
matchPhrase := MatchPhrase{map[string]interface{}{"kubernetes.pod_name.keyword": QueryWord{pod}}}
|
||||
shouldMatchPhrase.Shoulds = append(shouldMatchPhrase.Shoulds, matchPhrase)
|
||||
}
|
||||
}
|
||||
shouldMatchPhrase.MinimumShouldMatch = 1
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, BoolShouldMatchPhrase{shouldMatchPhrase})
|
||||
if param.WorkloadFilter != nil {
|
||||
boolQuery := makeBoolShould(matchPhrase, fieldPodName, param.WorkloadFilter)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, boolQuery)
|
||||
}
|
||||
if param.ContainerFilled {
|
||||
var shouldMatchPhrase ShouldMatchPhrase
|
||||
if len(param.Containers) == 0 {
|
||||
matchPhrase := MatchPhrase{map[string]interface{}{"kubernetes.container_name.key_word": QueryWord{""}}}
|
||||
shouldMatchPhrase.Shoulds = append(shouldMatchPhrase.Shoulds, matchPhrase)
|
||||
} else {
|
||||
for _, container := range param.Containers {
|
||||
matchPhrase := MatchPhrase{map[string]interface{}{"kubernetes.container_name.keyword": QueryWord{container}}}
|
||||
shouldMatchPhrase.Shoulds = append(shouldMatchPhrase.Shoulds, matchPhrase)
|
||||
}
|
||||
}
|
||||
shouldMatchPhrase.MinimumShouldMatch = 1
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, BoolShouldMatchPhrase{shouldMatchPhrase})
|
||||
if param.PodFilter != nil {
|
||||
boolQuery := makeBoolShould(matchPhrase, fieldPodName, param.PodFilter)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, boolQuery)
|
||||
}
|
||||
if param.ContainerFilter != nil {
|
||||
boolQuery := makeBoolShould(matchPhrase, fieldContainerName, param.ContainerFilter)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, boolQuery)
|
||||
}
|
||||
|
||||
if param.NamespaceQuery != "" {
|
||||
match := Match{map[string]interface{}{"kubernetes.namespace_name": QueryWord{param.NamespaceQuery}}}
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, match)
|
||||
if param.PodQuery != nil {
|
||||
boolQuery := makeBoolShould(matchPhrasePrefix, fieldPodName, param.PodQuery)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, boolQuery)
|
||||
}
|
||||
if param.PodQuery != "" {
|
||||
match := Match{map[string]interface{}{"kubernetes.pod_name": QueryWord{param.PodQuery}}}
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, match)
|
||||
if param.ContainerQuery != nil {
|
||||
boolQuery := makeBoolShould(matchPhrasePrefix, fieldContainerName, param.ContainerQuery)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, boolQuery)
|
||||
}
|
||||
if param.ContainerQuery != "" {
|
||||
match := Match{map[string]interface{}{"kubernetes.container_name": QueryWord{param.ContainerQuery}}}
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, match)
|
||||
}
|
||||
|
||||
if param.LogQuery != "" {
|
||||
match := Match{map[string]interface{}{"log": QueryWord{param.LogQuery}}}
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, match)
|
||||
if param.LogQuery != nil {
|
||||
boolQuery := makeBoolShould(matchPhrasePrefix, fieldLog, param.LogQuery)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, boolQuery)
|
||||
}
|
||||
|
||||
rangeQuery := RangeQuery{RangeSpec{TimeRange{param.StartTime, param.EndTime}}}
|
||||
mainBoolQuery.Musts = append(mainBoolQuery.Musts, rangeQuery)
|
||||
mainBoolQuery.Filter = append(mainBoolQuery.Filter, rangeQuery)
|
||||
|
||||
var operation int
|
||||
|
||||
@@ -286,6 +266,30 @@ func createQueryRequest(param QueryParameters) (int, []byte, error) {
|
||||
return operation, queryRequest, err
|
||||
}
|
||||
|
||||
func makeBoolShould(queryType int, field string, list []string) BoolQuery {
|
||||
var should []interface{}
|
||||
for _, phrase := range list {
|
||||
|
||||
var q interface{}
|
||||
|
||||
switch queryType {
|
||||
case matchPhrase:
|
||||
q = MatchPhrase{MatchPhrase: map[string]string{field: phrase}}
|
||||
case matchPhrasePrefix:
|
||||
q = MatchPhrasePrefix{MatchPhrasePrefix: map[string]string{field: phrase}}
|
||||
}
|
||||
|
||||
should = append(should, q)
|
||||
}
|
||||
|
||||
return BoolQuery{
|
||||
Bool: BoolShould{
|
||||
Should: should,
|
||||
MinimumShouldMatch: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Fore more info, refer to https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-search-API.html
|
||||
// Response from the elasticsearch engine
|
||||
type Response struct {
|
||||
@@ -396,7 +400,6 @@ type HistogramResult struct {
|
||||
type QueryResult struct {
|
||||
Status int `json:"status,omitempty" description:"query status"`
|
||||
Error string `json:"error,omitempty" description:"debugging information"`
|
||||
Workspace string `json:"workspace,omitempty" description:"the name of the workspace where logs come from"`
|
||||
Read *ReadResult `json:"query,omitempty" description:"query results"`
|
||||
Statistics *StatisticsResult `json:"statistics,omitempty" description:"statistics results"`
|
||||
Histogram *HistogramResult `json:"histogram,omitempty" description:"histogram results"`
|
||||
@@ -513,28 +516,29 @@ func parseQueryResult(operation int, param QueryParameters, body []byte) *QueryR
|
||||
}
|
||||
|
||||
queryResult.Status = http.StatusOK
|
||||
queryResult.Workspace = param.Workspace
|
||||
|
||||
return &queryResult
|
||||
}
|
||||
|
||||
type QueryParameters struct {
|
||||
NamespaceFilled bool
|
||||
Namespaces []string
|
||||
// when true, indicates the provided `namespaces` or `namespace_query` doesn't match any namespace
|
||||
NamespaceNotFound bool
|
||||
// a map of namespace with creation time
|
||||
NamespaceWithCreationTime map[string]string
|
||||
PodFilled bool
|
||||
Pods []string
|
||||
ContainerFilled bool
|
||||
Containers []string
|
||||
|
||||
NamespaceQuery string
|
||||
PodQuery string
|
||||
ContainerQuery string
|
||||
// when true, indicates the provided `workloads` or `workload_query` doesn't match any workload
|
||||
WorkloadNotFound bool
|
||||
WorkloadFilter []string
|
||||
|
||||
Workspace string
|
||||
PodFilter []string
|
||||
PodQuery []string
|
||||
|
||||
ContainerFilter []string
|
||||
ContainerQuery []string
|
||||
|
||||
LogQuery []string
|
||||
|
||||
Operation string
|
||||
LogQuery string
|
||||
Interval string
|
||||
StartTime string
|
||||
EndTime string
|
||||
@@ -547,6 +551,23 @@ func Query(param QueryParameters) *QueryResult {
|
||||
|
||||
var queryResult = new(QueryResult)
|
||||
|
||||
if param.NamespaceNotFound || param.WorkloadNotFound {
|
||||
queryResult = new(QueryResult)
|
||||
queryResult.Status = http.StatusOK
|
||||
switch param.Operation {
|
||||
case "statistics":
|
||||
queryResult.Statistics = new(StatisticsResult)
|
||||
case "histogram":
|
||||
queryResult.Histogram = &HistogramResult{
|
||||
StartTime: calcTimestamp(param.StartTime),
|
||||
EndTime: calcTimestamp(param.EndTime),
|
||||
Interval: param.Interval}
|
||||
default:
|
||||
queryResult.Read = new(ReadResult)
|
||||
}
|
||||
return queryResult
|
||||
}
|
||||
|
||||
if client == nil {
|
||||
queryResult.Status = http.StatusBadRequest
|
||||
queryResult.Error = fmt.Sprintf("Invalid elasticsearch address: host=%s, port=%s", config.Host, config.Port)
|
||||
|
||||
@@ -14,6 +14,7 @@ limitations under the License.
|
||||
package stringutils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
@@ -75,3 +76,10 @@ func Reverse(s string) string {
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func Split(str string, sep string) []string {
|
||||
if str == "" {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(str, sep)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user