diff --git a/agent/pkg/api/socket_routes.go b/agent/pkg/api/socket_routes.go index f3d810395..7ba69966c 100644 --- a/agent/pkg/api/socket_routes.go +++ b/agent/pkg/api/socket_routes.go @@ -17,6 +17,12 @@ import ( tapApi "github.com/up9inc/mizu/tap/api" ) +var extensionsMap map[string]*tapApi.Extension // global + +func InitExtensionsMap(ref map[string]*tapApi.Extension) { + extensionsMap = ref +} + type EventHandlers interface { WebSocketConnect(socketId int, isTapper bool) WebSocketDisconnect(socketId int, isTapper bool) @@ -165,7 +171,8 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even if params.EnableFullEntries { message, _ = models.CreateFullEntryWebSocketMessage(entry) } else { - base := tapApi.Summarize(entry) + extension := extensionsMap[entry.Protocol.Name] + base := extension.Dissector.Summarize(entry) message, _ = models.CreateBaseEntryWebSocketMessage(base) } diff --git a/agent/pkg/app/main.go b/agent/pkg/app/main.go index 36c32f1ae..971244491 100644 --- a/agent/pkg/app/main.go +++ b/agent/pkg/app/main.go @@ -60,6 +60,7 @@ func LoadExtensions() { }) controllers.InitExtensionsMap(ExtensionsMap) + api.InitExtensionsMap(ExtensionsMap) } func ConfigureBasenineServer(host string, port string, dbSize int64, logLevel logging.Level, insertionFilter string) { diff --git a/agent/pkg/controllers/entries_controller.go b/agent/pkg/controllers/entries_controller.go index d556d32d4..7523552d0 100644 --- a/agent/pkg/controllers/entries_controller.go +++ b/agent/pkg/controllers/entries_controller.go @@ -77,7 +77,8 @@ func GetEntries(c *gin.Context) { return // exit } - base := tapApi.Summarize(entry) + extension := extensionsMap[entry.Protocol.Name] + base := extension.Dissector.Summarize(entry) dataSlice = append(dataSlice, base) } @@ -123,6 +124,7 @@ func GetEntry(c *gin.Context) { } extension := extensionsMap[entry.Protocol.Name] + base := extension.Dissector.Summarize(entry) representation, bodySize, _ := extension.Dissector.Represent(entry.Request, entry.Response) var rules []map[string]interface{} @@ -142,6 +144,7 @@ func GetEntry(c *gin.Context) { Representation: string(representation), BodySize: bodySize, Data: entry, + Base: base, Rules: rules, IsRulesEnabled: isRulesEnabled, }) diff --git a/agent/pkg/elastic/esClient.go b/agent/pkg/elastic/esClient.go index 9ccc30ebb..296f8bcd6 100644 --- a/agent/pkg/elastic/esClient.go +++ b/agent/pkg/elastic/esClient.go @@ -80,11 +80,7 @@ type httpEntry struct { CreatedAt time.Time `json:"createdAt"` Request map[string]interface{} `json:"request"` Response map[string]interface{} `json:"response"` - Summary string `json:"summary"` - Method string `json:"method"` - Status int `json:"status"` ElapsedTime int64 `json:"elapsedTime"` - Path string `json:"path"` } func (client *client) PushEntry(entry *api.Entry) { @@ -103,11 +99,7 @@ func (client *client) PushEntry(entry *api.Entry) { CreatedAt: entry.StartTime, Request: entry.Request, Response: entry.Response, - Summary: entry.Summary, - Method: entry.Method, - Status: entry.Status, ElapsedTime: entry.ElapsedTime, - Path: entry.Path, } entryJson, err := json.Marshal(entryToPush) diff --git a/tap/api/api.go b/tap/api/api.go index f061db404..26bfa0b4f 100644 --- a/tap/api/api.go +++ b/tap/api/api.go @@ -100,6 +100,7 @@ type Dissector interface { Ping() Dissect(b *bufio.Reader, isClient bool, tcpID *TcpID, counterPair *CounterPair, superTimer *SuperTimer, superIdentifier *SuperIdentifier, emitter Emitter, options *TrafficFilteringOptions, reqResMatcher RequestResponseMatcher) error Analyze(item *OutputChannelItem, resolvedSource string, resolvedDestination string, namespace string) *Entry + Summarize(entry *Entry) *BaseEntry Represent(request map[string]interface{}, response map[string]interface{}) (object []byte, bodySize int64, err error) Macros() map[string]string NewResponseRequestMatcher() RequestResponseMatcher @@ -135,12 +136,7 @@ type Entry struct { StartTime time.Time `json:"startTime"` Request map[string]interface{} `json:"request"` Response map[string]interface{} `json:"response"` - Summary string `json:"summary"` - Method string `json:"method"` - Status int `json:"status"` ElapsedTime int64 `json:"elapsedTime"` - Path string `json:"path"` - IsOutgoing bool `json:"isOutgoing,omitempty"` Rules ApplicableRules `json:"rules,omitempty"` ContractStatus ContractStatus `json:"contractStatus,omitempty"` ContractRequestReason string `json:"contractRequestReason,omitempty"` @@ -154,6 +150,7 @@ type EntryWrapper struct { Representation string `json:"representation"` BodySize int64 `json:"bodySize"` Data *Entry `json:"data"` + Base *BaseEntry `json:"base"` Rules []map[string]interface{} `json:"rulesMatched,omitempty"` IsRulesEnabled bool `json:"isRulesEnabled"` } @@ -161,11 +158,12 @@ type EntryWrapper struct { type BaseEntry struct { Id uint `json:"id"` Protocol Protocol `json:"proto,omitempty"` - Url string `json:"url,omitempty"` - Path string `json:"path,omitempty"` Summary string `json:"summary,omitempty"` - StatusCode int `json:"status"` + SummaryQuery string `json:"summaryQuery,omitempty"` + Status int `json:"status"` + StatusQuery string `json:"statusQuery"` Method string `json:"method,omitempty"` + MethodQuery string `json:"methodQuery,omitempty"` Timestamp int64 `json:"timestamp,omitempty"` Source *TCP `json:"src"` Destination *TCP `json:"dst"` @@ -190,24 +188,6 @@ type Contract struct { Content string `json:"content"` } -func Summarize(entry *Entry) *BaseEntry { - return &BaseEntry{ - Id: entry.Id, - Protocol: entry.Protocol, - Path: entry.Path, - Summary: entry.Summary, - StatusCode: entry.Status, - Method: entry.Method, - Timestamp: entry.Timestamp, - Source: entry.Source, - Destination: entry.Destination, - IsOutgoing: entry.IsOutgoing, - Latency: entry.ElapsedTime, - Rules: entry.Rules, - ContractStatus: entry.ContractStatus, - } -} - type DataUnmarshaler interface { UnmarshalData(*Entry) error } @@ -215,14 +195,9 @@ type DataUnmarshaler interface { func (bed *BaseEntry) UnmarshalData(entry *Entry) error { bed.Protocol = entry.Protocol bed.Id = entry.Id - bed.Path = entry.Path - bed.Summary = entry.Summary - bed.StatusCode = entry.Status - bed.Method = entry.Method bed.Timestamp = entry.Timestamp bed.Source = entry.Source bed.Destination = entry.Destination - bed.IsOutgoing = entry.IsOutgoing bed.Latency = entry.ElapsedTime bed.ContractStatus = entry.ContractStatus return nil diff --git a/tap/extensions/amqp/main.go b/tap/extensions/amqp/main.go index 804d32338..31707fafc 100644 --- a/tap/extensions/amqp/main.go +++ b/tap/extensions/amqp/main.go @@ -219,31 +219,6 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, request := item.Pair.Request.Payload.(map[string]interface{}) reqDetails := request["details"].(map[string]interface{}) - summary := "" - switch request["method"] { - case basicMethodMap[40]: - summary = reqDetails["exchange"].(string) - case basicMethodMap[60]: - summary = reqDetails["exchange"].(string) - case exchangeMethodMap[10]: - summary = reqDetails["exchange"].(string) - case queueMethodMap[10]: - summary = reqDetails["queue"].(string) - case connectionMethodMap[10]: - summary = fmt.Sprintf( - "%s.%s", - strconv.Itoa(int(reqDetails["versionMajor"].(float64))), - strconv.Itoa(int(reqDetails["versionMinor"].(float64))), - ) - case connectionMethodMap[50]: - summary = reqDetails["replyText"].(string) - case queueMethodMap[20]: - summary = reqDetails["queue"].(string) - case basicMethodMap[20]: - summary = reqDetails["queue"].(string) - } - - request["url"] = summary reqDetails["method"] = request["method"] return &api.Entry{ Protocol: protocol, @@ -260,17 +235,70 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, Namespace: namespace, Outgoing: item.ConnectionInfo.IsOutgoing, Request: reqDetails, - Method: request["method"].(string), - Status: 0, Timestamp: item.Timestamp, StartTime: item.Pair.Request.CaptureTime, ElapsedTime: 0, - Summary: summary, - IsOutgoing: item.ConnectionInfo.IsOutgoing, } } +func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry { + summary := "" + summaryQuery := "" + method := entry.Request["method"].(string) + methodQuery := fmt.Sprintf(`request.method == "%s"`, method) + switch method { + case basicMethodMap[40]: + summary = entry.Request["exchange"].(string) + summaryQuery = fmt.Sprintf(`request.exchange == "%s"`, summary) + case basicMethodMap[60]: + summary = entry.Request["exchange"].(string) + summaryQuery = fmt.Sprintf(`request.exchange == "%s"`, summary) + case exchangeMethodMap[10]: + summary = entry.Request["exchange"].(string) + summaryQuery = fmt.Sprintf(`request.exchange == "%s"`, summary) + case queueMethodMap[10]: + summary = entry.Request["queue"].(string) + summaryQuery = fmt.Sprintf(`request.queue == "%s"`, summary) + case connectionMethodMap[10]: + versionMajor := int(entry.Request["versionMajor"].(float64)) + versionMinor := int(entry.Request["versionMinor"].(float64)) + summary = fmt.Sprintf( + "%s.%s", + strconv.Itoa(versionMajor), + strconv.Itoa(versionMinor), + ) + summaryQuery = fmt.Sprintf(`request.versionMajor == %d and request.versionMinor == %d`, versionMajor, versionMinor) + case connectionMethodMap[50]: + summary = entry.Request["replyText"].(string) + summaryQuery = fmt.Sprintf(`request.replyText == "%s"`, summary) + case queueMethodMap[20]: + summary = entry.Request["queue"].(string) + summaryQuery = fmt.Sprintf(`request.queue == "%s"`, summary) + case basicMethodMap[20]: + summary = entry.Request["queue"].(string) + summaryQuery = fmt.Sprintf(`request.queue == "%s"`, summary) + } + + return &api.BaseEntry{ + Id: entry.Id, + Protocol: entry.Protocol, + Summary: summary, + SummaryQuery: summaryQuery, + Status: 0, + StatusQuery: "", + Method: method, + MethodQuery: methodQuery, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.Outgoing, + Latency: entry.ElapsedTime, + Rules: entry.Rules, + ContractStatus: entry.ContractStatus, + } +} + func (d dissecting) Represent(request map[string]interface{}, response map[string]interface{}) (object []byte, bodySize int64, err error) { bodySize = 0 representation := make(map[string]interface{}) diff --git a/tap/extensions/http/main.go b/tap/extensions/http/main.go index e1cb5e773..862010089 100644 --- a/tap/extensions/http/main.go +++ b/tap/extensions/http/main.go @@ -231,7 +231,6 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, reqDetails["targetUri"] = reqDetails["url"] reqDetails["path"] = path reqDetails["pathSegments"] = strings.Split(path, "/")[1:] - reqDetails["summary"] = path // Rearrange the maps for the querying reqDetails["_headers"] = reqDetails["headers"] @@ -248,17 +247,11 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, reqDetails["_queryStringMerged"] = mapSliceMergeRepeatedKeys(reqDetails["_queryString"].([]interface{})) reqDetails["queryString"] = mapSliceRebuildAsMap(reqDetails["_queryStringMerged"].([]interface{})) - method := reqDetails["method"].(string) statusCode := int(resDetails["status"].(float64)) if item.Protocol.Abbreviation == "gRPC" { resDetails["statusText"] = grpcStatusCodes[statusCode] } - if item.Protocol.Version == "2.0" && !isRequestUpgradedH2C { - reqDetails["url"] = path - request["url"] = path - } - elapsedTime := item.Pair.Response.CaptureTime.Sub(item.Pair.Request.CaptureTime).Round(time.Millisecond).Milliseconds() if elapsedTime < 0 { elapsedTime = 0 @@ -280,17 +273,40 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, Outgoing: item.ConnectionInfo.IsOutgoing, Request: reqDetails, Response: resDetails, - Method: method, - Status: statusCode, Timestamp: item.Timestamp, StartTime: item.Pair.Request.CaptureTime, ElapsedTime: elapsedTime, - Summary: path, - IsOutgoing: item.ConnectionInfo.IsOutgoing, HTTPPair: string(httpPair), } } +func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry { + summary := entry.Request["path"].(string) + summaryQuery := fmt.Sprintf(`request.path == "%s"`, summary) + method := entry.Request["method"].(string) + methodQuery := fmt.Sprintf(`request.method == "%s"`, method) + status := int(entry.Response["status"].(float64)) + statusQuery := fmt.Sprintf(`respoonse.status == %d`, status) + + return &api.BaseEntry{ + Id: entry.Id, + Protocol: entry.Protocol, + Summary: summary, + SummaryQuery: summaryQuery, + Status: status, + StatusQuery: statusQuery, + Method: method, + MethodQuery: methodQuery, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.Outgoing, + Latency: entry.ElapsedTime, + Rules: entry.Rules, + ContractStatus: entry.ContractStatus, + } +} + func representRequest(request map[string]interface{}) (repRequest []interface{}) { details, _ := json.Marshal([]api.TableData{ { diff --git a/tap/extensions/kafka/main.go b/tap/extensions/kafka/main.go index 190db217e..405ecc65d 100644 --- a/tap/extensions/kafka/main.go +++ b/tap/extensions/kafka/main.go @@ -61,83 +61,7 @@ func (d dissecting) Dissect(b *bufio.Reader, isClient bool, tcpID *api.TcpID, co func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, resolvedDestination string, namespace string) *api.Entry { request := item.Pair.Request.Payload.(map[string]interface{}) reqDetails := request["details"].(map[string]interface{}) - apiKey := ApiKey(reqDetails["apiKey"].(float64)) - summary := "" - switch apiKey { - case Metadata: - _topics := reqDetails["payload"].(map[string]interface{})["topics"] - if _topics == nil { - break - } - topics := _topics.([]interface{}) - for _, topic := range topics { - summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["name"].(string)) - } - if len(summary) > 0 { - summary = summary[:len(summary)-2] - } - case ApiVersions: - summary = reqDetails["clientID"].(string) - case Produce: - _topics := reqDetails["payload"].(map[string]interface{})["topicData"] - if _topics == nil { - break - } - topics := _topics.([]interface{}) - for _, topic := range topics { - summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["topic"].(string)) - } - if len(summary) > 0 { - summary = summary[:len(summary)-2] - } - case Fetch: - _topics := reqDetails["payload"].(map[string]interface{})["topics"] - if _topics == nil { - break - } - topics := _topics.([]interface{}) - for _, topic := range topics { - summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["topic"].(string)) - } - if len(summary) > 0 { - summary = summary[:len(summary)-2] - } - case ListOffsets: - _topics := reqDetails["payload"].(map[string]interface{})["topics"] - if _topics == nil { - break - } - topics := _topics.([]interface{}) - for _, topic := range topics { - summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["name"].(string)) - } - if len(summary) > 0 { - summary = summary[:len(summary)-2] - } - case CreateTopics: - _topics := reqDetails["payload"].(map[string]interface{})["topics"] - if _topics == nil { - break - } - topics := _topics.([]interface{}) - for _, topic := range topics { - summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["name"].(string)) - } - if len(summary) > 0 { - summary = summary[:len(summary)-2] - } - case DeleteTopics: - if reqDetails["topicNames"] == nil { - break - } - topicNames := reqDetails["topicNames"].([]string) - for _, name := range topicNames { - summary += fmt.Sprintf("%s, ", name) - } - } - - request["url"] = summary elapsedTime := item.Pair.Response.CaptureTime.Sub(item.Pair.Request.CaptureTime).Round(time.Millisecond).Milliseconds() if elapsedTime < 0 { elapsedTime = 0 @@ -158,13 +82,127 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, Outgoing: item.ConnectionInfo.IsOutgoing, Request: reqDetails, Response: item.Pair.Response.Payload.(map[string]interface{})["details"].(map[string]interface{}), - Method: apiNames[apiKey], - Status: 0, Timestamp: item.Timestamp, StartTime: item.Pair.Request.CaptureTime, ElapsedTime: elapsedTime, - Summary: summary, - IsOutgoing: item.ConnectionInfo.IsOutgoing, + } +} + +func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry { + status := 0 + statusQuery := "" + + apiKey := ApiKey(entry.Request["apiKey"].(float64)) + method := apiNames[apiKey] + methodQuery := fmt.Sprintf("request.apiKey == %d", int(entry.Request["apiKey"].(float64))) + + summary := "" + summaryQuery := "" + switch apiKey { + case Metadata: + _topics := entry.Request["payload"].(map[string]interface{})["topics"] + if _topics == nil { + break + } + topics := _topics.([]interface{}) + for i, topic := range topics { + summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["name"].(string)) + summaryQuery += fmt.Sprintf(`request.payload.topics[%d].name == "%s" and`, i, summary) + } + if len(summary) > 0 { + summary = summary[:len(summary)-2] + summaryQuery = summaryQuery[:len(summaryQuery)-4] + } + case ApiVersions: + summary = entry.Request["clientID"].(string) + summaryQuery = fmt.Sprintf(`request.clientID == "%s"`, summary) + case Produce: + _topics := entry.Request["payload"].(map[string]interface{})["topicData"] + if _topics == nil { + break + } + topics := _topics.([]interface{}) + for i, topic := range topics { + summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["topic"].(string)) + summaryQuery += fmt.Sprintf(`request.payload.topicData[%d].topic == "%s" and`, i, summary) + } + if len(summary) > 0 { + summary = summary[:len(summary)-2] + summaryQuery = summaryQuery[:len(summaryQuery)-4] + } + case Fetch: + _topics := entry.Request["payload"].(map[string]interface{})["topics"] + if _topics == nil { + break + } + topics := _topics.([]interface{}) + for i, topic := range topics { + summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["topic"].(string)) + summaryQuery += fmt.Sprintf(`request.payload.topics[%d].topic == "%s" and`, i, summary) + } + if len(summary) > 0 { + summary = summary[:len(summary)-2] + summaryQuery = summaryQuery[:len(summaryQuery)-4] + } + case ListOffsets: + _topics := entry.Request["payload"].(map[string]interface{})["topics"] + if _topics == nil { + break + } + topics := _topics.([]interface{}) + for i, topic := range topics { + summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["name"].(string)) + summaryQuery += fmt.Sprintf(`request.payload.topics[%d].name == "%s" and`, i, summary) + } + if len(summary) > 0 { + summary = summary[:len(summary)-2] + summaryQuery = summaryQuery[:len(summaryQuery)-4] + } + case CreateTopics: + _topics := entry.Request["payload"].(map[string]interface{})["topics"] + if _topics == nil { + break + } + topics := _topics.([]interface{}) + for i, topic := range topics { + summary += fmt.Sprintf("%s, ", topic.(map[string]interface{})["name"].(string)) + summaryQuery += fmt.Sprintf(`request.payload.topics[%d].name == "%s" and`, i, summary) + } + if len(summary) > 0 { + summary = summary[:len(summary)-2] + summaryQuery = summaryQuery[:len(summaryQuery)-4] + } + case DeleteTopics: + if entry.Request["topicNames"] == nil { + break + } + topicNames := entry.Request["topicNames"].([]string) + for i, name := range topicNames { + summary += fmt.Sprintf("%s, ", name) + summaryQuery += fmt.Sprintf(`request.topicNames[%d] == "%s" and`, i, summary) + } + if len(summary) > 0 { + summary = summary[:len(summary)-2] + summaryQuery = summaryQuery[:len(summaryQuery)-4] + } + } + + return &api.BaseEntry{ + Id: entry.Id, + Protocol: entry.Protocol, + Summary: summary, + SummaryQuery: summaryQuery, + Status: status, + StatusQuery: statusQuery, + Method: method, + MethodQuery: methodQuery, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.Outgoing, + Latency: entry.ElapsedTime, + Rules: entry.Rules, + ContractStatus: entry.ContractStatus, } } diff --git a/tap/extensions/redis/main.go b/tap/extensions/redis/main.go index 4fd20f510..ff9c87856 100644 --- a/tap/extensions/redis/main.go +++ b/tap/extensions/redis/main.go @@ -65,17 +65,6 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, reqDetails := request["details"].(map[string]interface{}) resDetails := response["details"].(map[string]interface{}) - method := "" - if reqDetails["command"] != nil { - method = reqDetails["command"].(string) - } - - summary := "" - if reqDetails["key"] != nil { - summary = reqDetails["key"].(string) - } - - request["url"] = summary elapsedTime := item.Pair.Response.CaptureTime.Sub(item.Pair.Request.CaptureTime).Round(time.Millisecond).Milliseconds() if elapsedTime < 0 { elapsedTime = 0 @@ -96,17 +85,50 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, Outgoing: item.ConnectionInfo.IsOutgoing, Request: reqDetails, Response: resDetails, - Method: method, - Status: 0, Timestamp: item.Timestamp, StartTime: item.Pair.Request.CaptureTime, ElapsedTime: elapsedTime, - Summary: summary, - IsOutgoing: item.ConnectionInfo.IsOutgoing, } } +func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry { + status := 0 + statusQuery := "" + + method := "" + methodQuery := "" + if entry.Request["command"] != nil { + method = entry.Request["command"].(string) + methodQuery = fmt.Sprintf(`request.command == "%s"`, method) + } + + summary := "" + summaryQuery := "" + if entry.Response["key"] != nil { + summary = entry.Response["key"].(string) + summaryQuery = fmt.Sprintf(`response.key == "%s"`, summary) + } + + return &api.BaseEntry{ + Id: entry.Id, + Protocol: entry.Protocol, + Summary: summary, + SummaryQuery: summaryQuery, + Status: status, + StatusQuery: statusQuery, + Method: method, + MethodQuery: methodQuery, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.Outgoing, + Latency: entry.ElapsedTime, + Rules: entry.Rules, + ContractStatus: entry.ContractStatus, + } +} + func (d dissecting) Represent(request map[string]interface{}, response map[string]interface{}) (object []byte, bodySize int64, err error) { bodySize = 0 representation := make(map[string]interface{}) diff --git a/ui/src/components/EntryDetailed.tsx b/ui/src/components/EntryDetailed.tsx index b31a15195..827efc951 100644 --- a/ui/src/components/EntryDetailed.tsx +++ b/ui/src/components/EntryDetailed.tsx @@ -119,7 +119,7 @@ export const EntryDetailed = () => { bodySize={entryData.bodySize} elapsedTime={entryData.data.elapsedTime} />} - {entryData && } + {entryData && } <> {entryData && = ({entry, style, headingMode}) => horizontal={false} /> : null} {isStatusCodeEnabled &&
- +
}
- +
= ({statusCode}) => { +const StatusCode: React.FC = ({statusCode, statusQuery}) => { const classification = getClassification(statusCode) return = ({method, summary}) => { +export const Summary: React.FC = ({method, methodQuery, summary, summaryQuery}) => { return
{method && = ({method, summary}) => { } {summary &&