feat: add metric feature support in goframe (#3138)

This commit is contained in:
John Guo
2024-03-24 21:18:30 +08:00
committed by GitHub
parent 313d9d138f
commit 8669512f42
103 changed files with 6056 additions and 751 deletions

View File

@ -0,0 +1,95 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
//
package response
import (
"bytes"
"net/http"
)
// BufferWriter is the custom writer for http response with buffer.
type BufferWriter struct {
*Writer // The underlying BufferWriter.
Status int // HTTP status.
buffer *bytes.Buffer // The output buffer.
}
func NewBufferWriter(writer http.ResponseWriter) *BufferWriter {
return &BufferWriter{
Writer: NewWriter(writer),
buffer: bytes.NewBuffer(nil),
}
}
// RawWriter returns the underlying BufferWriter.
func (w *BufferWriter) RawWriter() http.ResponseWriter {
return w.Writer
}
// Write implements the interface function of http.BufferWriter.Write.
func (w *BufferWriter) Write(data []byte) (int, error) {
return w.buffer.Write(data)
}
// WriteString writes string content to internal buffer.
func (w *BufferWriter) WriteString(data string) (int, error) {
return w.buffer.WriteString(data)
}
// Buffer returns the buffered content as []byte.
func (w *BufferWriter) Buffer() []byte {
return w.buffer.Bytes()
}
// BufferString returns the buffered content as string.
func (w *BufferWriter) BufferString() string {
return w.buffer.String()
}
// BufferLength returns the length of the buffered content.
func (w *BufferWriter) BufferLength() int {
return w.buffer.Len()
}
// SetBuffer overwrites the buffer with `data`.
func (w *BufferWriter) SetBuffer(data []byte) {
w.buffer.Reset()
w.buffer.Write(data)
}
// ClearBuffer clears the response buffer.
func (w *BufferWriter) ClearBuffer() {
w.buffer.Reset()
}
// WriteHeader implements the interface of http.BufferWriter.WriteHeader.
func (w *BufferWriter) WriteHeader(status int) {
w.Status = status
}
// Flush outputs the buffer to clients and clears the buffer.
func (w *BufferWriter) Flush() {
if w.Writer.IsHijacked() {
return
}
if w.Status != 0 && !w.Writer.IsHeaderWrote() {
w.Writer.WriteHeader(w.Status)
}
// Default status text output.
if w.Status != http.StatusOK && w.buffer.Len() == 0 {
w.buffer.WriteString(http.StatusText(w.Status))
}
if w.buffer.Len() > 0 {
_, _ = w.Writer.Write(w.buffer.Bytes())
w.buffer.Reset()
if flusher, ok := w.RawWriter().(http.Flusher); ok {
flusher.Flush()
}
}
}

View File

@ -14,9 +14,10 @@ import (
// Writer wraps http.ResponseWriter for extra features.
type Writer struct {
http.ResponseWriter // The underlying ResponseWriter.
hijacked bool // Mark this request is hijacked or not.
wroteHeader bool // Is header wrote or not, avoiding error: superfluous/multiple response.WriteHeader call.
http.ResponseWriter // The underlying ResponseWriter.
hijacked bool // Mark this request is hijacked or not.
wroteHeader bool // Is header wrote or not, avoiding error: superfluous/multiple response.WriteHeader call.
bytesWritten int64 // Bytes written to response.
}
// NewWriter creates and returns a new Writer.
@ -32,6 +33,18 @@ func (w *Writer) WriteHeader(status int) {
w.wroteHeader = true
}
// BytesWritten returns the length that was written to response.
func (w *Writer) BytesWritten() int64 {
return w.bytesWritten
}
// Write implements the interface function of http.ResponseWriter.Write.
func (w *Writer) Write(data []byte) (int, error) {
n, err := w.ResponseWriter.Write(data)
w.bytesWritten += int64(n)
return n, err
}
// Hijack implements the interface function of http.Hijacker.Hijack.
func (w *Writer) Hijack() (conn net.Conn, writer *bufio.ReadWriter, err error) {
conn, writer, err = w.ResponseWriter.(http.Hijacker).Hijack()