Support for compressed logfiles (#13)
Allow apps to upload gzipped log files
This commit is contained in:
parent
7cb9486333
commit
0417e8d385
|
@ -59,6 +59,11 @@ logs.)
|
||||||
* `id`: textual identifier for the logs. Currently ignored.
|
* `id`: textual identifier for the logs. Currently ignored.
|
||||||
* `lines`: log data. Newlines should be encoded as `\n`, as normal in JSON).
|
* `lines`: log data. Newlines should be encoded as `\n`, as normal in JSON).
|
||||||
|
|
||||||
|
* `compressed-log`: a gzipped logfile. Decompressed and then treated the same as
|
||||||
|
`log`.
|
||||||
|
|
||||||
|
Compressed logs are not supported for the JSON upload encoding.
|
||||||
|
|
||||||
* Any other form field names are interpreted as arbitrary name/value strings to
|
* Any other form field names are interpreted as arbitrary name/value strings to
|
||||||
include in the `details.log.gz` file.
|
include in the `details.log.gz` file.
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,20 @@ func parseFormPart(part *multipart.Part, p *payload) error {
|
||||||
defer part.Close()
|
defer part.Close()
|
||||||
field := part.FormName()
|
field := part.FormName()
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(part)
|
var partReader io.Reader
|
||||||
|
if field == "compressed-log" {
|
||||||
|
// decompress logs as we read them
|
||||||
|
zrdr, err := gzip.NewReader(part)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer zrdr.Close()
|
||||||
|
partReader = zrdr
|
||||||
|
} else {
|
||||||
|
// read the field data directly from the multipart part
|
||||||
|
partReader = part
|
||||||
|
}
|
||||||
|
b, err := ioutil.ReadAll(partReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -221,7 +234,7 @@ func parseFormPart(part *multipart.Part, p *payload) error {
|
||||||
p.Version = data
|
p.Version = data
|
||||||
} else if field == "user_agent" {
|
} else if field == "user_agent" {
|
||||||
p.UserAgent = data
|
p.UserAgent = data
|
||||||
} else if field == "log" {
|
} else if field == "log" || field == "compressed-log" {
|
||||||
p.Logs = append(p.Logs, logEntry{
|
p.Logs = append(p.Logs, logEntry{
|
||||||
ID: part.FileName(),
|
ID: part.FileName(),
|
||||||
Lines: data,
|
Lines: data,
|
||||||
|
|
|
@ -111,15 +111,26 @@ Content-Disposition: form-data; name="log"; filename="instance-0.067644760733513
|
||||||
Content-Type: text/plain
|
Content-Type: text/plain
|
||||||
|
|
||||||
log
|
log
|
||||||
------WebKitFormBoundarySsdgl8Nq9voFyhdO--
|
|
||||||
`
|
`
|
||||||
|
|
||||||
|
body += `------WebKitFormBoundarySsdgl8Nq9voFyhdO
|
||||||
|
Content-Disposition: form-data; name="compressed-log"; filename="instance-0.0109372050779190651492004373866"
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
|
||||||
|
`
|
||||||
|
body += string([]byte{
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0xbf, 0xd8, 0xf5, 0x58, 0x00, 0x03,
|
||||||
|
0x2b, 0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00,
|
||||||
|
0xc6, 0x35, 0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00})
|
||||||
|
body += "\n------WebKitFormBoundarySsdgl8Nq9voFyhdO--\n"
|
||||||
|
|
||||||
p := testParsePayload(t, body, "multipart/form-data; boundary=----WebKitFormBoundarySsdgl8Nq9voFyhdO")
|
p := testParsePayload(t, body, "multipart/form-data; boundary=----WebKitFormBoundarySsdgl8Nq9voFyhdO")
|
||||||
wanted := "test words."
|
wanted := "test words."
|
||||||
if p.Text != wanted {
|
if p.Text != wanted {
|
||||||
t.Errorf("User text: got %s, want %s", p.Text, wanted)
|
t.Errorf("User text: got %s, want %s", p.Text, wanted)
|
||||||
}
|
}
|
||||||
if len(p.Logs) != 2 {
|
if len(p.Logs) != 3 {
|
||||||
t.Errorf("Log length: got %d, want 2", len(p.Logs))
|
t.Errorf("Log length: got %d, want 3", len(p.Logs))
|
||||||
}
|
}
|
||||||
if len(p.Data) != 1 {
|
if len(p.Data) != 1 {
|
||||||
t.Errorf("Data length: got %d, want 1", len(p.Data))
|
t.Errorf("Data length: got %d, want 1", len(p.Data))
|
||||||
|
@ -144,4 +155,8 @@ log
|
||||||
if p.Logs[1].ID != wanted {
|
if p.Logs[1].ID != wanted {
|
||||||
t.Errorf("Log 1 ID: got %s, want %s", p.Logs[1].ID, wanted)
|
t.Errorf("Log 1 ID: got %s, want %s", p.Logs[1].ID, wanted)
|
||||||
}
|
}
|
||||||
|
wanted = "test\n"
|
||||||
|
if p.Logs[2].Lines != wanted {
|
||||||
|
t.Errorf("Log 2: got %s, want %s", p.Logs[2].Lines, wanted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue