...

Source file src/github.com/sassoftware/relic/server/logging.go

Documentation: github.com/sassoftware/relic/server

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package server
    18  
    19  import (
    20  	"fmt"
    21  	"net/http"
    22  	"strings"
    23  	"time"
    24  )
    25  
    26  // Log a general message
    27  func (s *Server) Logf(format string, args ...interface{}) {
    28  	s.ErrorLog.Output(2, fmt.Sprintf(format, args...))
    29  }
    30  
    31  // Log a message associated with an ongoing request
    32  func (s *Server) Logr(request *http.Request, format string, args ...interface{}) {
    33  	msg := fmt.Sprintf(format, args...)
    34  	dn := GetClientDN(request)
    35  	if dn != "" {
    36  		dn = " `" + dn + "`"
    37  	}
    38  	msg2 := fmt.Sprintf("[%s \"%s\"%s] %s", GetClientIP(request), GetClientName(request), dn, msg)
    39  	s.ErrorLog.Output(2, msg2)
    40  }
    41  
    42  // Log an unhandled error with optional traceback
    43  func (s *Server) LogError(request *http.Request, err interface{}, traceback []byte) Response {
    44  	msg := ""
    45  	if len(traceback) != 0 {
    46  		msg = "\n " + strings.Replace(string(traceback), "\n", "\n ", -1)
    47  	}
    48  	s.Logr(request, "unhandled exception: %s%s\n", err, msg)
    49  	return ErrorResponse(http.StatusInternalServerError)
    50  }
    51  
    52  // Wraps a http.ResponseWriter and writes an access log entry on completion
    53  type loggingWriter struct {
    54  	http.ResponseWriter
    55  	s      *Server
    56  	r      *http.Request
    57  	st     time.Time
    58  	wrote  bool
    59  	length int64
    60  	status int
    61  }
    62  
    63  func (lw *loggingWriter) WriteHeader(status int) {
    64  	lw.wrote = true
    65  	lw.status = status
    66  	lw.ResponseWriter.WriteHeader(status)
    67  }
    68  
    69  func (lw *loggingWriter) Write(d []byte) (int, error) {
    70  	if !lw.wrote {
    71  		lw.WriteHeader(http.StatusOK)
    72  	}
    73  	n, err := lw.ResponseWriter.Write(d)
    74  	lw.length += int64(n)
    75  	return n, err
    76  }
    77  
    78  func (lw *loggingWriter) Close() {
    79  	path := lw.r.URL.Path
    80  	if path == "/health" {
    81  		// don't log health check spam
    82  		return
    83  	}
    84  	ua := lw.r.Header.Get("User-Agent")
    85  	if ua == "" {
    86  		ua = "-"
    87  	}
    88  	elapsed := time.Since(lw.st)
    89  	lw.s.Logr(lw.r, "%s \"%s\" %d %d %s %.03f", lw.r.Method, lw.r.URL, lw.status, lw.length, ua, elapsed.Seconds())
    90  }
    91  

View as plain text