<commit_before>package filters

import "github.com/chakrit/go-bunyan"
import z "github.com/zaiuz/zaiuz"

const LogFilterPrefix = "z.log"

type logFilterData struct {
	logger bunyan.Log
}

func LogFilter(name string, parent bunyan.Log) z.Filter {
	if parent == nil {
		parent = bunyan.NewStdLogger(name, bunyan.StdoutSink())
	}
	if name != "" {
		parent = parent.Child()
	}

	data := &logFilterData{parent}

	return func(action z.Action) z.Action {
		return func(c *z.Context) z.Result {
			// TODO: Adds request id to logger scope.
			var sublogger bunyan.Log
			rid := GetRequestId(c)
			if rid != "" {
				sublogger = parent.
					Record("request_id", rid).
					Child()
			} else {
				sublogger = parent.Child()
			}

			sublogger.Infof("%s %s", c.Request.Method, c.Request.URL.Path)
			c.Set(LogFilterPrefix, data)

			result := action(c)

			duration := GetDuration(c)
			if duration != 0 {
				sublogger.Infof("finish %s", duration.String())
			} else {
				sublogger.Infof("finish")
			}

			return result
		}
	}
}

func GetLogger(c *z.Context) bunyan.Log {
	logger_, ok := c.GetOk(LogFilterPrefix)
	if !ok {
		return nil
	}

	logger, ok := logger_.(bunyan.Log)
	if !ok {
		return nil
	}

	return logger
}<commit_msg>Log some interesting header on incoming request.<commit_after>package filters

import "net/http"
import "github.com/chakrit/go-bunyan"
import z "github.com/zaiuz/zaiuz"

const LogFilterPrefix = "z.log"

type logFilterData struct {
	logger bunyan.Log
}

func LogFilter(name string, parent bunyan.Log) z.Filter {
	if parent == nil {
		parent = bunyan.NewStdLogger(name, bunyan.StdoutSink())
	}
	if name != "" {
		parent = parent.Child()
	}

	data := &logFilterData{parent}

	return func(action z.Action) z.Action {
		return func(c *z.Context) z.Result {
			var sublogger bunyan.Log
			rid := GetRequestId(c)
			if rid != "" {
				sublogger = parent.Record("request_id", rid).Child()
			} else {
				sublogger = parent.Child()
			}

			sublogger.Record("headers", headerDigest(c.Request.Header)).
				Infof("%s %s", c.Request.Method, c.Request.URL.Path)
			c.Set(LogFilterPrefix, data)

			result := action(c)

			duration := GetDuration(c)
			if duration != 0 {
				sublogger.Infof("finish %s", duration.String())
			} else {
				sublogger.Infof("finish")
			}

			return result
		}
	}
}

func GetLogger(c *z.Context) bunyan.Log {
	logger_, ok := c.GetOk(LogFilterPrefix)
	if !ok {
		return nil
	}

	logger, ok := logger_.(bunyan.Log)
	if !ok {
		return nil
	}

	return logger
}

func headerDigest(headers http.Header) map[string]string {
	interests := []string{"Accept", "User-Agent", "Referer"}

	result := map[string]string{}
	for _, header := range interests {
		values, ok := headers[header]
		if ok && len(values) > 0 {
			result[header] = values[0]
		}
	}

	return result
}
{'fraction_non_alphanumeric': 0.1441312879058152, 'fraction_numerical': 0.0014270424545130217, 'mean_word_length': 3.38125, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, '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': '7005986', 'n_tokens_mistral': 1142, 'n_tokens_neox': 1023, 'n_words': 232}