mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 02:09:01 +02:00
fix(rules): buffer log output before writing to stdout/stderr
This commit is contained in:
@@ -470,17 +470,29 @@ var commands = map[string]struct {
|
|||||||
build: func(args any) HandlerFunc {
|
build: func(args any) HandlerFunc {
|
||||||
level, f, tmpl := args.(*onLogArgs).Unpack()
|
level, f, tmpl := args.(*onLogArgs).Unpack()
|
||||||
var logger io.Writer
|
var logger io.Writer
|
||||||
if f == stdout || f == stderr {
|
isStdLogger := f == stdout || f == stderr
|
||||||
|
if isStdLogger {
|
||||||
logger = logging.NewLoggerWithFixedLevel(level, f)
|
logger = logging.NewLoggerWithFixedLevel(level, f)
|
||||||
} else {
|
} else {
|
||||||
logger = f
|
logger = f
|
||||||
}
|
}
|
||||||
return func(w *httputils.ResponseModifier, r *http.Request, upstream http.HandlerFunc) error {
|
return func(w *httputils.ResponseModifier, r *http.Request, upstream http.HandlerFunc) error {
|
||||||
_, err := tmpl.ExpandVars(w, r, logger)
|
if isStdLogger {
|
||||||
if err != nil {
|
bufPool := w.BufPool()
|
||||||
|
buf := bufPool.GetBuffer()
|
||||||
|
defer bufPool.PutBuffer(buf)
|
||||||
|
|
||||||
|
if _, err := tmpl.ExpandVars(w, r, buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if buf.Len() == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err := logger.Write(buf.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
_, err := tmpl.ExpandVars(w, r, logger)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package rules
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -8,6 +9,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -69,6 +71,17 @@ default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLogCommand_StdoutAndStderr(t *testing.T) {
|
func TestLogCommand_StdoutAndStderr(t *testing.T) {
|
||||||
|
originalStdout := stdout
|
||||||
|
originalStderr := stderr
|
||||||
|
var stdoutBuf bytes.Buffer
|
||||||
|
var stderrBuf bytes.Buffer
|
||||||
|
stdout = noopWriteCloser{&stdoutBuf}
|
||||||
|
stderr = noopWriteCloser{&stderrBuf}
|
||||||
|
defer func() {
|
||||||
|
stdout = originalStdout
|
||||||
|
stderr = originalStderr
|
||||||
|
}()
|
||||||
|
|
||||||
upstream := mockUpstream(http.StatusOK, "success")
|
upstream := mockUpstream(http.StatusOK, "success")
|
||||||
|
|
||||||
var rules Rules
|
var rules Rules
|
||||||
@@ -88,8 +101,12 @@ default {
|
|||||||
handler.ServeHTTP(w, req)
|
handler.ServeHTTP(w, req)
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, w.Code)
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
// Note: We can't easily capture stdout/stderr in unit tests,
|
require.Eventually(t, func() bool {
|
||||||
// but we can verify no errors occurred and the handler completed
|
return strings.Contains(stdoutBuf.String(), "stdout: GET 200") &&
|
||||||
|
strings.Contains(stderrBuf.String(), "stderr: /test 200")
|
||||||
|
}, time.Second, 10*time.Millisecond)
|
||||||
|
assert.Equal(t, 1, strings.Count(stdoutBuf.String(), "stdout: GET 200"))
|
||||||
|
assert.Equal(t, 1, strings.Count(stderrBuf.String(), "stderr: /test 200"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLogCommand_DifferentLogLevels(t *testing.T) {
|
func TestLogCommand_DifferentLogLevels(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user