-
Notifications
You must be signed in to change notification settings - Fork 98
Praposal for logging support for msal-go #535
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
Open
4gust
wants to merge
33
commits into
andyohart/managed-identity
Choose a base branch
from
4gust/logging-praposal
base: andyohart/managed-identity
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 23 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
a58420b
Added MD file
4gust 57f484f
Updated callback support in 1.21 as well
4gust deb5d6e
Updated logging with files
4gust e855af1
* Pushes changes needed for logging, including removing support for 1…
AndyOHart 0ba0540
* Changes how logger works so that we can create a logger implementat…
AndyOHart 77d735e
* remove unneeded log
AndyOHart e6aa078
* moves context.Background to internal implementation
AndyOHart dffa979
* Makes changes so WithLogger is only accessible for 1.21 and above
AndyOHart aa59b0f
* Updates logic to create default logger instance and remove returnin…
AndyOHart da84180
* Updates to remove LoggerInterface
AndyOHart 435bbb6
* Adds missing functions to help compile go1.18
AndyOHart 1a2ccbf
* Updates logger to remove LoggerInterface
AndyOHart bc17181
* Updates packages to use slog instead of logger
AndyOHart f4639c5
* Updates to use pointer
AndyOHart fca7a8a
* update documentation
AndyOHart 61b5358
* Removed some uneeded fileds and information
AndyOHart c9b47f5
* More PR Changes
AndyOHart 6d69a31
Changes to how logger works
AndyOHart ca09100
Merge remote-tracking branch 'origin/andyohart/managed-identity' into…
AndyOHart 41d9c77
* Adds logger to managed identity
AndyOHart 281d376
* Some small fixes such as extra lines and some comments being removed
AndyOHart 0ef46fe
Update documentation WithLogger
AndyOHart 7232018
Documentation update
AndyOHart dee0a5d
Address PR comments
AndyOHart 2f88c40
* Add ability to pass WithPiiLogging
AndyOHart 21ab563
* Update documentation
AndyOHart 6a8d621
* Update documentation
AndyOHart f284171
* Removes separate WithPiiLogging to add bool to WithLogger
AndyOHart b37530d
Merge remote-tracking branch 'origin/andyohart/managed-identity' into…
AndyOHart 2da41d2
* PR Changes
AndyOHart 72611ca
Updated the file name
4gust 0122e72
* Address some PR Comments
AndyOHart 6d52633
* Use context of the function rather than the logOnce
AndyOHart File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Logging | ||
|
||
GO 1.21 introduces enhanced features like structured logging with `log/slog`. | ||
As part of MSAL GO, we have decided to only support logging using slog from version 1.21. | ||
The reason for this is `log/slog` greatly enhances the debugging and monitoring capabilities compared to the old SDK. This is especially useful in production environments where accurate, traceable logs are crucial for maintaining application health and troubleshooting issues. | ||
|
||
## **Expected Output** | ||
|
||
```plaintext | ||
time=2024-12-19T01:25:58.730Z level=INFO msg="This is an info message via slog." username=john_doe age=30 | ||
time=2024-12-19T01:25:58.730Z level=ERROR msg="This is an error message via slog." module=user-service retry=3 | ||
time=2024-12-19T01:25:58.730Z level=WARN msg="Disk space is low." free_space_mb=100 | ||
time=2024-12-19T01:25:58.730Z level=INFO msg="Default log message." module=main | ||
``` | ||
|
||
## Key Pointers | ||
|
||
1. **Full `slog` Support for Go 1.21+**: | ||
- The `logger.go` file leverages the `slog` package, supporting structured logs, multiple log levels (`info`, `error`, `warn`), and fields. | ||
|
||
2. **Structured Logging**: | ||
- You can pass key-value pairs using `slog.String`, `slog.Int`, etc., for structured logging, which is handled by `slog` in Go 1.21 and later. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
//go:build go1.21 | ||
|
||
package slog | ||
|
||
import ( | ||
"context" | ||
"log/slog" | ||
) | ||
|
||
type Level = slog.Level | ||
|
||
const ( | ||
LevelDebug = slog.LevelDebug | ||
LevelInfo = slog.LevelInfo | ||
LevelWarn = slog.LevelWarn | ||
LevelError = slog.LevelError | ||
) | ||
|
||
type Handler = slog.Handler | ||
type Logger = slog.Logger | ||
type NopHandler struct{} | ||
|
||
func (*NopHandler) Enabled(context.Context, slog.Level) bool { return false } | ||
func (*NopHandler) Handle(context.Context, slog.Record) error { return nil } | ||
func (h *NopHandler) WithAttrs([]slog.Attr) slog.Handler { return h } | ||
func (h *NopHandler) WithGroup(string) slog.Handler { return h } | ||
|
||
// New creates a new logger instance for Go 1.21+ with full `slog` logging support. | ||
func New(h Handler) *Logger { | ||
return slog.New(h) | ||
} | ||
|
||
// Any creates a slog field for any value | ||
func Any(key string, value any) any { | ||
return slog.Any(key, value) | ||
} | ||
|
||
// String creates a slog field for a string value | ||
func String(key, value string) slog.Attr { | ||
return slog.String(key, value) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
//go:build !go1.21 | ||
|
||
package slog | ||
|
||
import ( | ||
"context" | ||
) | ||
|
||
type Level int | ||
|
||
type Logger struct{} | ||
|
||
const ( | ||
LevelDebug Level = iota | ||
LevelInfo | ||
LevelWarn | ||
LevelError | ||
) | ||
|
||
type NopHandler struct{} | ||
AndyOHart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// These are all noop functions for go < 1.21 | ||
func New(h any) *Logger { | ||
return &Logger{} | ||
} | ||
|
||
func Any(key string, value any) any { | ||
return nil | ||
} | ||
|
||
func String(key, value string) any { | ||
return nil | ||
} | ||
|
||
func (*Logger) Log(ctx context.Context, level Level, msg string, args ...any) {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
//go:build go1.21 | ||
|
||
package slog | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"log/slog" | ||
"testing" | ||
) | ||
|
||
func TestLogger_Log_ConsoleOutput(t *testing.T) { | ||
// Capture the console output | ||
var buf bytes.Buffer | ||
|
||
// Create a new JSON handler | ||
handler := slog.NewJSONHandler(&buf, &slog.HandlerOptions{ | ||
Level: slog.LevelDebug, // Set the log level to Debug to capture all log levels | ||
}) | ||
|
||
// Create a new logger instance with the handler | ||
loggerInstance := New(handler) | ||
|
||
// Log messages | ||
loggerInstance.Log(context.Background(), slog.LevelInfo, "This is an info message via slog.", slog.Any("username", "john_doe"), slog.Int("age", 30)) | ||
loggerInstance.Log(context.Background(), slog.LevelError, "This is an error message via slog.", slog.String("module", "user-service"), slog.Int("retry", 3)) | ||
loggerInstance.Log(context.Background(), slog.LevelWarn, "This is a warn message via slog.", slog.Int("free_space_mb", 100)) | ||
loggerInstance.Log(context.Background(), slog.LevelDebug, "This is a debug message via slog.", slog.String("module", "main")) | ||
|
||
// Check the output | ||
output := buf.String() | ||
expectedMessages := []struct { | ||
msg string | ||
contains []string | ||
}{ | ||
{"This is an info message via slog.", []string{`"username":"john_doe"`, `"age":30}`}}, | ||
{"This is an error message via slog.", []string{`"module":"user-service"`, `"retry":3}`}}, | ||
{"This is a warn message via slog.", []string{`"free_space_mb":100}`}}, | ||
{"This is a debug message via slog.", []string{`"module":"main"`}}, | ||
} | ||
|
||
for _, expected := range expectedMessages { | ||
if !bytes.Contains([]byte(output), []byte(expected.msg)) { | ||
t.Errorf("expected log message %q not found in output", expected.msg) | ||
} | ||
for _, attr := range expected.contains { | ||
if !bytes.Contains([]byte(output), []byte(attr)) { | ||
t.Errorf("expected attribute %q not found in output for message %q", attr, expected.msg) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestNewLogger_ValidSlogHandler(t *testing.T) { | ||
// Test case where handler is a valid slog.Handler | ||
var buf bytes.Buffer | ||
handler := slog.NewJSONHandler(&buf, &slog.HandlerOptions{ | ||
Level: slog.LevelDebug, | ||
}) | ||
logInstance := New(handler) | ||
if logInstance == nil { | ||
AndyOHart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
t.Fatalf("expected non-nil logInstance, got nil") | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.