Skip to content

Commit

Permalink
PLTFRS-15345 use structured log (#10)
Browse files Browse the repository at this point in the history
* refact: use slog

* refact: removing custom logger
  • Loading branch information
cthirouin-swi authored Oct 1, 2024
1 parent c48c8d7 commit 0f8564e
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 93 deletions.
25 changes: 6 additions & 19 deletions airvantage.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import (
"encoding/json"
"fmt"
"io"
"log"
"log/slog"
"net/http"
"net/url"
"os"
"regexp"
"strings"
"time"
Expand All @@ -21,16 +20,13 @@ const (
defaultTimeout = 5 * time.Second
)

var defaultLogger = log.New(os.Stderr, "", log.LstdFlags)

// AirVantage API client using oAuth2
type AirVantage struct {
client *http.Client
CompanyUID string
Debug bool
baseURLv1 *url.URL
baseURLv2 *url.URL
log *log.Logger
}

// NewClient logins to AirVantage an returns a new API client.
Expand All @@ -57,6 +53,7 @@ func NewClient(host, clientID, clientSecret, login, password string) (*AirVantag

ctx := context.WithValue(context.Background(), oauth2.HTTPClient, http.Client{Timeout: defaultTimeout})

slog.Info("Fetching OAuth token")
token, err := conf.PasswordCredentialsToken(ctx, login, password)
if err != nil {
return nil, err
Expand All @@ -66,7 +63,6 @@ func NewClient(host, clientID, clientSecret, login, password string) (*AirVantag
client: conf.Client(ctx, token),
baseURLv1: &url.URL{Host: host, Scheme: scheme, Path: "/api/v1/"},
baseURLv2: &url.URL{Host: host, Scheme: scheme, Path: "/api/v2/"},
log: defaultLogger,
},
nil
}
Expand Down Expand Up @@ -117,7 +113,8 @@ func (av *AirVantage) parseResponse(resp *http.Response, respStruct any) error {
if err != nil {
return err
}
av.log.Printf("Path: %s\nContent: %s\n", resp.Request.URL, string(body))
slog.Debug("Parsing response", "path", resp.Request.URL.String(), "content", string(body))

payload = bytes.NewReader(body)
}

Expand Down Expand Up @@ -146,9 +143,7 @@ func (av *AirVantage) parseResponseSerializedJava(resp *http.Response, respStruc
if err != nil {
return err
}
if av.Debug {
av.log.Printf("Path: %s\nContent: %s\n", resp.Request.URL, string(body))
}
slog.Debug("Parsing serialized java response", "path", resp.Request.URL.String(), "content", string(body))

// use a regexp to remove the Java object reference from the response
// it's much easier to do that rather than parsing json into a []any
Expand All @@ -168,10 +163,7 @@ func (av *AirVantage) parseError(resp *http.Response) error {
if err != nil {
return err
}

if av.Debug {
av.log.Printf("Path: %s\nContent: %s\n", resp.Request.URL, string(body))
}
slog.Debug("Parsing error", "path", resp.Request.URL.String(), "content", string(body))

if len(body) == 0 {
return fmt.Errorf("error %d %s", resp.StatusCode, resp.Status)
Expand All @@ -189,11 +181,6 @@ func (av *AirVantage) parseError(resp *http.Response) error {
return nil
}

// SetLogger allows you to set a custom logger instead of Go's default.
func (av *AirVantage) SetLogger(logger *log.Logger) {
av.log = logger
}

// SetTimeout sets the request timeout of the HTTP client.
func (av *AirVantage) SetTimeout(timeout time.Duration) {
av.client.Timeout = timeout
Expand Down
5 changes: 2 additions & 3 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"log/slog"
"mime/multipart"
"net/url"
"strings"
Expand Down Expand Up @@ -84,9 +85,7 @@ func (av *AirVantage) AwaitOperation(opUID string, timeout time.Duration) (*Oper
return nil, err
}

if av.Debug {
av.log.Printf("DBG operation %+v\n", op)
}
slog.Debug("Waiting Operation", "uid", op)

if op.State == "FINISHED" {
return op, nil
Expand Down
114 changes: 114 additions & 0 deletions simpleloghandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// https://github.com/jba/slog/blob/main/handlers/loghandler/log_handler.go
// loghandler provides a slog.Handler whose output resembles that of [log.Logger].
package airvantage

import (
"context"
"fmt"
"io"
"log/slog"
"runtime"
"strconv"
"sync"
"time"
)

type SimpleLogHandler struct {
opts slog.HandlerOptions
prefix string // preformatted group names followed by a dot
preformat string // preformatted Attrs, with an initial space

mu sync.Mutex
w io.Writer
}

func NewSimpleLogHandler(w io.Writer, opts *slog.HandlerOptions) *SimpleLogHandler {
h := &SimpleLogHandler{w: w}
if opts != nil {
h.opts = *opts
}
if h.opts.ReplaceAttr == nil {
h.opts.ReplaceAttr = func(_ []string, a slog.Attr) slog.Attr { return a }
}
return h
}

func (h *SimpleLogHandler) Enabled(ctx context.Context, level slog.Level) bool {
minLevel := slog.LevelInfo
if h.opts.Level != nil {
minLevel = h.opts.Level.Level()
}
return level >= minLevel
}

func (h *SimpleLogHandler) WithGroup(name string) slog.Handler {
return &SimpleLogHandler{
w: h.w,
opts: h.opts,
preformat: h.preformat,
prefix: h.prefix + name + ".",
}
}

func (h *SimpleLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
var buf []byte
for _, a := range attrs {
buf = h.appendAttr(buf, h.prefix, a)
}
return &SimpleLogHandler{
w: h.w,
opts: h.opts,
prefix: h.prefix,
preformat: h.preformat + string(buf),
}
}

func (h *SimpleLogHandler) Handle(ctx context.Context, r slog.Record) error {
var buf []byte
if !r.Time.IsZero() {
buf = r.Time.AppendFormat(buf, time.RFC3339)
buf = append(buf, ' ')
}
buf = append(buf, r.Level.String()...)
buf = append(buf, ' ')
if h.opts.AddSource && r.PC != 0 {
fs := runtime.CallersFrames([]uintptr{r.PC})
f, _ := fs.Next()
buf = append(buf, f.File...)
buf = append(buf, ':')
buf = strconv.AppendInt(buf, int64(f.Line), 10)
buf = append(buf, ' ')
}
buf = append(buf, r.Message...)
buf = append(buf, h.preformat...)
r.Attrs(func(a slog.Attr) bool {
buf = h.appendAttr(buf, h.prefix, a)
return true
})
buf = append(buf, '\n')
h.mu.Lock()
defer h.mu.Unlock()
_, err := h.w.Write(buf)
return err
}

func (h *SimpleLogHandler) appendAttr(buf []byte, prefix string, a slog.Attr) []byte {
if a.Equal(slog.Attr{}) {
return buf
}
if a.Value.Kind() != slog.KindGroup {
buf = append(buf, ' ')
buf = append(buf, prefix...)
buf = append(buf, a.Key...)
buf = append(buf, '=')
return fmt.Appendf(buf, "%v", a.Value.Any())
}
// Group
if a.Key != "" {
prefix += a.Key + "."
}
for _, a := range a.Value.Group() {
buf = h.appendAttr(buf, prefix, a)
}
return buf
}
Loading

0 comments on commit 0f8564e

Please sign in to comment.