Skip to content

Instantly share code, notes, and snippets.

@WillAbides
Created July 10, 2023 19:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WillAbides/6d7052b95f0a8e829dc1f3e349775fe8 to your computer and use it in GitHub Desktop.
Save WillAbides/6d7052b95f0a8e829dc1f3e349775fe8 to your computer and use it in GitHub Desktop.
package actionslog
import (
"bytes"
"context"
"io"
"log/slog"
"sync"
)
type Wrapper struct {
handler slog.Handler
writer io.Writer
}
func NewWrapper(w io.Writer, handler func(io.Writer) slog.Handler) *Wrapper {
return &Wrapper{
handler: handler(&escapeWriter{w: w}),
writer: w,
}
}
func (w *Wrapper) Enabled(ctx context.Context, level slog.Level) bool {
return w.handler.Enabled(ctx, level)
}
func (w *Wrapper) Handle(ctx context.Context, record slog.Record) error {
ghLog := "error"
switch {
case record.Level < slog.LevelInfo:
ghLog = "debug"
case record.Level < slog.LevelWarn:
ghLog = "notice"
case record.Level < slog.LevelError:
ghLog = "warning"
}
_, err := io.WriteString(w.writer, "::" + ghLog + "::")
if err != nil {
return err
}
err = w.handler.Handle(ctx, record)
if err != nil {
return err
}
_, err = w.writer.Write([]byte{'\n'})
return err
}
func (w *Wrapper) WithAttrs(attrs []slog.Attr) slog.Handler {
return &Wrapper{
handler: w.handler.WithAttrs(attrs),
writer: w.writer,
}
}
func (w *Wrapper) WithGroup(name string) slog.Handler {
return &Wrapper{
handler: w.handler.WithGroup(name),
writer: w.writer,
}
}
type escapeWriter struct {
w io.Writer
pool sync.Pool
}
func (e *escapeWriter) Write(p []byte) (int, error) {
n := 0
buf, ok := e.pool.Get().(*[]byte)
if !ok {
b := make([]byte, 0, len(p))
buf = &b
}
defer e.pool.Put(buf)
*buf = (*buf)[:0]
for len(p) > 0 {
i := bytes.IndexAny(p, "\n\r%")
if i < 0 {
*buf = append(*buf, p...)
break
}
*buf = append(*buf, p[:i]...)
p = p[i:]
n += i
switch p[0] {
case '\n':
*buf = append(*buf, "%0A"...)
case '\r':
*buf = append(*buf, "%0D"...)
case '%':
*buf = append(*buf, "%25"...)
}
p = p[1:]
n++
}
return n, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment