diff --git a/prog/app.go b/prog/app.go index 0e66b8f196..dfa108d84f 100644 --- a/prog/app.go +++ b/prog/app.go @@ -270,7 +270,10 @@ func appMain(flags appFlags) { handler := router(collector, controlRouter, pipeRouter, flags.externalUI) if flags.logHTTP { - handler = middleware.LogFailed.Wrap(handler) + handler = middleware.Log{ + LogRequestHeaders: flags.logHTTPHeaders, + LogSuccess: false, + }.Wrap(handler) } server := &graceful.Server{ diff --git a/prog/main.go b/prog/main.go index 0a679970c6..ac1ca13a79 100644 --- a/prog/main.go +++ b/prog/main.go @@ -112,12 +112,13 @@ type probeFlags struct { } type appFlags struct { - window time.Duration - listen string - stopTimeout time.Duration - logLevel string - logPrefix string - logHTTP bool + window time.Duration + listen string + stopTimeout time.Duration + logLevel string + logPrefix string + logHTTP bool + logHTTPHeaders bool weaveEnabled bool weaveAddr string @@ -298,6 +299,7 @@ func main() { flag.StringVar(&flags.app.logLevel, "app.log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic") flag.StringVar(&flags.app.logPrefix, "app.log.prefix", "", "prefix for each log line") flag.BoolVar(&flags.app.logHTTP, "app.log.http", false, "Log individual HTTP requests") + flag.BoolVar(&flags.app.logHTTPHeaders, "app.log.httpHeaders", false, "Log HTTP headers. Needs app.log.http to be enabled.") flag.StringVar(&flags.app.weaveAddr, "app.weave.addr", app.DefaultWeaveURL, "Address on which to contact WeaveDNS") flag.StringVar(&flags.app.weaveHostname, "app.weave.hostname", app.DefaultHostname, "Hostname to advertise in WeaveDNS") diff --git a/vendor/github.com/weaveworks/common/logging/event.go b/vendor/github.com/weaveworks/common/logging/event.go deleted file mode 100644 index ddffc73e25..0000000000 --- a/vendor/github.com/weaveworks/common/logging/event.go +++ /dev/null @@ -1,135 +0,0 @@ -package logging - -import ( - "fmt" - "net" - "net/http" - "strconv" - - log "github.com/Sirupsen/logrus" - "github.com/fluent/fluent-logger-golang/fluent" -) - -const maxBufferedEvents = 100 - -// Event is a user event to be sent to out analytics system -type Event struct { - ID string `msg:"event"` - SessionID string `msg:"session_id"` - Product string `msg:"product"` - Version string `msg:"version"` - UserAgent string `msg:"user_agent"` - ClientID string `msg:"client_id"` - OrganizationID string `msg:"org_id"` - UserID string `msg:"user_id"` - Values string `msg:"values"` -} - -// EventLogger logs events to the analytics system -type EventLogger struct { - stop chan struct{} - events chan Event - logger *fluent.Fluent -} - -// NewEventLogger creates a new EventLogger. -func NewEventLogger(fluentHostPort string) (*EventLogger, error) { - host, port, err := net.SplitHostPort(fluentHostPort) - if err != nil { - return nil, err - } - intPort, err := strconv.Atoi(port) - if err != nil { - return nil, err - } - logger, err := fluent.New(fluent.Config{ - FluentPort: intPort, - FluentHost: host, - AsyncConnect: true, - MaxRetry: -1, - }) - if err != nil { - return nil, err - } - - el := &EventLogger{ - stop: make(chan struct{}), - events: make(chan Event, maxBufferedEvents), - logger: logger, - } - go el.logLoop() - return el, nil -} - -func (el *EventLogger) post(e Event) { - if err := el.logger.Post("events", e); err != nil { - log.Warnf("EventLogger: failed to log event: %v", e) - } -} - -func (el *EventLogger) logLoop() { - for done := false; !done; { - select { - case event := <-el.events: - el.post(event) - case <-el.stop: - done = true - } - } - - // flush remaining events - for done := false; !done; { - select { - case event := <-el.events: - el.post(event) - default: - done = true - } - } - - el.logger.Close() -} - -// Close closes and deallocates the event logger -func (el *EventLogger) Close() error { - close(el.stop) - return nil -} - -// LogEvent logs an event to the analytics system -func (el *EventLogger) LogEvent(e Event) error { - select { - case <-el.stop: - return fmt.Errorf("Stopping, discarding event: %v", e) - default: - } - - select { - case el.events <- e: // Put event in the channel unless it is full - return nil - default: - // full - } - return fmt.Errorf("Reached event buffer limit (%d), discarding event: %v", maxBufferedEvents, e) -} - -// HTTPEventExtractor extracts an event from an http requests indicating whether it should be loggged -type HTTPEventExtractor func(*http.Request) (Event, bool) - -// HTTPEventLogger logs an events extracted from an http request -type HTTPEventLogger struct { - Extractor HTTPEventExtractor - Logger *EventLogger -} - -// Wrap implements middleware.Wrap() -func (el HTTPEventLogger) Wrap(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if event, shouldLog := el.Extractor(r); shouldLog { - if err := el.Logger.LogEvent(event); err != nil { - log.Warnf("HTTPEventLogger: failed to log event: %v", err) - } - } - next.ServeHTTP(w, r) - }) -} diff --git a/vendor/github.com/weaveworks/common/middleware/logging.go b/vendor/github.com/weaveworks/common/middleware/logging.go index e05a80ce14..19d29cd84a 100644 --- a/vendor/github.com/weaveworks/common/middleware/logging.go +++ b/vendor/github.com/weaveworks/common/middleware/logging.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "net/http" + "net/http/httputil" "time" log "github.com/Sirupsen/logrus" @@ -12,7 +13,8 @@ import ( // Log middleware logs http requests type Log struct { - LogSuccess bool // LogSuccess true -> log successful queries; false -> only log failed queries + LogSuccess bool // LogSuccess true -> log successful queries; false -> only log failed queries + LogRequestHeaders bool // LogRequestHeaders true -> dump http headers at debug log level } // Wrap implements Middleware @@ -20,6 +22,15 @@ func (l Log) Wrap(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { begin := time.Now() uri := r.RequestURI // capture the URI before running next, as it may get rewritten + if l.LogRequestHeaders { + // Log headers before running 'next' in case other interceptors change the data. + headers, err := httputil.DumpRequest(r, false) + if err != nil { + log.Warnf("Could not dump request headers: %v", err) + return + } + log.Debugf("Is websocket request: %v\n%s", IsWSHandshakeRequest(r), string(headers)) + } i := &interceptor{ResponseWriter: w, statusCode: http.StatusOK} next.ServeHTTP(i, r) if l.LogSuccess || !(100 <= i.statusCode && i.statusCode < 400) { @@ -31,7 +42,8 @@ func (l Log) Wrap(next http.Handler) http.Handler { // Logging middleware logs each HTTP request method, path, response code and // duration for all HTTP requests. var Logging = Log{ - LogSuccess: true, + LogSuccess: true, + LogRequestHeaders: false, } // LogFailed middleware logs each HTTP request method, path, response code and diff --git a/vendor/github.com/weaveworks/common/middleware/redirect.go b/vendor/github.com/weaveworks/common/middleware/redirect.go new file mode 100644 index 0000000000..34c1772817 --- /dev/null +++ b/vendor/github.com/weaveworks/common/middleware/redirect.go @@ -0,0 +1,48 @@ +package middleware + +import ( + "net/http" + "net/url" +) + +// Redirect middleware, will redirect requests to hosts which match any of the +// Matches to RedirectScheme://RedirectHost +type Redirect struct { + Matches []Match + + RedirectHost string + RedirectScheme string +} + +// Match specifies a match for a redirect. Host and/or Scheme can be empty +// signify match-all. +type Match struct { + Host, Scheme string +} + +func (m Match) match(u *url.URL) bool { + if m.Host != "" && m.Host != u.Host { + return false + } + + if m.Scheme != "" && m.Scheme != u.Scheme { + return false + } + + return true +} + +// Wrap implements Middleware +func (m Redirect) Wrap(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + for _, match := range m.Matches { + if match.match(r.URL) { + r.URL.Host = m.RedirectHost + r.URL.Scheme = m.RedirectScheme + http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently) + return + } + } + next.ServeHTTP(w, r) + }) +} diff --git a/vendor/manifest b/vendor/manifest index b3b8f980f7..7b3bf7510a 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -1361,7 +1361,7 @@ "importpath": "github.com/weaveworks/common", "repository": "https://github.com/weaveworks/common", "vcs": "git", - "revision": "cc20acf03ebf74be0facaae4259dff6cde01ce77", + "revision": "139d0313ac15170e9de8187b26e7df03b4cb910e", "branch": "master", "notests": true },