diff --git a/logs/example/main.go b/logs/example/main.go index 0386036..8b4c518 100644 --- a/logs/example/main.go +++ b/logs/example/main.go @@ -30,6 +30,7 @@ func (s staticLogRequestor) Query(ctx context.Context, r logs.Request) (<-chan l resp <- logs.Message{ Name: r.Name, + Namespace: r.Namespace, Instance: "fake", Timestamp: time.Now(), Text: m, diff --git a/logs/handler.go b/logs/handler.go index 0ab10a0..70616d8 100644 --- a/logs/handler.go +++ b/logs/handler.go @@ -107,6 +107,7 @@ func NewLogHandlerFunc(requestor Requester, timeout time.Duration) http.HandlerF func parseRequest(r *http.Request) (logRequest Request, err error) { query := r.URL.Query() logRequest.Name = getValue(query, "name") + logRequest.Namespace = getValue(query, "namespace") logRequest.Instance = getValue(query, "instance") tailStr := getValue(query, "tail") if tailStr != "" { diff --git a/logs/handler_test.go b/logs/handler_test.go index 5b9c2a2..6fb718b 100644 --- a/logs/handler_test.go +++ b/logs/handler_test.go @@ -19,7 +19,7 @@ func Test_logsHandlerDoesNotLeakGoroutinesWhenProviderClosesStream(t *testing.T) defer goleak.VerifyNoLeaks(t) msgs := []Message{ - Message{Name: "funcFoo", Text: "msg 0"}, + Message{Name: "funcFoo", Text: "msg 0", Namespace: "default"}, Message{Name: "funcFoo", Text: "msg 1"}, } @@ -54,7 +54,7 @@ func Test_logsHandlerDoesNotLeakGoroutinesWhenClientClosesConnection(t *testing. defer goleak.VerifyNoLeaks(t) msgs := []Message{ - Message{Name: "funcFoo", Text: "msg 0"}, + Message{Name: "funcFoo", Text: "msg 0", Namespace: "default"}, Message{Name: "funcFoo", Text: "msg 1"}, } @@ -103,12 +103,6 @@ func Test_GETRequestParsing(t *testing.T) { err: "", expectedRequest: Request{Name: "foobar"}, }, - { - name: "name only query", - rawQueryStr: "name=foobar", - err: "", - expectedRequest: Request{Name: "foobar"}, - }, { name: "multiple name values selects the last value", rawQueryStr: "name=foobar&name=theactual name", @@ -117,13 +111,14 @@ func Test_GETRequestParsing(t *testing.T) { }, { name: "valid request with every parameter", - rawQueryStr: "name=foobar&since=2019-02-16T09%3A10%3A06%2B00%3A00&tail=5&follow=true", + rawQueryStr: "name=foobar&since=2019-02-16T09%3A10%3A06%2B00%3A00&tail=5&follow=true&namespace=default", err: "", expectedRequest: Request{ - Name: "foobar", - Since: &sinceTime, - Tail: 5, - Follow: true, + Name: "foobar", + Namespace: "default", + Since: &sinceTime, + Tail: 5, + Follow: true, }, }, } diff --git a/logs/logs.go b/logs/logs.go index 6a48c50..4069c40 100644 --- a/logs/logs.go +++ b/logs/logs.go @@ -16,6 +16,9 @@ import ( type Request struct { // Name is the function name and is required Name string `json:"name"` + // Namespace is the namespace the function is deployed to, how a namespace is defined + // is faas-provider specific + Namespace string `json:"namespace"` // Instance is the optional container name, that allows you to request logs from a specific function instance Instance string `json:"instance"` // Since is the optional datetime value to start the logs from @@ -29,13 +32,19 @@ type Request struct { // String implements that Stringer interface and prints the log Request in a consistent way that // allows you to safely compare if two requests have the same value. func (r Request) String() string { - return fmt.Sprintf("name:%s instance:%s since:%v tail:%d follow:%v", r.Name, r.Instance, r.Since, r.Tail, r.Follow) + return fmt.Sprintf( + "name:%s namespace: %s instance:%s since:%v tail:%d follow:%v", + r.Name, r.Namespace, r.Instance, r.Since, r.Tail, r.Follow, + ) } // Message is a specific log message from a function container log stream type Message struct { // Name is the function name Name string `json:"name"` + // Namespace is the namespace the function is deployed to, how a namespace is defined + // is faas-provider specific + Namespace string `json:"namespace"` // instance is the name/id of the specific function instance Instance string `json:"instance"` // Timestamp is the timestamp of when the log message was recorded @@ -46,5 +55,8 @@ type Message struct { // String implements the Stringer interface and allows for nice and simple string formatting of a log Message. func (m Message) String() string { - return fmt.Sprintf("%s %s (%s) %s", m.Timestamp.String(), m.Name, m.Instance, m.Text) + return fmt.Sprintf( + "%s %s (%s %s) %s", + m.Timestamp.String(), m.Name, m.Namespace, m.Instance, m.Text, + ) }