pomerium/internal/log/access.go

91 lines
2.9 KiB
Go

package log
import (
"errors"
"fmt"
"strings"
)
// An AccessLogField is a field in the access logs.
type AccessLogField string
// known access log fields
const (
AccessLogFieldAuthority AccessLogField = "authority"
AccessLogFieldDuration AccessLogField = "duration"
AccessLogFieldForwardedFor AccessLogField = "forwarded-for"
AccessLogFieldMethod AccessLogField = "method"
AccessLogFieldPath AccessLogField = "path"
AccessLogFieldReferer AccessLogField = "referer"
AccessLogFieldRequestID AccessLogField = "request-id"
AccessLogFieldResponseCode AccessLogField = "response-code"
AccessLogFieldResponseCodeDetails AccessLogField = "response-code-details"
AccessLogFieldSize AccessLogField = "size"
AccessLogFieldUpstreamCluster AccessLogField = "upstream-cluster"
AccessLogFieldUserAgent AccessLogField = "user-agent"
)
// DefaultAccessLogFields returns the default access log fields.
func DefaultAccessLogFields() []AccessLogField {
return []AccessLogField{
AccessLogFieldUpstreamCluster,
AccessLogFieldMethod,
AccessLogFieldAuthority,
AccessLogFieldPath,
AccessLogFieldUserAgent,
AccessLogFieldReferer,
AccessLogFieldForwardedFor,
AccessLogFieldRequestID,
AccessLogFieldDuration,
AccessLogFieldSize,
AccessLogFieldResponseCode,
AccessLogFieldResponseCodeDetails,
}
}
const accessLogFieldHeaderPrefix = "header."
// AccessLogFieldForHeader returns an access log field for the given header name.
func AccessLogFieldForHeader(header string) AccessLogField {
return AccessLogField(accessLogFieldHeaderPrefix + header)
}
// IsForHeader returns true if the access log field is for a header.
func (field AccessLogField) IsForHeader() (headerName string, ok bool) {
if strings.HasPrefix(string(field), accessLogFieldHeaderPrefix) {
return string(field[len(accessLogFieldHeaderPrefix):]), true
}
return "", false
}
// ErrUnknownAccessLogField indicates that an access log field is unknown.
var ErrUnknownAccessLogField = errors.New("unknown access log field")
var accessLogFieldLookup = map[AccessLogField]struct{}{
AccessLogFieldAuthority: {},
AccessLogFieldDuration: {},
AccessLogFieldForwardedFor: {},
AccessLogFieldMethod: {},
AccessLogFieldPath: {},
AccessLogFieldReferer: {},
AccessLogFieldRequestID: {},
AccessLogFieldResponseCode: {},
AccessLogFieldResponseCodeDetails: {},
AccessLogFieldSize: {},
AccessLogFieldUpstreamCluster: {},
AccessLogFieldUserAgent: {},
}
// Validate returns an error if the access log field is invalid.
func (field AccessLogField) Validate() error {
if _, ok := field.IsForHeader(); ok {
return nil
}
_, ok := accessLogFieldLookup[field]
if !ok {
return fmt.Errorf("%w: %s", ErrUnknownAccessLogField, field)
}
return nil
}