Support reverse query function for query log (#1298)

This commit is contained in:
moluzhang
2019-09-02 18:02:07 +08:00
committed by Ta-Ching Chen
parent 58811ab522
commit 62016b2f83
4 changed files with 13 additions and 13 deletions
+3
View File
@@ -730,6 +730,8 @@ func fnLogs(c *cli.Context) error {
Namespace: fnNamespace, Namespace: fnNamespace,
} }
logReverseQuery := !c.Bool("f") && c.Bool("r")
recordLimit := c.Int("recordcount") recordLimit := c.Int("recordcount")
if recordLimit <= 0 { if recordLimit <= 0 {
recordLimit = 1000 recordLimit = 1000
@@ -758,6 +760,7 @@ func fnLogs(c *cli.Context) error {
Function: f.Metadata.Name, Function: f.Metadata.Name,
FuncUid: string(f.Metadata.UID), FuncUid: string(f.Metadata.UID),
Since: t, Since: t,
Reverse: logReverseQuery,
RecordLimit: recordLimit, RecordLimit: recordLimit,
} }
logEntries, err := logDB.GetLogs(logFilter) logEntries, err := logDB.GetLogs(logFilter)
+7 -12
View File
@@ -22,7 +22,6 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -66,13 +65,18 @@ func (influx InfluxDB) GetLogs(filter LogFilter) ([]LogEntry, error) {
parameters["time"] = timestamp parameters["time"] = timestamp
//the parameters above are only for the where clause and do not work with LIMIT //the parameters above are only for the where clause and do not work with LIMIT
orderCondition := " order by \"time\" asc"
if filter.Reverse {
orderCondition = " order by \"time\" desc"
}
if filter.Pod != "" { if filter.Pod != "" {
// wait for bug fix for fluent-bit influxdb plugin // wait for bug fix for fluent-bit influxdb plugin
queryCmd = "select * from /^log*/ where (\"funcuid\" = $funcuid OR \"kubernetes_labels_functionUid\" = $funcuid) AND \"pod\" = $pod AND \"time\" > $time LIMIT " + strconv.Itoa(filter.RecordLimit) queryCmd = "select * from /^log*/ where (\"funcuid\" = $funcuid OR \"kubernetes_labels_functionUid\" = $funcuid) AND \"pod\" = $pod AND \"time\" > $time " + orderCondition + " LIMIT " + strconv.Itoa(filter.RecordLimit)
parameters["pod"] = filter.Pod parameters["pod"] = filter.Pod
} else { } else {
// wait for bug fix for fluent-bit influxdb plugin // wait for bug fix for fluent-bit influxdb plugin
queryCmd = "select * from /^log*/ where (\"funcuid\" = $funcuid OR \"kubernetes_labels_functionUid\" = $funcuid) AND \"time\" > $time LIMIT " + strconv.Itoa(filter.RecordLimit) queryCmd = "select * from /^log*/ where (\"funcuid\" = $funcuid OR \"kubernetes_labels_functionUid\" = $funcuid) AND \"time\" > $time " + orderCondition + " LIMIT " + strconv.Itoa(filter.RecordLimit)
} }
query := influxdbClient.NewQueryWithParameters(queryCmd, INFLUXDB_DATABASE, "", parameters) query := influxdbClient.NewQueryWithParameters(queryCmd, INFLUXDB_DATABASE, "", parameters)
@@ -125,16 +129,7 @@ func (influx InfluxDB) GetLogs(filter LogFilter) ([]LogEntry, error) {
} }
} }
} }
sort.Slice(logEntries, func(i, j int) bool {
if logEntries[i].Timestamp.Before(logEntries[j].Timestamp) {
return true
}
if logEntries[j].Timestamp.Before(logEntries[i].Timestamp) {
return false
}
return logEntries[i].Sequence < logEntries[j].Sequence
})
return logEntries, nil return logEntries, nil
} }
+1
View File
@@ -34,6 +34,7 @@ type LogFilter struct {
Function string Function string
FuncUid string FuncUid string
Since time.Time Since time.Time
Reverse bool
RecordLimit int RecordLimit int
} }
+2 -1
View File
@@ -117,6 +117,7 @@ func NewCliApp() *cli.App {
fnBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "build command for builder to run with"} fnBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "build command for builder to run with"}
fnSecretFlag := cli.StringSliceFlag{Name: "secret", Usage: "function access to secret, should be present in the same namespace as the function. You can provide multiple secrets using multiple --secrets flags."} fnSecretFlag := cli.StringSliceFlag{Name: "secret", Usage: "function access to secret, should be present in the same namespace as the function. You can provide multiple secrets using multiple --secrets flags."}
fnCfgMapFlag := cli.StringSliceFlag{Name: "configmap", Usage: "function access to configmap, should be present in the same namespace as the function. You can provide multiple configmaps using multiple --configmap flags."} fnCfgMapFlag := cli.StringSliceFlag{Name: "configmap", Usage: "function access to configmap, should be present in the same namespace as the function. You can provide multiple configmaps using multiple --configmap flags."}
fnLogReverseQueryFlag := cli.BoolFlag{Name: "reverse, r", Usage: "specify the log reverse query base on time, it will be invalid if the 'follow' flag is specified"}
fnLogCountFlag := cli.StringFlag{Name: "recordcount", Usage: "the n most recent log records"} fnLogCountFlag := cli.StringFlag{Name: "recordcount", Usage: "the n most recent log records"}
fnForceFlag := cli.BoolFlag{Name: "force", Usage: "Force update a package even if it is used by one or more functions"} fnForceFlag := cli.BoolFlag{Name: "force", Usage: "Force update a package even if it is used by one or more functions"}
fnExecutorTypeFlag := cli.StringFlag{Name: "executortype", Value: types.ExecutorTypePoolmgr, Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy' defaults to 'poolmgr'"} fnExecutorTypeFlag := cli.StringFlag{Name: "executortype", Value: types.ExecutorTypePoolmgr, Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy' defaults to 'poolmgr'"}
@@ -131,7 +132,7 @@ func NewCliApp() *cli.App {
// TODO : for fnList, i feel like it's nice to allow --fns all, to list functions across all namespaces for cluster admins, although, this is against ns isolation. // TODO : for fnList, i feel like it's nice to allow --fns all, to list functions across all namespaces for cluster admins, although, this is against ns isolation.
// so, in the future, if we end up using kubeconfig in fission cli and enforcing rolebindings to be created for users by admins etc, we can add this option at the time. // so, in the future, if we end up using kubeconfig in fission cli and enforcing rolebindings to be created for users by admins etc, we can add this option at the time.
{Name: "list", Usage: "List all functions in a namespace if specified, else, list functions across all namespaces", Flags: []cli.Flag{fnNamespaceFlag}, Action: fnList}, {Name: "list", Usage: "List all functions in a namespace if specified, else, list functions across all namespaces", Flags: []cli.Flag{fnNamespaceFlag}, Action: fnList},
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogCountFlag}, Action: fnLogs}, {Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogReverseQueryFlag, fnLogCountFlag}, Action: fnLogs},
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, {Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag,
fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag, fnQueryFlag, fnTimeoutFlag}, fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag, fnQueryFlag, fnTimeoutFlag},
Action: fnTest}, Action: fnTest},