fission function logs returns logs in correct order now (#405)
Fix a bug in `fission function logs` due to which logs with the same timestamp were printed in the wrong order.
This commit is contained in:
committed by
Soam Vasani
parent
04531850d5
commit
2247d3118a
+10
-4
@@ -444,6 +444,11 @@ func fnLogs(c *cli.Context) error {
|
|||||||
Namespace: metav1.NamespaceDefault,
|
Namespace: metav1.NamespaceDefault,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recordLimit := c.Int("recordcount")
|
||||||
|
if recordLimit <= 0 {
|
||||||
|
recordLimit = 1000
|
||||||
|
}
|
||||||
|
|
||||||
f, err := client.FunctionGet(m)
|
f, err := client.FunctionGet(m)
|
||||||
checkErr(err, "get function")
|
checkErr(err, "get function")
|
||||||
|
|
||||||
@@ -463,10 +468,11 @@ func fnLogs(c *cli.Context) error {
|
|||||||
select {
|
select {
|
||||||
case <-requestChan:
|
case <-requestChan:
|
||||||
logFilter := logdb.LogFilter{
|
logFilter := logdb.LogFilter{
|
||||||
Pod: fnPod,
|
Pod: fnPod,
|
||||||
Function: f.Metadata.Name,
|
Function: f.Metadata.Name,
|
||||||
FuncUid: string(f.Metadata.UID),
|
FuncUid: string(f.Metadata.UID),
|
||||||
Since: t,
|
Since: t,
|
||||||
|
RecordLimit: recordLimit,
|
||||||
}
|
}
|
||||||
logEntries, err := logDB.GetLogs(logFilter)
|
logEntries, err := logDB.GetLogs(logFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -74,12 +76,13 @@ func (influx InfluxDB) GetLogs(filter LogFilter) ([]LogEntry, error) {
|
|||||||
parameters := make(map[string]interface{})
|
parameters := make(map[string]interface{})
|
||||||
parameters["funcuid"] = filter.FuncUid
|
parameters["funcuid"] = filter.FuncUid
|
||||||
parameters["time"] = timestamp
|
parameters["time"] = timestamp
|
||||||
|
//the parameters above are only for the where clause and do not work with LIMIT
|
||||||
|
|
||||||
if filter.Pod != "" {
|
if filter.Pod != "" {
|
||||||
queryCmd = "select * from \"log\" where \"funcuid\" = $funcuid AND \"pod\" = $pod AND \"time\" > $time ORDER BY time ASC"
|
queryCmd = "select * from \"log\" where \"funcuid\" = $funcuid AND \"pod\" = $pod AND \"time\" > $time LIMIT " + strconv.Itoa(filter.RecordLimit)
|
||||||
parameters["pod"] = filter.Pod
|
parameters["pod"] = filter.Pod
|
||||||
} else {
|
} else {
|
||||||
queryCmd = "select * from \"log\" where \"funcuid\" = $funcuid AND \"time\" > $time ORDER BY time ASC"
|
queryCmd = "select * from \"log\" where \"funcuid\" = $funcuid AND \"time\" > $time LIMIT " + strconv.Itoa(filter.RecordLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
query := influxdbClient.NewQueryWithParameters(queryCmd, INFLUXDB_DATABASE, "", parameters)
|
query := influxdbClient.NewQueryWithParameters(queryCmd, INFLUXDB_DATABASE, "", parameters)
|
||||||
@@ -95,6 +98,10 @@ func (influx InfluxDB) GetLogs(filter LogFilter) ([]LogEntry, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
seqNum, err := strconv.Atoi(row[1].(string))
|
||||||
|
if err != nil {
|
||||||
|
return logEntries, err
|
||||||
|
}
|
||||||
logEntries = append(logEntries, LogEntry{
|
logEntries = append(logEntries, LogEntry{
|
||||||
//The attributes of the LogEntry are selected as relative to their position in InfluxDB's line protocol response
|
//The attributes of the LogEntry are selected as relative to their position in InfluxDB's line protocol response
|
||||||
Timestamp: t,
|
Timestamp: t,
|
||||||
@@ -105,10 +112,21 @@ func (influx InfluxDB) GetLogs(filter LogFilter) ([]LogEntry, error) {
|
|||||||
Namespace: row[14].(string), //kubernetes_namespace_name
|
Namespace: row[14].(string), //kubernetes_namespace_name
|
||||||
Pod: row[15].(string), //kubernetes_pod_name
|
Pod: row[15].(string), //kubernetes_pod_name
|
||||||
Stream: row[18].(string), //stream
|
Stream: row[18].(string), //stream
|
||||||
|
Sequence: seqNum, //sequence tag
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,16 +32,18 @@ type LogDatabase interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LogFilter struct {
|
type LogFilter struct {
|
||||||
Pod string
|
Pod string
|
||||||
Function string
|
Function string
|
||||||
FuncUid string
|
FuncUid string
|
||||||
Since time.Time
|
Since time.Time
|
||||||
|
RecordLimit int
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogEntry struct {
|
type LogEntry struct {
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
Message string
|
Message string
|
||||||
Stream string
|
Stream string
|
||||||
|
Sequence int
|
||||||
Container string
|
Container string
|
||||||
Namespace string
|
Namespace string
|
||||||
FuncName string
|
FuncName string
|
||||||
|
|||||||
+2
-1
@@ -51,6 +51,7 @@ func main() {
|
|||||||
fnHeaderFlag := cli.StringSliceFlag{Name: "header, H", Usage: "request headers"}
|
fnHeaderFlag := cli.StringSliceFlag{Name: "header, H", Usage: "request headers"}
|
||||||
fnEntryPointFlag := cli.StringFlag{Name: "entrypoint", Usage: "entry point for environment v2 to load with"}
|
fnEntryPointFlag := cli.StringFlag{Name: "entrypoint", Usage: "entry point for environment v2 to load with"}
|
||||||
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"}
|
||||||
|
fnLogCountFlag := cli.StringFlag{Name: "recordcount", Usage: "the n most recent log records"}
|
||||||
|
|
||||||
fnSubcommands := []cli.Command{
|
fnSubcommands := []cli.Command{
|
||||||
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, htUrlFlag, htMethodFlag}, Action: fnCreate},
|
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, htUrlFlag, htMethodFlag}, Action: fnCreate},
|
||||||
@@ -59,7 +60,7 @@ func main() {
|
|||||||
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag}, Action: fnUpdate},
|
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag}, Action: fnUpdate},
|
||||||
{Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag}, Action: fnDelete},
|
{Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag}, Action: fnDelete},
|
||||||
{Name: "list", Usage: "List all functions", Flags: []cli.Flag{}, Action: fnList},
|
{Name: "list", Usage: "List all functions", Flags: []cli.Flag{}, Action: fnList},
|
||||||
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag}, Action: fnLogs},
|
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogCountFlag}, Action: fnLogs},
|
||||||
{Name: "pods", Usage: "Display function pods", Flags: []cli.Flag{fnNameFlag, fnLogDBTypeFlag}, Action: fnPods},
|
{Name: "pods", Usage: "Display function pods", Flags: []cli.Flag{fnNameFlag, fnLogDBTypeFlag}, Action: fnPods},
|
||||||
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag}, Action: fnTest},
|
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag}, Action: fnTest},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user