mirror of
https://github.com/yusing/godoxy.git
synced 2026-03-17 23:14:21 +01:00
Modified JSON tags in the Notify struct of ACL config and the ConfigBase and Retention structs in access log config to include 'omitempty'
140 lines
3.4 KiB
Go
140 lines
3.4 KiB
Go
package accesslog
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/yusing/godoxy/internal/serialization"
|
|
gperr "github.com/yusing/goutils/errs"
|
|
)
|
|
|
|
type (
|
|
ConfigBase struct {
|
|
Path string `json:"path,omitempty"`
|
|
Stdout bool `json:"stdout"`
|
|
Retention *Retention `json:"retention" aliases:"keep"`
|
|
RotateInterval time.Duration `json:"rotate_interval,omitempty" swaggertype:"primitive,integer"`
|
|
} // @name AccessLoggerConfigBase
|
|
ACLLoggerConfig struct {
|
|
ConfigBase
|
|
LogAllowed bool `json:"log_allowed"`
|
|
} // @name ACLLoggerConfig
|
|
RequestLoggerConfig struct {
|
|
ConfigBase
|
|
Format Format `json:"format" validate:"oneof=common combined json"`
|
|
Filters Filters `json:"filters"`
|
|
Fields Fields `json:"fields"`
|
|
} // @name RequestLoggerConfig
|
|
Config struct {
|
|
ConfigBase
|
|
acl *ACLLoggerConfig
|
|
req *RequestLoggerConfig
|
|
}
|
|
AnyConfig interface {
|
|
ToConfig() *Config
|
|
Writers() ([]File, error)
|
|
}
|
|
|
|
Format string
|
|
Filters struct {
|
|
StatusCodes LogFilter[*StatusCodeRange] `json:"status_codes,omitzero"`
|
|
Method LogFilter[HTTPMethod] `json:"method,omitzero"`
|
|
Host LogFilter[Host] `json:"host,omitzero"`
|
|
Headers LogFilter[*HTTPHeader] `json:"headers,omitzero"` // header exists or header == value
|
|
CIDR LogFilter[*CIDR] `json:"cidr,omitzero"`
|
|
}
|
|
Fields struct {
|
|
Headers FieldConfig `json:"headers,omitzero" aliases:"header"`
|
|
Query FieldConfig `json:"query,omitzero" aliases:"queries"`
|
|
Cookies FieldConfig `json:"cookies,omitzero" aliases:"cookie"`
|
|
}
|
|
)
|
|
|
|
var (
|
|
FormatCommon Format = "common"
|
|
FormatCombined Format = "combined"
|
|
FormatJSON Format = "json"
|
|
|
|
ReqLoggerFormats = []Format{FormatCommon, FormatCombined, FormatJSON}
|
|
)
|
|
|
|
func (cfg *ConfigBase) Validate() gperr.Error {
|
|
if cfg.Path == "" && !cfg.Stdout {
|
|
return gperr.New("path or stdout is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Writers returns a list of writers for the config.
|
|
func (cfg *ConfigBase) Writers() ([]File, error) {
|
|
writers := make([]File, 0, 2)
|
|
if cfg.Path != "" {
|
|
f, err := OpenFile(cfg.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
writers = append(writers, f)
|
|
}
|
|
if cfg.Stdout {
|
|
writers = append(writers, stdout)
|
|
}
|
|
return writers, nil
|
|
}
|
|
|
|
func (cfg *ACLLoggerConfig) ToConfig() *Config {
|
|
return &Config{
|
|
ConfigBase: cfg.ConfigBase,
|
|
acl: cfg,
|
|
}
|
|
}
|
|
|
|
func (cfg *RequestLoggerConfig) ToConfig() *Config {
|
|
return &Config{
|
|
ConfigBase: cfg.ConfigBase,
|
|
req: cfg,
|
|
}
|
|
}
|
|
|
|
func (cfg *Config) ShouldLogRequest(req *http.Request, res *http.Response) bool {
|
|
if cfg.req == nil {
|
|
return true
|
|
}
|
|
return cfg.req.Filters.StatusCodes.CheckKeep(req, res) &&
|
|
cfg.req.Filters.Method.CheckKeep(req, res) &&
|
|
cfg.req.Filters.Headers.CheckKeep(req, res) &&
|
|
cfg.req.Filters.CIDR.CheckKeep(req, res)
|
|
}
|
|
|
|
func DefaultRequestLoggerConfig() *RequestLoggerConfig {
|
|
return &RequestLoggerConfig{
|
|
ConfigBase: ConfigBase{
|
|
Retention: &Retention{Days: 30},
|
|
},
|
|
Format: FormatCombined,
|
|
Fields: Fields{
|
|
Headers: FieldConfig{
|
|
Default: FieldModeDrop,
|
|
},
|
|
Query: FieldConfig{
|
|
Default: FieldModeKeep,
|
|
},
|
|
Cookies: FieldConfig{
|
|
Default: FieldModeDrop,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func DefaultACLLoggerConfig() *ACLLoggerConfig {
|
|
return &ACLLoggerConfig{
|
|
ConfigBase: ConfigBase{
|
|
Retention: &Retention{Days: 30},
|
|
},
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
serialization.RegisterDefaultValueFactory(DefaultRequestLoggerConfig)
|
|
serialization.RegisterDefaultValueFactory(DefaultACLLoggerConfig)
|
|
}
|