Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenwallis committed Aug 10, 2023
1 parent 201236e commit 56ca33f
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 0 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: CI

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read
pull-requests: read

jobs:
ci:
name: ci | ${{ matrix.go_version }}
runs-on: ubuntu-latest

strategy:
matrix:
go_version: ["1.21"]

steps:
- uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go_version }}
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
only-new-issues: true

- name: Make out dir
run: |
mkdir out
- name: Run tests
run: |
go test -race ./... -coverprofile=out/coverage.txt -covermode=atomic
- name: Upload coverage
uses: codecov/codecov-action@v2
with:
files: out/coverage.txt

# Ensures all matrix jobs complete before passing the build
complete:
name: complete
if: ${{ always() }}
needs: [ci]
runs-on: ubuntu-latest
steps:
- name: Check that all steps completed
run: |
[ "${{ needs.ci.result }}" != "success" ] && echo "CI failed." && exit 1;
echo "CI succeeded!";
exit 0;
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# slogctx

Simple [slog](https://pkg.go.dev/log/slog) wrapping handler that lets you pass fields down to a slog call through context.


3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/aidenwallis/slogctx

go 1.21
46 changes: 46 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package slogctx

import (
"context"
"log/slog"
)

type contextKey uint8

const (
argsKey contextKey = iota
)

// GetArgs returns the args currently found in context, or nil
func GetArgs(ctx context.Context) []any {
if v, ok := ctx.Value(argsKey).([]any); ok {
return v
}
return nil
}

// WithArgs appends slog args to context
func WithArgs(ctx context.Context, args ...any) context.Context {
return context.WithValue(ctx, argsKey, append(GetArgs(ctx), args...))
}

// Handler wraps a given slog handler, and applies extra fields to the call
type Handler struct {
slog.Handler
}

var _ slog.Handler = (*Handler)(nil)

// NewHandler creates a new instance of Handler
func NewHandler(handler slog.Handler) *Handler {
return &Handler{Handler: handler}
}

// Handle appends any fields from context to the record and calls the nested handler
func (h *Handler) Handle(ctx context.Context, r slog.Record) error {
if v := GetArgs(ctx); len(v) > 0 {
r.Add(v...)
}

return h.Handler.Handle(ctx, r)
}
57 changes: 57 additions & 0 deletions handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package slogctx_test

import (
"context"
"log/slog"
"testing"

"github.com/aidenwallis/slogctx"
)

type testHandler struct {
slog.Handler
lastRecord slog.Record
ch chan struct{}
}

func (h *testHandler) wait() {
<-h.ch
}

func (h *testHandler) Handle(ctx context.Context, r slog.Record) error {
h.lastRecord = r
h.ch <- struct{}{}
return nil
}

var _ slog.Handler = (*testHandler)(nil)

func TestHandler(t *testing.T) {
ctx := context.Background()

handler := &testHandler{
Handler: slog.NewTextHandler(nil, nil),
ch: make(chan struct{}, 1), // allows the test to pause for the lastRecord to be written
}
logger := slog.New(slogctx.NewHandler(handler))

// default case: should have 0 attrs
logger.InfoContext(ctx, "test message")
handler.wait()
assert(t, handler.lastRecord.NumAttrs(), 0)

ctx = slogctx.WithArgs(ctx, "abc", 123)

// should now have 1 attr from the ctx
logger.InfoContext(ctx, "test message")
handler.wait()
assert(t, handler.lastRecord.NumAttrs(), 1)
}

func assert[T comparable](t *testing.T, in, expected T) {
t.Helper()

if in != expected {
t.Fatalf("expected %#v but got %#v", expected, in)
}
}
7 changes: 7 additions & 0 deletions view-coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

# This small script simply runs the tests and opens a browser window of the results.
# From: https://stackoverflow.com/a/27284510

t="/tmp/go-cover.$$.tmp"
go test -coverprofile=$t -race ./... $@ && go tool cover -html=$t && unlink $t

0 comments on commit 56ca33f

Please sign in to comment.