httplog

package module
v0.0.0-...-6780988 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2021 License: MIT Imports: 26 Imported by: 0

README

httplog

Travis CI Software License GoDoc Coverage Status goreport

httplog golang version. see java version

Usage

Import

go get github.com/bingoohuang/httplog

Standard http wrapper
mux := httplog.NewMux(http.NewServeMux(), httplog.NewLogrusStore())
mux.HandleFunc("/echo", handleIndex, httplog.Biz("回显处理"))
mux.HandleFunc("/json", handleJSON, httplog.Biz("JSON处理"))
mux.HandleFunc("/ignored", handleIgnore, httplog.Ignore(true))
mux.HandleFunc("/noname", handleNoname)

server := http.Server{Addr: ":8080", Handler: mux}
log.Fatal(server.ListenAndServe())
Gin wrapper
router := httplog.NewGin(gin.New(), httplog.NewLogrusStore())

router.GET("/hello/:name", ctler.Hello, httplog.Biz("你好"))
router.GET("/bypass/:name", ctler.Bypass, httplog.Ignore(true))

// 监听运行于 0.0.0.0:8080
router.Run(":8080")
save log to SQL database
DSN := `root:root@tcp(127.0.0.1:3306)/httplog?charset=utf8mb4&parseTime=true&loc=Local`
db, _ := sql.Open("mysql", DSN)
store := httplog.NewSQLStore(db, "")
router := httplog.NewGin(gin.New(), store)

router.GET("/hello/:name", ctler.Hello, httplog.Biz("你好"), httplog.Tables("biz_log"))
router.GET("/bypass/:name", ctler.Bypass, httplog.Ignore(true))

// 监听运行于 0.0.0.0:8080
router.Run(":8080")
Prepare log tables

业务日志表定义,根据具体业务需要,必须字段为主键id(名字固定), 示例: mysql

日志表建表规范

字段注释包含 或者字段名 说明
内置类:
httplog:"id" id 日志记录ID
httplog:"created" created 创建时间
httplog:"ip" ip 当前机器IP
httplog:"addr" addr http客户端地址
httplog:"hostname" hostname 当前机器名称
httplog:"pid" pid 应用程序PID
httplog:"started" start 开始时间
httplog:"end" end 结束时间
httplog:"cost" cost 花费时间(ms)
httplog:"biz" biz 业务名称,eg httplog.Biz("项目列表")
请求类:
httplog:"req_head_xxx" req_head_xxx 请求中的xxx头
httplog:"req_heads" req_heads 请求中的所有头
httplog:"req_method" req_method 请求method
httplog:"req_url" req_url 请求URL
httplog:"req_path_xxx" req_path_xxx 请求URL中的xxx路径参数
httplog:"req_paths" req_paths 请求URL中的所有路径参数
httplog:"req_query_xxx" req_query_xxx 请求URl中的xxx查询参数
httplog:"req_queries" req_queries 请求URl中的所有查询参数
httplog:"req_param_xxx" req_param_xxx 请求中query/form的xxx参数
httplog:"req_params" req_params 请求中query/form的所有参数
httplog:"req_body" req_body 请求体
httplog:"req_json" req_json 请求体(当Content-Type为JSON时)
httplog:"req_json_xxx" req_json_xxx 请求体JSON中的xxx属性
响应类:
httplog:"rsp_head_xxx" rsp_head_xxx 响应中的xxx头
httplog:"rsp_heads" rsp_heads 响应中的所有头
httplog:"rsp_body" rsp_body 响应体
httplog:"rsp_json" rsp_json 响应体JSON(当Content-Type为JSON时)
httplog:"rsp_json_xxx" rsp_json_xxx 请求体JSON中的xxx属性
httplog:"rsp_status" rsp_status 响应编码
上下文:
httplog:"ctx_xxx" ctx_xxx 上下文对象xxx的值, 通过api设置: httplog.PutAttr(r, "xxx", "yyy") 或者 httplog.PutAttrMap(r, httplog.Attrs{"name": "alice", "female": true})
Ctrler examples
type Ctrler struct {
	Hello  gin.HandlerFunc `route:"GET /hello/:name" name:"你好"`
	Bypass gin.HandlerFunc `route:"POST /bypass/:name" ignore:"true"`
}

func main) {
	ctler := Ctrler{
		Hello: func(context *gin.Context) {
			context.String(200, "welcome "+context.Param("name"))
		},
		Bypass: func(context *gin.Context) {
			context.String(200, "welcome "+context.Param("name"))
		},
	}

	router := httplog.NewGin(gin.New(), &httplog.LogrusStore{})
	router.RegisterCtler(ctler)
    // 监听运行于 0.0.0.0:8080
    router.Run(":8080")
}

Scripts

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"username":"xyz","password":"xyz"}' \
  http://localhost:8100

Resources

  1. Logging HTTP requests in Go
  2. httpsnoop provides an easy way to capture http related metrics (i.e. response time, bytes written, and http status code) from your application's http.Handlers.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	JSONUnmarshal     = jsoniter.Unmarshal
	JSONMarshal       = jsoniter.Marshal
	JSONMarshalIndent = jsoniter.MarshalIndent
)

nolint

Functions

func Abbreviate

func Abbreviate(str string, maxWidth int) string

Abbreviate abbreviates a string using ellipses.

func At

func At(s []string, i int) string

At returns the element of index i in the slice s.

func ContainsFold

func ContainsFold(a, b string) bool

ContainsFold tell if a contains b in case-insensitively.

func FirstWord

func FirstWord(s string) string

FirstWord returns the first word of the SQL statement s.

func GetRemoteAddress

func GetRemoteAddress(r *http.Request) string

GetRemoteAddress returns ip address of the client making the request, taking into account http proxies.

func IPAddrFromRemoteAddr

func IPAddrFromRemoteAddr(s string) string

IPAddrFromRemoteAddr parses the IP Address. Request.RemoteAddress contains port, which we want to remove i.e.: "[::1]:58292" => "[::1]".

func IfElse

func IfElse(ifCondition bool, ifValue, elseValue string) string

IfElse if else ...

func ImplSQLScanner

func ImplSQLScanner(t reflect.Type) bool

ImplSQLScanner tells t whether it implements sql.Scanner interface.

func ImplType

func ImplType(src, target reflect.Type) bool

ImplType tells src whether it implements target type.

func IsQuerySQL

func IsQuerySQL(sql string) (string, bool)

IsQuerySQL tests a sql is a query or not.

func IsWsRequest

func IsWsRequest(url string) bool

IsWsRequest return true if this request is a websocket request.

func LookupDriverName

func LookupDriverName(driver driver.Driver) string

LookupDriverName get driverName from the driver instance. The database/sql API doesn't provide a way to get the registry name for a driver from the driver type. from https://github.com/golang/go/issues/12600

func PeekBody

func PeekBody(r *http.Request, maxSize int) []byte

PeekBody peeks the maxSize body from the request limit to maxSize bytes.

func PerformRequest

func PerformRequest(method, target string, fn http.Handler, fns ...RequestVarsFn) *httptest.ResponseRecorder

PerformRequest performs a test request. from https://github.com/gin-gonic/gin/issues/1120.

func PutAttr

func PutAttr(r *http.Request, key string, value interface{})

PutAttr put an attribute into the Attributes in the context.

func PutAttrMap

func PutAttrMap(r *http.Request, attrs Attrs)

PutAttrMap put an attribute map into the Attributes in the context.

func WriteJSON

func WriteJSON(w http.ResponseWriter, obj interface{}) error

WriteJSON marshals the given interface object and writes it with custom ContentType.

Types

type Attrs

type Attrs map[string]interface{}

Attrs carries map. It implements value for that key and delegates all other calls to the embedded Context.

func ParseAttrs

func ParseAttrs(r *http.Request) Attrs

ParseAttrs returns the attributes map from the request context.

type ContextKey

type ContextKey int

ContextKey defines the context key type.

const (
	// CtxKey defines the context key for CtxVar.
	CtxKey ContextKey = iota
)

type CtxVar

type CtxVar struct {
	Req   *Log
	Attrs Attrs
}

CtxVar defines the context structure.

type ExecResult

type ExecResult struct {
	Error     error
	CostTime  time.Duration
	Headers   []string
	Rows      interface{} // [][]string or []YourStruct
	RowsCount int

	RowsAffected int64
	LastInsertID int64
	IsQuery      bool
}

ExecResult defines the result structure of sql execution.

func (ExecResult) StringRows

func (r ExecResult) StringRows() [][]string

StringRows return the string rows when using MapPreparer.

type GinRouter

type GinRouter struct {
	*gin.Engine

	// XXX is a shortcut for router.Handle("XXX", path, handle).
	POST, GET, DELETE, PATCH, PUT, OPTIONS, HEAD RouterFn
	// contains filtered or unexported fields
}

GinRouter defines adaptor routes implementation for IRoutes.

func NewGin

func NewGin(router *gin.Engine, store Store, muxOptions ...MuxOptionFn) *GinRouter

NewGin wraps a new GinRouter for the gin router.

func (*GinRouter) Any

func (r *GinRouter) Any(relativePath string, handler gin.HandlerFunc, options ...OptionFn) *GinRouter

Any registers a route that matches all the HTTP methods. GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.

func (*GinRouter) Group

func (r *GinRouter) Group(groupPath string, handlers ...gin.HandlerFunc) *GinRouterGroup

Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix. For example, all the routes that use a common middleware for authorization could be grouped.

func (*GinRouter) Handle

func (r *GinRouter) Handle(httpMethod, relativePath string, handler gin.HandlerFunc, options ...OptionFn) *GinRouter

Handle registers a new request handle and middleware with the given path and method. The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes. See the example code in GitHub.

For GET, POST, PUT, PATCH and DELETE requests the respective shortcut functions can be used.

This function is intended for bulk loading and to allow the usage of less frequently used, non-standardized or custom methods (e.g. for internal communication with a proxy).

func (*GinRouter) RegisterCtler

func (r *GinRouter) RegisterCtler(ctler interface{})

RegisterCtler registers a controller object which declares the router in the structure fields' tag.

func (*GinRouter) Run

func (r *GinRouter) Run(addr ...string) (err error)

Run attaches the router to a http.Server and starts listening and serving HTTP requests. It is a shortcut for http.ListenAndServe(addr, router) Note: this method will block the calling goroutine indefinitely unless an error happens.

func (*GinRouter) ServeHTTP

func (r *GinRouter) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP calls f(w, r).

type GinRouterGroup

type GinRouterGroup struct {
	*gin.RouterGroup
	GinRouter *GinRouter

	// XXX is a shortcut for router.Handle("XXX", path, handle).
	POST, GET, DELETE, PATCH, PUT, OPTIONS, HEAD GinRouterGroupFn
}

GinRouterGroup wraps the gin.RouterGroup.

type GinRouterGroupFn

type GinRouterGroupFn func(relativePath string, handler gin.HandlerFunc, options ...OptionFn) *GinRouterGroup

GinRouterGroupFn defines the prototype for function gin Handle group.

type HandlerFuncAware

type HandlerFuncAware interface {
	HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
}

HandlerFuncAware declares interface which holds the HandleFunc function.

type JSON

type JSON struct {
	Data interface{}
}

JSON contains the given interface object.

func (JSON) Render

func (r JSON) Render(w http.ResponseWriter) error

Render (JSON) writes rowsData with custom ContentType.

func (JSON) WriteContentType

func (r JSON) WriteContentType(w http.ResponseWriter)

WriteContentType (JSON) writes JSON ContentType.

type Log

type Log struct {
	ID  string
	Biz string

	// Method is GET etc.
	Method string
	URL    string
	IPAddr string

	RspHeader http.Header
	ReqBody   string

	// RspStatus, like 200, 404.
	RspStatus int
	// ReqHeader records the response header.
	ReqHeader http.Header
	// RespSize is number of bytes of the response sent.
	RespSize int64
	// RspBody is the response body(limit to 1000).
	RspBody string

	Created time.Time

	// Start records the start time of the request.
	Start time.Time
	// End records the end time of the request.
	End time.Time
	// Duration means how long did it take to.
	Duration time.Duration
	Attrs    Attrs

	Option     *Option
	PathParams httprouter.Params
	Request    *http.Request
}

Log describes info about HTTP request.

func ParseReq

func ParseReq(r *http.Request) *Log

ParseReq parses the Log from http.Request context.

type LogrusStore

type LogrusStore struct{}

LogrusStore stores the log as logurs info.

func NewLogrusStore

func NewLogrusStore() *LogrusStore

NewLogrusStore returns a new LogrusStore.

func (*LogrusStore) Store

func (s *LogrusStore) Store(log *Log)

Store stores the log in database like MySQL, InfluxDB, and etc.

type MapMapping

type MapMapping struct {
	// contains filtered or unexported fields
}

MapMapping maps the query rows to maps.

func (*MapMapping) RowsData

func (m *MapMapping) RowsData() interface{}

RowsData returns the mapped rows data.

func (*MapMapping) Scan

func (m *MapMapping) Scan(rowNum int) error

Scan scans the rows one by one.

type MapPreparer

type MapPreparer struct {
	// NullReplace is the replacement of null values.
	NullReplace string
}

MapPreparer prepares to scan query rows.

func NewMapPreparer

func NewMapPreparer(nullReplace string) *MapPreparer

NewMapPreparer creates a new MapPreparer.

func (*MapPreparer) Prepare

func (m *MapPreparer) Prepare(rows *sql.Rows, columns []string) Mapping

Prepare prepares to scan query rows.

type Mapping

type Mapping interface {
	Scan(rowNum int) error
	RowsData() interface{}
}

Mapping defines the interface for SQL query processing.

type Metrics

type Metrics struct {
	// Code is the first http response code passed to the WriteHeader func of
	// the ResponseWriter. If no such call is made, a default code of 200 is
	// assumed instead.
	Code  int
	Start time.Time
	End   time.Time
	// Duration is the time it took to execute the handler.
	Duration time.Duration
	// Written is the number of bytes successfully written by the Write or
	// ReadFrom function of the ResponseWriter. ResponseWriters may also write
	// rowsData to their underlying connection directly (e.g. headers), but those
	// are not tracked. Therefore the number of Written bytes will usually match
	// the size of the response body.
	Written  int64
	RespBody string
	Header   http.Header
}

Metrics holds metrics captured from CaptureMetrics.

func CaptureMetrics

func CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Metrics

CaptureMetrics wraps the given hnd, executes it with the given w and r, and returns the metrics it captured from it.

func CaptureMetricsFn

func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics

CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the resulting metrics. This is very similar to CaptureMetrics (which is just sugar on top of this func), but is a more usable interface if your application doesn't use the Go http.Handler interface.

type MiniDB

type MiniDB interface {
	// Exec executes update.
	Exec(query string, args ...interface{}) (sql.Result, error)
	// Query performs query.
	Query(query string, args ...interface{}) (*sql.Rows, error)
}

MiniDB wraps Exec method.

type Mux

type Mux struct {
	// contains filtered or unexported fields
}

Mux defines the wrapper of http.ServeMux.

func NewMux

func NewMux(handler http.Handler, store Store, muxOptions ...MuxOptionFn) *Mux

NewMux returns a new instance of Mux.

func (*Mux) HandleFunc

func (mux *Mux) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request), options ...OptionFn)

HandleFunc registers the handler function for the given pattern.

func (*Mux) ParseOption

func (mux *Mux) ParseOption(r *http.Request) *OptionHolder

func (*Mux) ServeHTTP

func (mux *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP calls f(w, r).

type MuxOption

type MuxOption struct {
	IgnoreBizNoname bool
}

MuxOption defines the option of mux.

type MuxOptionFn

type MuxOptionFn func(m *MuxOption)

MuxOptionFn defines the function prototype to seting MuxOption.

func IgnoreBizNoname

func IgnoreBizNoname(ignore bool) MuxOptionFn

IgnoreBizNoname set the ignoreBizNoname option.

type NullAny

type NullAny struct {
	Type reflect.Type
	Val  reflect.Value
}

NullAny represents any that may be null. it implements the Scanner interface so it can be used as a scan destination.

func (*NullAny) Scan

func (n *NullAny) Scan(value interface{}) error

Scan assigns a value from a database driver.

The src value will be of one of the following types:

int64
float64
bool
[]byte
string
time.Time
nil - for NULL values

An error should be returned if the value cannot be stored without loss of information.

Reference types such as []byte are only valid until the next call to Scan and should not be retained. Their underlying memory is owned by the driver. If retention is necessary, copy their values before the next call to Scan.

type Option

type Option struct {
	Biz    string
	Tables []string
	Ignore bool
}

Option defines the option for the handler in the httplog.

func (Option) GetBiz

func (o Option) GetBiz() string

GetBiz returns the name from the option.

type OptionFn

type OptionFn func(option *Option)

OptionFn defines the option function prototype.

func Biz

func Biz(name string) OptionFn

Biz defines the descriptive name of the handler.

func Ignore

func Ignore(ignore bool) OptionFn

Ignore tells the current handler should to be ignored for httplog.

func Tables

func Tables(names ...string) OptionFn

Tables defines the tables to saving log.

type OptionFns

type OptionFns []OptionFn

OptionFns defines the slice of OptionFns.

func (OptionFns) CreateOption

func (fns OptionFns) CreateOption() *Option

CreateOption returns the option after functions call.

type OptionHolder

type OptionHolder struct {
	// contains filtered or unexported fields
}

OptionHolder defines the holder for option and params.

func (OptionHolder) Header

func (ho OptionHolder) Header() http.Header

Header returns the header map that will be sent by WriteHeader.

func (OptionHolder) Write

func (ho OptionHolder) Write([]byte) (int, error)

Write writes the data to the connection as part of an HTTP reply.

func (OptionHolder) WriteHeader

func (ho OptionHolder) WriteHeader(int)

WriteHeader sends an HTTP response header with the provided status code.

type Preparer

type Preparer interface {
	// Prepare prepares to scan query rows.
	Prepare(rows *sql.Rows, columns []string) Mapping
}

Preparer prepares to scan query rows.

type RequestVars

type RequestVars struct {
	Body        io.Reader
	ContentType string
}

RequestVars defines the structure of request vars tha can be set.

type RequestVarsFn

type RequestVarsFn func(r *RequestVars)

RequestVarsFn defines the prototype of RequestVars option setting function.

func JSONVar

func JSONVar(obj interface{}) RequestVarsFn

JSONVar creates a new JSON RequestVarsFn.

type RequestVarsFns

type RequestVarsFns []RequestVarsFn

RequestVarsFns is the slice of RequestVarsFn.

func (RequestVarsFns) Create

func (fns RequestVarsFns) Create() *RequestVars

Create creates new RequestVars.

type RouterFn

type RouterFn func(relativePath string, handler gin.HandlerFunc, options ...OptionFn) *GinRouter

RouterFn defines the prototype for function gin Handle.

type SQLExec

type SQLExec struct {
	MiniDB
}

SQLExec is used to execute only updates.

func NewSQLExec

func NewSQLExec(db MiniDB) *SQLExec

NewSQLExec creates a new SQLExec for only updates.

func (*SQLExec) DoUpdate

func (s *SQLExec) DoUpdate(query string, vars ...interface{}) (result ExecResult)

DoUpdate does the update.

type SQLRun

type SQLRun struct {
	*SQLExec
	Preparer // required only for query

	MaxRows int
}

SQLRun is used to execute queries and updates.

func NewSQLRun

func NewSQLRun(db MiniDB, preparer Preparer) *SQLRun

NewSQLRun creates a new SQLRun for queries and updates.

func (*SQLRun) DoExec

func (s *SQLRun) DoExec(query string, args ...interface{}) ExecResult

DoExec executes a SQL.

func (*SQLRun) DoQuery

func (s *SQLRun) DoQuery(query string, args ...interface{}) (result ExecResult)

DoQuery does the query.

type SQLStore

type SQLStore struct {
	DB         *sql.DB
	DriverName string
	LogTables  []string

	TableCols map[string]*tableSchema
}

SQLStore stores the log into database.

func NewSQLStore

func NewSQLStore(db *sql.DB, defaultLogTables ...string) *SQLStore

NewSQLStore creates a new SQLStore.

func (*SQLStore) Store

func (s *SQLStore) Store(l *Log)

Store stores the log in database like MySQL, InfluxDB, and etc.

type Store

type Store interface {
	// Store stores the log in database like MySQL, InfluxDB, and etc.
	Store(log *Log)
}

Store defines the interface to Store a log.

type Stores

type Stores struct {
	Composite []Store
}

Stores is the composite stores.

func NewStores

func NewStores(stores ...Store) *Stores

NewStores composes the stores as a Store.

func (*Stores) Store

func (s *Stores) Store(log *Log)

Store stores the log in database like MySQL, InfluxDB, and etc.

type StructMapping

type StructMapping struct {
	*StructPreparer
	// contains filtered or unexported fields
}

StructMapping is the structure for mapping row to a structure.

func (*StructMapping) RowsData

func (s *StructMapping) RowsData() interface{}

RowsData returns the mapped rows data.

func (*StructMapping) Scan

func (s *StructMapping) Scan(rowNum int) error

Scan scans the query result to fetch the rows one by one.

type StructPreparer

type StructPreparer struct {
	StructType reflect.Type
}

StructPreparer is the the structure to create struct mapping.

func NewStructPreparer

func NewStructPreparer(v interface{}) *StructPreparer

NewStructPreparer creates a new StructPreparer.

func (*StructPreparer) Prepare

func (m *StructPreparer) Prepare(rows *sql.Rows, columns []string) Mapping

Prepare prepares to scan query rows.

type TableCol

type TableCol struct {
	Name      string `name:"column_name"`
	Comment   string `name:"column_comment"`
	DataType  string `name:"data_type"`
	MaxLength int    `name:"max_length"`

	ValueGetter col `name:"-"`
}

TableCol defines the schema of a table.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL