Skip to content

Commit 74fdcec

Browse files
nitishkumar71alexellis
authored andcommitted
Add support for GetLogs
Tested end to end with OpenFaaS Standard, and with a new unit test. Signed-off-by: Nitishkumar Singh <nitishkumarsingh71@gmail.com> Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent 0974213 commit 74fdcec

File tree

4 files changed

+256
-66
lines changed

4 files changed

+256
-66
lines changed

client.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ import (
66
"encoding/json"
77
"fmt"
88
"io"
9+
"log"
910
"net/http"
1011
"net/url"
1112
"os"
1213
"path/filepath"
14+
"strconv"
1315
"strings"
16+
"time"
1417

18+
"github.com/openfaas/faas-provider/logs"
1519
"github.com/openfaas/faas-provider/types"
1620
)
1721

@@ -59,6 +63,7 @@ func (s *Client) do(req *http.Request) (*http.Response, error) {
5963
req.Body = io.NopCloser(strings.NewReader(buf.String()))
6064
}
6165
}
66+
6267
return s.client.Do(req)
6368
}
6469

@@ -843,3 +848,95 @@ func (s *Client) DeleteSecret(ctx context.Context, secretName, namespace string)
843848
}
844849
return nil
845850
}
851+
852+
func generateLogRequest(functionName, namespace string, follow bool, tail int, since *time.Time) url.Values {
853+
query := url.Values{}
854+
query.Add("name", functionName)
855+
if len(namespace) > 0 {
856+
query.Add("namespace", namespace)
857+
}
858+
859+
if follow {
860+
query.Add("follow", "1")
861+
} else {
862+
query.Add("follow", "0")
863+
}
864+
865+
if since != nil {
866+
query.Add("since", since.Format(time.RFC3339))
867+
}
868+
869+
if tail != 0 {
870+
query.Add("tail", strconv.Itoa(tail))
871+
}
872+
873+
return query
874+
}
875+
876+
func (s *Client) GetLogs(ctx context.Context, functionName, namespace string, follow bool, tail int, since *time.Time) (<-chan logs.Message, error) {
877+
878+
var err error
879+
880+
u := s.GatewayURL
881+
u.Path = "/system/logs"
882+
883+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
884+
if err != nil {
885+
return nil, fmt.Errorf("cannot connect to OpenFaaS on URL: %s, error: %s", u.String(), err)
886+
}
887+
888+
req.URL.RawQuery = generateLogRequest(functionName, namespace, follow, tail, since).Encode()
889+
log.Printf("%s", req.URL.RawQuery)
890+
891+
if s.ClientAuth != nil {
892+
if err := s.ClientAuth.Set(req); err != nil {
893+
return nil, fmt.Errorf("unable to set Authorization header: %w", err)
894+
}
895+
}
896+
897+
res, err := s.do(req)
898+
if err != nil {
899+
return nil, fmt.Errorf("cannot connect to OpenFaaS on URL: %s, error: %s", s.GatewayURL, err)
900+
901+
}
902+
903+
logStream := make(chan logs.Message, 1000)
904+
905+
switch res.StatusCode {
906+
case http.StatusOK:
907+
go func() {
908+
defer func() {
909+
close(logStream)
910+
}()
911+
912+
if res.Body != nil {
913+
defer res.Body.Close()
914+
}
915+
916+
decoder := json.NewDecoder(res.Body)
917+
918+
for decoder.More() {
919+
msg := logs.Message{}
920+
err := decoder.Decode(&msg)
921+
if err != nil {
922+
log.Printf("cannot parse log results: %s", err.Error())
923+
return
924+
}
925+
logStream <- msg
926+
}
927+
}()
928+
929+
case http.StatusNotFound:
930+
return nil, fmt.Errorf("function: %s not found", functionName)
931+
932+
case http.StatusUnauthorized:
933+
return nil, fmt.Errorf("unauthorized action, please setup authentication for this server")
934+
935+
default:
936+
bytesOut, err := io.ReadAll(res.Body)
937+
if err == nil {
938+
return nil, fmt.Errorf("unexpected status code: %d, message: %q", res.StatusCode, string(bytesOut))
939+
}
940+
}
941+
return logStream, nil
942+
}

0 commit comments

Comments
 (0)