-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 264e966
Showing
7 changed files
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
# from https://github.com/golangci/golangci-lint/blob/master/.golangci.yml | ||
linters-settings: | ||
depguard: | ||
list-type: blacklist | ||
packages: | ||
# logging is allowed only by logutils.Log, logrus | ||
# is allowed to use only in logutils package | ||
- github.com/sirupsen/logrus | ||
packages-with-error-message: | ||
- github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" | ||
dupl: | ||
threshold: 100 | ||
exhaustive: | ||
default-signifies-exhaustive: false | ||
funlen: | ||
lines: 100 | ||
statements: 50 | ||
gci: | ||
local-prefixes: github.com/golangci/golangci-lint | ||
goconst: | ||
min-len: 2 | ||
min-occurrences: 2 | ||
gocritic: | ||
enabled-tags: | ||
- diagnostic | ||
- experimental | ||
- opinionated | ||
- performance | ||
- style | ||
disabled-checks: | ||
- dupImport # https://github.com/go-critic/go-critic/issues/845 | ||
- ifElseChain | ||
- octalLiteral | ||
- whyNoLint | ||
- wrapperFunc | ||
gocyclo: | ||
min-complexity: 15 | ||
goimports: | ||
local-prefixes: github.com/golangci/golangci-lint | ||
golint: | ||
min-confidence: 0 | ||
gomnd: | ||
settings: | ||
mnd: | ||
# don't include the "operation" and "assign" | ||
checks: argument,case,condition,return | ||
govet: | ||
check-shadowing: true | ||
settings: | ||
printf: | ||
funcs: | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf | ||
lll: | ||
line-length: 140 | ||
maligned: | ||
suggest-new: true | ||
misspell: | ||
locale: US | ||
nolintlint: | ||
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) | ||
allow-unused: false # report any unused nolint directives | ||
require-explanation: false # don't require an explanation for nolint directives | ||
require-specific: false # don't require nolint directives to be specific about which linter is being skipped | ||
|
||
linters: | ||
# please, do not use `enable-all`: it's deprecated and will be removed soon. | ||
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint | ||
disable-all: true | ||
enable: | ||
- bodyclose | ||
- deadcode | ||
- depguard | ||
- dogsled | ||
- dupl | ||
- errcheck | ||
- exhaustive | ||
- funlen | ||
- gochecknoinits | ||
- goconst | ||
- gocritic | ||
- gocyclo | ||
- gofmt | ||
- goimports | ||
- golint | ||
- gomnd | ||
- goprintffuncname | ||
- gosec | ||
- gosimple | ||
- govet | ||
- ineffassign | ||
- interfacer | ||
- lll | ||
- misspell | ||
- nakedret | ||
- noctx | ||
- nolintlint | ||
- rowserrcheck | ||
- scopelint | ||
- staticcheck | ||
- structcheck | ||
- stylecheck | ||
- typecheck | ||
- unconvert | ||
- unparam | ||
- unused | ||
- varcheck | ||
- whitespace | ||
|
||
# don't enable: | ||
# - asciicheck | ||
# - gochecknoglobals | ||
# - gocognit | ||
# - godot | ||
# - godox | ||
# - goerr113 | ||
# - maligned | ||
# - nestif | ||
# - prealloc | ||
# - testpackage | ||
# - wsl | ||
|
||
issues: | ||
# Excluding configuration per-path, per-linter, per-text and per-source | ||
exclude-rules: | ||
- path: _test\.go | ||
linters: | ||
- gomnd | ||
|
||
# https://github.com/go-critic/go-critic/issues/926 | ||
- linters: | ||
- gocritic | ||
text: "unnecessaryDefer:" | ||
|
||
run: | ||
skip-dirs: | ||
- vendor | ||
- hack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
displayName: Request Logger | ||
summary: Send request info to stdout. | ||
type: middleware | ||
import: github.com/joy2fun/traefik-plugin-log-request | ||
testData: | ||
responseBody: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Traefik plugin to log requests | ||
|
||
file provider example: | ||
|
||
```yml | ||
http: | ||
middlewares: | ||
my-plugin: | ||
plugin: | ||
log-request: | ||
responseBody: true # also including response body | ||
``` | ||
crd example: | ||
```yml | ||
apiVersion: traefik.containo.us/v1alpha1 | ||
kind: Middleware | ||
metadata: | ||
name: log-request | ||
spec: | ||
plugin: | ||
log-request: | ||
responseBody: true | ||
``` | ||
helm chart values example: | ||
```yaml | ||
additionalArguments: | ||
- >- | ||
--experimental.localplugins.log-request.modulename=github.com/joy2fun/traefik-plugin-log-request | ||
additionalVolumeMounts: | ||
- mountPath: /plugins-local | ||
name: plugins | ||
deployment: | ||
additionalVolumes: | ||
- hostPath: | ||
path: /data/plugins-local | ||
name: plugins | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/joy2fun/traefik-plugin-log-request | ||
|
||
go 1.14 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package traefik_plugin_log_request | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net" | ||
"net/http" | ||
"os" | ||
) | ||
|
||
// Config holds the plugin configuration. | ||
type Config struct { | ||
ResponseBody bool `json:"responseBody,omitempty"` | ||
} | ||
|
||
// CreateConfig creates and initializes the plugin configuration. | ||
func CreateConfig() *Config { | ||
return &Config{} | ||
} | ||
|
||
type logRequest struct { | ||
name string | ||
next http.Handler | ||
responseBody bool | ||
} | ||
|
||
type RequestData struct { | ||
URL string `json:"url"` | ||
Host string `json:"host"` | ||
Body string `json:"body"` | ||
Headers string `json:"headers"` | ||
ResponseBody string `json:"response_body"` | ||
} | ||
|
||
func New(_ context.Context, next http.Handler, config *Config, name string) (http.Handler, error) { | ||
return &logRequest{ | ||
name: name, | ||
next: next, | ||
responseBody: config.ResponseBody, | ||
}, nil | ||
} | ||
|
||
func (p *logRequest) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | ||
body, err := io.ReadAll(req.Body) | ||
if err != nil { | ||
} | ||
|
||
req.Body = io.NopCloser(bytes.NewBuffer(body)) | ||
|
||
wrappedWriter := &responseWriter{ | ||
ResponseWriter: rw, | ||
} | ||
|
||
p.next.ServeHTTP(wrappedWriter, req) | ||
|
||
bodyBytes := wrappedWriter.buffer.Bytes() | ||
rw.Write(bodyBytes) | ||
|
||
headers := make(map[string]string) | ||
for name, values := range req.Header { | ||
headers[name] = values[0] // Take the first value of the header | ||
} | ||
|
||
jsonHeader, err := json.Marshal(headers) | ||
if err != nil { | ||
} | ||
|
||
requestData := RequestData{ | ||
URL: req.URL.String(), | ||
Host: req.Host, | ||
Body: string(body), | ||
Headers: string(jsonHeader), | ||
} | ||
|
||
if p.responseBody { | ||
responseBody := io.NopCloser(bytes.NewBuffer(bodyBytes)) | ||
responseBodyBytes, err := io.ReadAll(responseBody) | ||
if err != nil { | ||
} | ||
|
||
requestData.ResponseBody = string(responseBodyBytes) | ||
} | ||
|
||
jsonData, err := json.Marshal(requestData) | ||
if err != nil { | ||
} | ||
|
||
os.Stdout.WriteString(string(jsonData) + "\n") | ||
} | ||
|
||
type responseWriter struct { | ||
buffer bytes.Buffer | ||
|
||
http.ResponseWriter | ||
} | ||
|
||
func (r *responseWriter) Write(p []byte) (int, error) { | ||
return r.buffer.Write(p) | ||
} | ||
|
||
func (r *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { | ||
hijacker, ok := r.ResponseWriter.(http.Hijacker) | ||
if !ok { | ||
return nil, nil, fmt.Errorf("%T is not a http.Hijacker", r.ResponseWriter) | ||
} | ||
|
||
return hijacker.Hijack() | ||
} | ||
|
||
func (r *responseWriter) Flush() { | ||
if flusher, ok := r.ResponseWriter.(http.Flusher); ok { | ||
flusher.Flush() | ||
} | ||
} |