OpenTracing for Fission (#1079)

Added Opentracing integration using opencensus libraries for all Fission components.
This commit is contained in:
Vishal
2019-02-07 11:56:41 +05:30
committed by GitHub
parent 8b0a201f69
commit 5d2abdd95b
29 changed files with 400 additions and 121 deletions
+17 -9
View File
@@ -2,6 +2,7 @@ package client
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"log"
@@ -9,18 +10,25 @@ import (
"strings"
"time"
"go.opencensus.io/plugin/ochttp"
"golang.org/x/net/context/ctxhttp"
"github.com/fission/fission"
)
type (
Client struct {
url string
url string
httpClient *http.Client
}
)
func MakeClient(fetcherUrl string) *Client {
return &Client{
url: strings.TrimSuffix(fetcherUrl, "/"),
httpClient: &http.Client{
Transport: &ochttp.Transport{},
},
}
}
@@ -36,18 +44,18 @@ func (c *Client) getUploadUrl() string {
return c.url + "/upload"
}
func (c *Client) Specialize(req *fission.FunctionSpecializeRequest) error {
_, err := sendRequest(req, c.getSpecializeUrl())
func (c *Client) Specialize(ctx context.Context, req *fission.FunctionSpecializeRequest) error {
_, err := sendRequest(ctx, c.httpClient, req, c.getSpecializeUrl())
return err
}
func (c *Client) Fetch(fr *fission.FunctionFetchRequest) error {
_, err := sendRequest(fr, c.getFetchUrl())
func (c *Client) Fetch(ctx context.Context, fr *fission.FunctionFetchRequest) error {
_, err := sendRequest(ctx, c.httpClient, fr, c.getFetchUrl())
return err
}
func (c *Client) Upload(fr *fission.ArchiveUploadRequest) (*fission.ArchiveUploadResponse, error) {
body, err := sendRequest(fr, c.getUploadUrl())
func (c *Client) Upload(ctx context.Context, fr *fission.ArchiveUploadRequest) (*fission.ArchiveUploadResponse, error) {
body, err := sendRequest(ctx, c.httpClient, fr, c.getUploadUrl())
uploadResp := fission.ArchiveUploadResponse{}
err = json.Unmarshal(body, &uploadResp)
@@ -58,7 +66,7 @@ func (c *Client) Upload(fr *fission.ArchiveUploadRequest) (*fission.ArchiveUploa
return &uploadResp, nil
}
func sendRequest(req interface{}, url string) ([]byte, error) {
func sendRequest(ctx context.Context, httpClient *http.Client, req interface{}, url string) ([]byte, error) {
body, err := json.Marshal(req)
if err != nil {
return nil, err
@@ -68,7 +76,7 @@ func sendRequest(req interface{}, url string) ([]byte, error) {
var resp *http.Response
for i := 0; i < maxRetries; i++ {
resp, err = http.Post(url, "application/json", bytes.NewReader(body))
resp, err = ctxhttp.Post(ctx, httpClient, url, "application/json", bytes.NewReader(body))
if err == nil {
if resp.StatusCode == 200 {
+38 -2
View File
@@ -1,6 +1,7 @@
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
@@ -11,6 +12,10 @@ import (
"runtime/debug"
"syscall"
"go.opencensus.io/exporter/jaeger"
"go.opencensus.io/plugin/ochttp"
"go.opencensus.io/trace"
"github.com/fission/fission"
"github.com/fission/fission/environments/fetcher"
)
@@ -19,6 +24,29 @@ func dumpStackTrace() {
debug.PrintStack()
}
func registerTraceExporter(collectorEndpoint string) error {
if collectorEndpoint == "" {
return nil
}
serviceName := "Fission-Fetcher"
exporter, err := jaeger.NewExporter(jaeger.Options{
CollectorEndpoint: collectorEndpoint,
Process: jaeger.Process{
ServiceName: serviceName,
Tags: []jaeger.Tag{
jaeger.BoolTag("fission", true),
},
},
})
if err != nil {
return err
}
trace.RegisterExporter(exporter)
trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
return nil
}
// Usage: fetcher <shared volume path>
func main() {
// register signal handler for dumping stack trace.
@@ -32,6 +60,7 @@ func main() {
}()
flag.Usage = fetcherUsage
collectorEndpoint := flag.String("jaeger-collector-endpoint", "", "")
specializeOnStart := flag.Bool("specialize-on-startup", false, "Flag to activate specialize process at pod starup")
specializePayload := flag.String("specialize-request", "", "JSON payload for specialize request")
secretDir := flag.String("secret-dir", "", "Path to shared secrets directory")
@@ -53,6 +82,10 @@ func main() {
}
}
if err := registerTraceExporter(*collectorEndpoint); err != nil {
log.Fatalf("Could not register trace exporter: %v", err)
}
f, err := fetcher.MakeFetcher(dir, *secretDir, *configDir)
if err != nil {
log.Fatalf("Error making fetcher: %v", err)
@@ -70,7 +103,8 @@ func main() {
log.Fatalf("Error decoding specialize request: %v", err)
}
err = f.SpecializePod(specializeReq.FetchReq, specializeReq.LoadReq)
ctx := context.Background()
err = f.SpecializePod(ctx, specializeReq.FetchReq, specializeReq.LoadReq)
if err != nil {
log.Fatalf("Error specialing function poadt: %v", err)
}
@@ -96,7 +130,9 @@ func main() {
})
log.Println("Fetcher ready to receive requests")
http.ListenAndServe(":8000", mux)
http.ListenAndServe(":8000", &ochttp.Handler{
Handler: mux,
})
}
func fetcherUsage() {
+28 -19
View File
@@ -2,6 +2,7 @@ package fetcher
import (
"bytes"
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
@@ -18,7 +19,9 @@ import (
"github.com/mholt/archiver"
"github.com/pkg/errors"
"github.com/satori/go.uuid"
uuid "github.com/satori/go.uuid"
"go.opencensus.io/plugin/ochttp"
"golang.org/x/net/context/ctxhttp"
k8serr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
@@ -35,6 +38,7 @@ type (
sharedConfigPath string
fissionClient *crd.FissionClient
kubeClient *kubernetes.Clientset
httpClient *http.Client
}
)
@@ -60,11 +64,14 @@ func MakeFetcher(sharedVolumePath string, sharedSecretPath string, sharedConfigP
sharedConfigPath: sharedConfigPath,
fissionClient: fissionClient,
kubeClient: kubeClient,
httpClient: &http.Client{
Transport: &ochttp.Transport{},
},
}, nil
}
func downloadUrl(url string, localPath string) error {
resp, err := http.Get(url)
func downloadUrl(ctx context.Context, httpClient *http.Client, url string, localPath string) error {
resp, err := ctxhttp.Get(ctx, httpClient, url)
if err != nil {
return err
}
@@ -116,15 +123,11 @@ func getChecksum(path string) (*fission.Checksum, error) {
}, nil
}
func verifyChecksum(path string, checksum *fission.Checksum) error {
func verifyChecksum(fileChecksum, checksum *fission.Checksum) error {
if checksum.Type != fission.ChecksumTypeSHA256 {
return fission.MakeError(fission.ErrorInvalidArgument, "Unsupported checksum type")
}
c, err := getChecksum(path)
if err != nil {
return err
}
if c.Sum != checksum.Sum {
if fileChecksum.Sum != checksum.Sum {
return fission.MakeError(fission.ErrorChecksumFail, "Checksum validation failed")
}
return nil
@@ -175,8 +178,7 @@ func (fetcher *Fetcher) FetchHandler(w http.ResponseWriter, r *http.Request) {
return
}
log.Printf("fetcher received fetch request and started downloading: %v", req)
code, err := fetcher.Fetch(req)
code, err := fetcher.Fetch(r.Context(), req)
if err != nil {
http.Error(w, err.Error(), code)
return
@@ -217,7 +219,7 @@ func (fetcher *Fetcher) SpecializeHandler(w http.ResponseWriter, r *http.Request
//log.Printf("fetcher received fetch request and started downloading: %v", req)
err = fetcher.SpecializePod(req.FetchReq, req.LoadReq)
err = fetcher.SpecializePod(r.Context(), req.FetchReq, req.LoadReq)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
@@ -229,7 +231,7 @@ func (fetcher *Fetcher) SpecializeHandler(w http.ResponseWriter, r *http.Request
// Fetch takes FetchRequest and makes the fetch call
// It returns the HTTP code and error if any
func (fetcher *Fetcher) Fetch(req fission.FunctionFetchRequest) (int, error) {
func (fetcher *Fetcher) Fetch(ctx context.Context, req fission.FunctionFetchRequest) (int, error) {
// check that the requested filename is not an empty string and error out if so
if len(req.Filename) == 0 {
e := fmt.Sprintf("Fetch request received for an empty file name, request: %v", req)
@@ -248,7 +250,7 @@ func (fetcher *Fetcher) Fetch(req fission.FunctionFetchRequest) (int, error) {
if req.FetchType == fission.FETCH_URL {
// fetch the file and save it to the tmp path
err := downloadUrl(req.Url, tmpPath)
err := downloadUrl(ctx, fetcher.httpClient, req.Url, tmpPath)
if err != nil {
e := fmt.Sprintf("Failed to download url %v: %v", req.Url, err)
log.Printf(e)
@@ -289,14 +291,21 @@ func (fetcher *Fetcher) Fetch(req fission.FunctionFetchRequest) (int, error) {
}
} else {
// download and verify
err = downloadUrl(archive.URL, tmpPath)
err := downloadUrl(ctx, fetcher.httpClient, archive.URL, tmpPath)
if err != nil {
e := fmt.Sprintf("Failed to download url %v: %v", req.Url, err)
log.Printf(e)
return http.StatusBadRequest, errors.New(e)
}
err = verifyChecksum(tmpPath, &archive.Checksum)
checksum, err := getChecksum(tmpPath)
if err != nil {
e := fmt.Sprintf("Failed to get checksum: %v", err)
log.Printf(e)
return http.StatusBadRequest, errors.New(e)
}
err = verifyChecksum(checksum, &archive.Checksum)
if err != nil {
e := fmt.Sprintf("Failed to verify checksum: %v", err)
log.Printf(e)
@@ -454,7 +463,7 @@ func (fetcher *Fetcher) UploadHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Starting upload...")
ssClient := storageSvcClient.MakeClient(req.StorageSvcUrl)
fileID, err := ssClient.Upload(dstFilepath, nil)
fileID, err := ssClient.Upload(r.Context(), dstFilepath, nil)
if err != nil {
e := fmt.Sprintf("Error uploading zip file: %v", err)
log.Println(e)
@@ -526,14 +535,14 @@ func (fetcher *Fetcher) unarchive(src string, dst string) error {
return nil
}
func (fetcher *Fetcher) SpecializePod(fetchReq fission.FunctionFetchRequest, loadReq fission.FunctionLoadRequest) error {
func (fetcher *Fetcher) SpecializePod(ctx context.Context, fetchReq fission.FunctionFetchRequest, loadReq fission.FunctionLoadRequest) error {
startTime := time.Now()
defer func() {
elapsed := time.Since(startTime)
log.Printf("Elapsed time in fetch request = %v", elapsed)
}()
_, err := fetcher.Fetch(fetchReq)
_, err := fetcher.Fetch(ctx, fetchReq)
if err != nil {
return errors.Wrap(err, "Error fetching deploy package")
}