-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
parse azapi logs from the live traffic logger (#4)
* parse azapi logs from the live traffic logger * fix go version * fix unit test
- Loading branch information
Showing
11 changed files
with
239 additions
and
400 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,129 +1,98 @@ | ||
package provider | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/url" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/ms-henglu/pal/rawlog" | ||
"github.com/ms-henglu/pal/types" | ||
"github.com/ms-henglu/pal/utils" | ||
) | ||
|
||
var _ Provider = AzAPIProvider{} | ||
|
||
type AzAPIProvider struct { | ||
} | ||
var r = regexp.MustCompile(`Live traffic: (.+): timestamp`) | ||
|
||
func (a AzAPIProvider) IsRequestTrace(l rawlog.RawLog) bool { | ||
return l.Level == "DEBUG" && strings.Contains(l.Message, "Request: ==> OUTGOING REQUEST") | ||
type AzAPIProvider struct { | ||
} | ||
|
||
func (a AzAPIProvider) IsResponseTrace(l rawlog.RawLog) bool { | ||
return l.Level == "DEBUG" && strings.Contains(l.Message, "Response: ==> REQUEST/RESPONSE") | ||
func (a AzAPIProvider) IsTrafficTrace(l rawlog.RawLog) bool { | ||
return l.Level == "DEBUG" && strings.Contains(l.Message, "Live traffic:") | ||
} | ||
|
||
func (a AzAPIProvider) ParseRequest(l rawlog.RawLog) (*types.RequestTrace, error) { | ||
method := "" | ||
host := "" | ||
uriPath := "" | ||
body := "" | ||
headers := make(map[string]string) | ||
for _, line := range strings.Split(l.Message, "\n") { | ||
line = strings.Trim(line, " ") | ||
switch { | ||
case line == "" || strings.Contains(line, "==>") || | ||
strings.Contains(line, "Request contained no body") || | ||
strings.Contains(line, "-----"): | ||
continue | ||
case strings.Contains(line, ": "): | ||
key, value, err := utils.ParseHeader(line) | ||
if err != nil { | ||
return nil, err | ||
} | ||
headers[key] = value | ||
case utils.IsJson(line): | ||
body = line | ||
default: | ||
if parts := strings.Split(line, " "); len(parts) == 2 { | ||
method = parts[0] | ||
parsedUrl, err := url.Parse(parts[1]) | ||
if err == nil { | ||
host = parsedUrl.Host | ||
uriPath = fmt.Sprintf("%s?%s", parsedUrl.Path, parsedUrl.RawQuery) | ||
} | ||
} | ||
} | ||
func (a AzAPIProvider) ParseTraffic(l rawlog.RawLog) (*types.RequestTrace, error) { | ||
matches := r.FindAllStringSubmatch(l.Message, -1) | ||
if len(matches) == 0 || len(matches[0]) != 2 { | ||
return nil, fmt.Errorf("failed to parse request trace, no matches found") | ||
} | ||
return &types.RequestTrace{ | ||
TimeStamp: l.TimeStamp, | ||
Method: method, | ||
Host: host, | ||
Url: utils.NormalizeUrlPath(uriPath), | ||
Provider: "azapi", | ||
Request: &types.HttpRequest{ | ||
Headers: headers, | ||
Body: body, | ||
}, | ||
}, nil | ||
} | ||
|
||
func (a AzAPIProvider) ParseResponse(l rawlog.RawLog) (*types.RequestTrace, error) { | ||
method := "" | ||
host := "" | ||
uriPath := "" | ||
body := "" | ||
headers := make(map[string]string) | ||
|
||
sections := strings.Split(l.Message, strings.Repeat("-", 80)) | ||
message := l.Message | ||
if len(sections) == 4 { | ||
body = sections[2] | ||
message = utils.LineAt(sections[0], 1) + sections[1] | ||
trafficJson := matches[0][1] | ||
var liveTraffic traffic | ||
err := json.Unmarshal([]byte(trafficJson), &liveTraffic) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse request trace, %v", err) | ||
} | ||
|
||
for _, line := range strings.Split(message, "\n") { | ||
line = strings.Trim(line, " ") | ||
switch { | ||
case line == "" || strings.Contains(line, "==>") || | ||
strings.Contains(line, "contained no body") || | ||
strings.Contains(line, "-----"): | ||
continue | ||
case strings.Contains(line, ": "): | ||
key, value, err := utils.ParseHeader(line) | ||
if err != nil { | ||
return nil, err | ||
} | ||
headers[key] = value | ||
case utils.IsJson(line): | ||
body = line | ||
default: | ||
if parts := strings.Split(line, " "); len(parts) == 2 { | ||
method = parts[0] | ||
parsedUrl, err := url.Parse(parts[1]) | ||
if err == nil { | ||
host = parsedUrl.Host | ||
uriPath = fmt.Sprintf("%s?%s", parsedUrl.Path, parsedUrl.RawQuery) | ||
} | ||
} | ||
} | ||
parsedUrl, err := url.Parse(liveTraffic.LiveRequest.Url) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse request trace, %v", err) | ||
} | ||
|
||
statusCode := 0 | ||
if v := headers["RESPONSE Status"]; v != "" { | ||
delete(headers, "RESPONSE Status") | ||
fmt.Sscanf(v, "%d", &statusCode) | ||
if liveTraffic.LiveRequest.Headers == nil { | ||
liveTraffic.LiveRequest.Headers = map[string]string{} | ||
} | ||
if liveTraffic.LiveResponse.Headers == nil { | ||
liveTraffic.LiveResponse.Headers = map[string]string{} | ||
} | ||
|
||
return &types.RequestTrace{ | ||
TimeStamp: l.TimeStamp, | ||
Method: method, | ||
Host: host, | ||
Url: utils.NormalizeUrlPath(uriPath), | ||
StatusCode: statusCode, | ||
Method: liveTraffic.LiveRequest.Method, | ||
Host: parsedUrl.Host, | ||
Url: parsedUrl.Path + "?" + parsedUrl.RawQuery, | ||
StatusCode: liveTraffic.LiveResponse.StatusCode, | ||
Provider: "azapi", | ||
Request: &types.HttpRequest{ | ||
Headers: liveTraffic.LiveRequest.Headers, | ||
Body: liveTraffic.LiveRequest.Body, | ||
}, | ||
Response: &types.HttpResponse{ | ||
Headers: headers, | ||
Body: body, | ||
Headers: liveTraffic.LiveResponse.Headers, | ||
Body: liveTraffic.LiveResponse.Body, | ||
}, | ||
}, nil | ||
} | ||
|
||
func (a AzAPIProvider) IsRequestTrace(l rawlog.RawLog) bool { | ||
return false | ||
} | ||
|
||
func (a AzAPIProvider) IsResponseTrace(l rawlog.RawLog) bool { | ||
return false | ||
} | ||
|
||
func (a AzAPIProvider) ParseRequest(l rawlog.RawLog) (*types.RequestTrace, error) { | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
func (a AzAPIProvider) ParseResponse(l rawlog.RawLog) (*types.RequestTrace, error) { | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
type traffic struct { | ||
LiveRequest liveRequest `json:"request"` | ||
LiveResponse liveResponse `json:"response"` | ||
} | ||
|
||
type liveRequest struct { | ||
Headers map[string]string `json:"headers"` | ||
Method string `json:"method"` | ||
Url string `json:"url"` | ||
Body string `json:"body"` | ||
} | ||
|
||
type liveResponse struct { | ||
StatusCode int `json:"statusCode"` | ||
Headers map[string]string `json:"headers"` | ||
Body string `json:"body"` | ||
} |
Oops, something went wrong.