Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

authz: Stdout logger #6230

Merged
merged 30 commits into from May 17, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
065089d
Draft of StdoutLogger
erm-g Apr 25, 2023
e17b64e
Fitting StdoutLogger to lb patterns
erm-g Apr 25, 2023
92b53a7
Merge branch 'grpc:master' into AuditLoggerRegistry
erm-g Apr 27, 2023
5665daa
conversion from proto to json for laudit loggers
erm-g Apr 28, 2023
95ebc88
Tests for multiple loggers and empty Options
erm-g Apr 28, 2023
bcf4256
Added LoggerConfig impl
erm-g May 1, 2023
b918c0a
Switched to grpcLogger and added a unit test comparing log with os.St…
erm-g May 4, 2023
861d9f2
Minor fix in exception handling wording
erm-g May 4, 2023
270948b
Added timestamp for logging statement
erm-g May 4, 2023
8859707
Changed format to json and added custom marshalling
erm-g May 7, 2023
c073753
Migration to log.go and additional test for a full event
erm-g May 7, 2023
c6dd904
Migration of stdout logger to a separate package
erm-g May 7, 2023
e72bfa2
migration to grpcLogger, unit test fix
erm-g May 8, 2023
9866f61
Delete xds parsing functionality. Will be done in a separate PR
erm-g May 8, 2023
0d9a56e
Delete xds parsing functionality. Will be done in a separate PR
erm-g May 8, 2023
8c24380
Address PR comments (embedding interface, table test, pointer optimiz…
erm-g May 9, 2023
317f501
vet.sh fixes
erm-g May 9, 2023
e0800ba
Address PR comments
erm-g May 10, 2023
e0c53d8
Commit for go tidy changes
erm-g May 10, 2023
da716bb
vet.sh fix for buf usage
erm-g May 10, 2023
7c36609
Address PR comments
erm-g May 11, 2023
c903401
Address PR comments
erm-g May 11, 2023
9bcb689
Address PR comments (easwars)
erm-g May 12, 2023
a1e3e7a
Address PR comments (luwei)
erm-g May 14, 2023
c74d21b
Migrate printing to standard out from log package level func to a Log…
erm-g May 15, 2023
e6c450b
Changed event Timestamp format back to RFC3339
erm-g May 15, 2023
f60c376
Address PR comments
erm-g May 16, 2023
8f0ad3c
Address PR comments
erm-g May 16, 2023
6ef31dd
Address PR comments
erm-g May 16, 2023
d663a6d
Address PR comments
erm-g May 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion authz/audit/audit_logger.go
Expand Up @@ -79,7 +79,7 @@ type Event struct {
// logger configuration. Concrete types representing configuration of specific
// audit loggers must embed this interface to implement it.
type LoggerConfig interface {
loggerConfig()
LoggerConfig()
erm-g marked this conversation as resolved.
Show resolved Hide resolved
}

// Logger is the interface to be implemented by audit loggers.
Expand Down
101 changes: 101 additions & 0 deletions authz/audit/stdout/stdout_logger.go
@@ -0,0 +1,101 @@
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

// Package stdout contains a Stdout implementation of audit logging interface
// The Stdoutlogger prints the audit.Event using log.go in json format
erm-g marked this conversation as resolved.
Show resolved Hide resolved
package stdout
erm-g marked this conversation as resolved.
Show resolved Hide resolved

import (
"encoding/json"
"log"
"time"

"google.golang.org/grpc/authz/audit"
"google.golang.org/grpc/grpclog"
)

var grpcLogger = grpclog.Component("authz-audit")
erm-g marked this conversation as resolved.
Show resolved Hide resolved

type stdoutEvent struct {
erm-g marked this conversation as resolved.
Show resolved Hide resolved
FullMethodName string `json:"fullMethodName"`
rockspore marked this conversation as resolved.
Show resolved Hide resolved
Principal string `json:"principal"`
PolicyName string `json:"policyName"`
MatchedRule string `json:"matchedRule"`
Authorized bool `json:"authorized"`
//Timestamp is populated using time.Now() during StdoutLogger.Log call
erm-g marked this conversation as resolved.
Show resolved Hide resolved
Timestamp string `json:"timestamp"`
}

// Stdout implementation of audit.Logger

Check failure on line 44 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported type StdoutLogger should be of the form "StdoutLogger ..." (with optional leading article)
type StdoutLogger struct {

Check failure on line 45 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

type name will be used as stdout.StdoutLogger by other packages, and that stutters; consider calling this Logger
erm-g marked this conversation as resolved.
Show resolved Hide resolved
}

// Stdout implementation of audit.Logger.Log

Check failure on line 48 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported method StdoutLogger.Log should be of the form "Log ..."
func (logger *StdoutLogger) Log(event *audit.Event) {
jsonBytes, err := json.Marshal(convertEvent(event))
erm-g marked this conversation as resolved.
Show resolved Hide resolved
rockspore marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
grpcLogger.Errorf("failed to marshal AuditEvent data to JSON: %v", err)
easwars marked this conversation as resolved.
Show resolved Hide resolved
}
log.Println(string(jsonBytes))
}

const (
stdName = "stdout"
rockspore marked this conversation as resolved.
Show resolved Hide resolved
)
easwars marked this conversation as resolved.
Show resolved Hide resolved

// Stdout implementation of audit.LoggerConfig

Check failure on line 61 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported type StdoutLoggerConfig should be of the form "StdoutLoggerConfig ..." (with optional leading article)
// Since the logger doesn't support custom configs, it's a no-op one
type StdoutLoggerConfig struct{}

Check failure on line 63 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

type name will be used as stdout.StdoutLoggerConfig by other packages, and that stutters; consider calling this LoggerConfig

// No-op implementation of audit.LoggerConfig

Check failure on line 65 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported method StdoutLoggerConfig.LoggerConfig should be of the form "LoggerConfig ..."
func (StdoutLoggerConfig) LoggerConfig() {}
erm-g marked this conversation as resolved.
Show resolved Hide resolved

// Stdout implementation of audit.LoggerBuilder

Check failure on line 68 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported type StdoutLoggerBuilder should be of the form "StdoutLoggerBuilder ..." (with optional leading article)
type StdoutLoggerBuilder struct{}

Check failure on line 69 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

type name will be used as stdout.StdoutLoggerBuilder by other packages, and that stutters; consider calling this LoggerBuilder

// Stdout implementation of audit.LoggerBuilder.Name

Check failure on line 71 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported method StdoutLoggerBuilder.Name should be of the form "Name ..."
func (StdoutLoggerBuilder) Name() string {
erm-g marked this conversation as resolved.
Show resolved Hide resolved
return stdName
}

// Stdout implementation of audit.LoggerBuilder.Build

Check failure on line 76 in authz/audit/stdout/stdout_logger.go

View workflow job for this annotation

GitHub Actions / tests (vet, 1.20)

comment on exported method StdoutLoggerBuilder.Build should be of the form "Build ..."
// LoggerConfig is ignored so it always returns default StdoutLogger
func (StdoutLoggerBuilder) Build(audit.LoggerConfig) audit.Logger {
erm-g marked this conversation as resolved.
Show resolved Hide resolved
return &StdoutLogger{}
}

// Stdout implementation of audit.LoggerBuilder.ParseLoggerConfig
// Passed value is ignored but warning is printed
func (StdoutLoggerBuilder) ParseLoggerConfig(config json.RawMessage) (audit.LoggerConfig, error) {
if config != nil {
rockspore marked this conversation as resolved.
Show resolved Hide resolved
grpcLogger.Warningf("Config value %v ignored, "+
gtcooke94 marked this conversation as resolved.
Show resolved Hide resolved
erm-g marked this conversation as resolved.
Show resolved Hide resolved
"StdoutLogger doesn't support custom configs", string(config))
}
return &StdoutLoggerConfig{}, nil
}

func convertEvent(event *audit.Event) stdoutEvent {
erm-g marked this conversation as resolved.
Show resolved Hide resolved
return stdoutEvent{
FullMethodName: event.FullMethodName,
Principal: event.Principal,
PolicyName: event.PolicyName,
MatchedRule: event.MatchedRule,
Authorized: event.Authorized,
Timestamp: time.Now().Format(time.RFC3339),
rockspore marked this conversation as resolved.
Show resolved Hide resolved
}
}
81 changes: 81 additions & 0 deletions authz/audit/stdout/stdout_logger_test.go
@@ -0,0 +1,81 @@
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package stdout

import (
"bytes"
"encoding/json"
"log"
"testing"
"time"

"google.golang.org/grpc/authz/audit"
)

var (
content = json.RawMessage(`{"name": "conf", "val": "to be ignored"}`)
builder = &StdoutLoggerBuilder{}
config, _ = builder.ParseLoggerConfig(content)
auditLogger = builder.Build(config)
)

erm-g marked this conversation as resolved.
Show resolved Hide resolved
func TestStdoutLoggerBuilder_NilConfig(t *testing.T) {
erm-g marked this conversation as resolved.
Show resolved Hide resolved
builder = &StdoutLoggerBuilder{}
config, err := builder.ParseLoggerConfig(nil)
if err != nil {
t.Fatalf("unexpected error\n%v", err)
erm-g marked this conversation as resolved.
Show resolved Hide resolved
}
auditLogger = builder.Build(config)
erm-g marked this conversation as resolved.
Show resolved Hide resolved
}

func TestStdoutLogger_Log(t *testing.T) {
var buf bytes.Buffer
log.SetOutput(&buf)
log.SetFlags(0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these be moved to be inside t.Run?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the first two, but log.SetFlags(0) looks more global so I left it as is

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to have a good reason for them to be outside of t.Run(). I would say move everything to be inside of t.Run() so that your sub-tests are independent of each other.


event := &audit.Event{PolicyName: "test policy", Principal: "test principal"}
auditLogger.Log(event)

expected := `{"fullMethodName":"","principal":"test principal","policyName":"test policy","matchedRule":"","authorized":false`
if buf.String() != (expected + ",\"timestamp\":\"" + time.Now().Format(time.RFC3339) + "\"}\n") {
gtcooke94 marked this conversation as resolved.
Show resolved Hide resolved
t.Fatalf("unexpected error\nwant:%v\n got:%v", expected, buf.String())
}
}

func TestStdoutLogger_LogAllEventFields(t *testing.T) {
var buf bytes.Buffer
log.SetOutput(&buf)
log.SetFlags(0)

event := &audit.Event{
FullMethodName: "/helloworld.Greeter/SayHello",
Principal: "spiffe://example.org/ns/default/sa/default/backend",
PolicyName: "example-policy",
MatchedRule: "dev-access",
Authorized: true,
}
auditLogger.Log(event)

expected := `{"fullMethodName":"/helloworld.Greeter/SayHello",` +
`"principal":"spiffe://example.org/ns/default/sa/default/backend","policyName":"example-policy",` +
`"matchedRule":"dev-access","authorized":true`
if buf.String() != (expected + ",\"timestamp\":\"" + time.Now().Format(time.RFC3339) + "\"}\n") {
gtcooke94 marked this conversation as resolved.
Show resolved Hide resolved
t.Fatalf("unexpected error\nwant:%v\n got:%v", expected, buf.String())
}
}