<commit_before>package middleware

import (
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/newrelic/go-agent"
	"github.com/oinume/lekcije/server/config"
	"github.com/oinume/lekcije/server/controller"
	"github.com/oinume/lekcije/server/controller/flash_message"
	"github.com/oinume/lekcije/server/errors"
	"github.com/oinume/lekcije/server/logger"
	"github.com/oinume/lekcije/server/model"
	"github.com/rs/cors"
	"github.com/uber-go/zap"
)

var _ = fmt.Print

const maxDBConnections = 5

func PanicHandler(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if r := recover(); r != nil {
				var err error
				switch errorType := r.(type) {
				case string:
					err = fmt.Errorf(errorType)
				case error:
					err = errorType
				default:
					err = fmt.Errorf("Unknown error type: %v", errorType)
				}
				controller.InternalServerError(w, errors.InternalWrapf(err, "panic ocurred"))
				return
			}
		}()
		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

func AccessLogger(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		writerProxy := controller.WrapWriter(w)
		h.ServeHTTP(writerProxy, r)
		func() {
			end := time.Now()
			status := writerProxy.Status()
			if status == 0 {
				status = http.StatusOK
			}
			remoteAddr := r.RemoteAddr
			if remoteAddr != "" {
				remoteAddr = (strings.Split(remoteAddr, ":"))[0]
			}

			// 172.16.58.3 - - [31/Jul/2016:13:18:07 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
			logger.AccessLogger.Info(
				"",
				zap.String("date", start.Format(time.RFC3339)),
				zap.String("method", r.Method),
				zap.String("url", r.URL.String()),
				zap.Int("status", status),
				zap.Int("bytes", writerProxy.BytesWritten()),
				zap.String("remoteAddr", remoteAddr),
				zap.String("userAgent", r.Header.Get("User-Agent")),
				zap.String("referer", r.Referer()),
				zap.Duration("elapsed", end.Sub(start)/time.Millisecond),
			)
		}()
	}
	return http.HandlerFunc(fn)
}

func NewRelic(h http.Handler) http.Handler {
	key := os.Getenv("NEW_RELIC_LICENSE_KEY")
	if key == "" {
		return h
	}

	c := newrelic.NewConfig("lekcije", key)
	app, err := newrelic.NewApplication(c)
	if err != nil {
		logger.AppLogger.Error("Failed to newrelic.NewApplication()", zap.Error(err))
		return h
	}
	fn := func(w http.ResponseWriter, r *http.Request) {
		tx := app.StartTransaction(r.URL.Path, w, r)
		defer tx.End()
		h.ServeHTTP(tx, r)
	}
	return http.HandlerFunc(fn)
}

func SetDBAndRedisToContext(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		if r.RequestURI == "/api/status" {
			h.ServeHTTP(w, r)
			return
		}
		fmt.Printf("%s %s\n", r.Method, r.RequestURI)

		db, c, err := model.OpenDBAndSetToContext(
			ctx, os.Getenv("DB_URL"), maxDBConnections, !config.IsProductionEnv(),
		)
		if err != nil {
			controller.InternalServerError(w, err)
			return
		}
		defer db.Close()
<commit_msg>Print access log only when local environment<commit_after>package middleware

import (
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/newrelic/go-agent"
	"github.com/oinume/lekcije/server/config"
	"github.com/oinume/lekcije/server/controller"
	"github.com/oinume/lekcije/server/controller/flash_message"
	"github.com/oinume/lekcije/server/errors"
	"github.com/oinume/lekcije/server/logger"
	"github.com/oinume/lekcije/server/model"
	"github.com/rs/cors"
	"github.com/uber-go/zap"
)

var _ = fmt.Print

const maxDBConnections = 5

func PanicHandler(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if r := recover(); r != nil {
				var err error
				switch errorType := r.(type) {
				case string:
					err = fmt.Errorf(errorType)
				case error:
					err = errorType
				default:
					err = fmt.Errorf("Unknown error type: %v", errorType)
				}
				controller.InternalServerError(w, errors.InternalWrapf(err, "panic ocurred"))
				return
			}
		}()
		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

func AccessLogger(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		writerProxy := controller.WrapWriter(w)
		h.ServeHTTP(writerProxy, r)
		func() {
			end := time.Now()
			status := writerProxy.Status()
			if status == 0 {
				status = http.StatusOK
			}
			remoteAddr := r.RemoteAddr
			if remoteAddr != "" {
				remoteAddr = (strings.Split(remoteAddr, ":"))[0]
			}

			// 172.16.58.3 - - [31/Jul/2016:13:18:07 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
			logger.AccessLogger.Info(
				"",
				zap.String("date", start.Format(time.RFC3339)),
				zap.String("method", r.Method),
				zap.String("url", r.URL.String()),
				zap.Int("status", status),
				zap.Int("bytes", writerProxy.BytesWritten()),
				zap.String("remoteAddr", remoteAddr),
				zap.String("userAgent", r.Header.Get("User-Agent")),
				zap.String("referer", r.Referer()),
				zap.Duration("elapsed", end.Sub(start)/time.Millisecond),
			)
		}()
	}
	return http.HandlerFunc(fn)
}

func NewRelic(h http.Handler) http.Handler {
	key := os.Getenv("NEW_RELIC_LICENSE_KEY")
	if key == "" {
		return h
	}

	c := newrelic.NewConfig("lekcije", key)
	app, err := newrelic.NewApplication(c)
	if err != nil {
		logger.AppLogger.Error("Failed to newrelic.NewApplication()", zap.Error(err))
		return h
	}
	fn := func(w http.ResponseWriter, r *http.Request) {
		tx := app.StartTransaction(r.URL.Path, w, r)
		defer tx.End()
		h.ServeHTTP(tx, r)
	}
	return http.HandlerFunc(fn)
}

func SetDBAndRedisToContext(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		if r.RequestURI == "/api/status" {
			h.ServeHTTP(w, r)
			return
		}
		if config.IsLocalEnv() {
			fmt.Printf("%s %s\n", r.Method, r.RequestURI)
		}

		db, c, err := model.OpenDBAndSetToContext(
			ctx, os.Getenv("DB_URL"), maxDBConnections, !config.IsProductionEnv(),
		)
		if err != nil {
			controller.InternalServerError(w, err)
			return
		}
		defer db.Close()

{'fraction_non_alphanumeric': 0.1677636859849093, 'fraction_numerical': 0.013806389468614545, 'mean_word_length': 3.577516531961793, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6529324', 'n_tokens_mistral': 2697, 'n_tokens_neox': 2361, 'n_words': 426}