Files
mpbot-github/ci/logger/remoteLog.go
2019-01-26 18:18:18 +00:00

118 lines
2.6 KiB
Go

package logger
import (
"bytes"
"errors"
"io"
"log"
"mime/multipart"
"net/http"
"net/url"
"os"
retryablehttp "github.com/hashicorp/go-retryablehttp"
)
type remoteLogger struct {
logBigFileChan chan *LogFile
parent *Logger
quitChan chan byte
pasteURL *url.URL
httpClient *retryablehttp.Client
}
func newRemoteLogger(parent *Logger) *remoteLogger {
defaultPasteURL, _ := url.Parse("https://paste.macports.org/")
pasteURL := defaultPasteURL
if envPasteURL := os.Getenv("PASTE_URL"); envPasteURL != "" {
var err error
pasteURL, err = url.Parse(envPasteURL)
if err != nil {
log.Println(err)
pasteURL = defaultPasteURL
}
}
r := &remoteLogger{
logBigFileChan: make(chan *LogFile, 4),
parent: parent,
quitChan: make(chan byte),
pasteURL: pasteURL,
httpClient: retryablehttp.NewClient(),
}
r.httpClient.Logger = nil
r.httpClient.HTTPClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
return r
}
func (r *remoteLogger) run() {
for {
var err error
var fieldName string
select {
case logBigFile := <-r.logBigFileChan:
if logBigFile == nil {
r.parent.LogChan <- &LogText{FieldName: "", Text: nil}
return
}
fieldName = logBigFile.FieldName
fileInfo, iErr := os.Stat(logBigFile.Filename)
if iErr != nil {
err = iErr
break
}
file, iErr := os.Open(logBigFile.Filename)
if iErr != nil {
err = iErr
break
}
buf := new(bytes.Buffer)
mimeWriter := multipart.NewWriter(buf)
writer, iErr := mimeWriter.CreateFormField("paste")
if iErr != nil {
err = iErr
break
}
// Max 8 MiB
const trimNote = "*log trimmed*\n"
if fileSize := fileInfo.Size(); fileSize > 8*1024*1024-int64(len(trimNote)) {
file.Seek(fileSize-8*1024*1024+int64(len(trimNote)), 0)
io.WriteString(writer, trimNote)
}
io.Copy(writer, file)
file.Close()
mimeWriter.Close()
postForm := bytes.NewReader(buf.Bytes())
resp, iErr := r.httpClient.Post(r.pasteURL.String(), mimeWriter.FormDataContentType(), postForm)
if iErr != nil {
err = iErr
break
}
resp.Body.Close()
loc := resp.Header.Get("Location")
if loc == "" {
err = errors.New("missing Location header")
break
}
u, iErr := r.pasteURL.Parse(loc)
if iErr != nil {
err = iErr
break
}
r.parent.LogChan <- &LogText{
fieldName + "-pastebin",
[]byte(u.String()),
}
}
if err != nil {
r.parent.LogChan <- &LogText{
fieldName + "-pastebin-fail",
[]byte(err.Error()),
}
}
}
}