-
Notifications
You must be signed in to change notification settings - Fork 1
/
HttpLogger.go
119 lines (92 loc) · 3.08 KB
/
HttpLogger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// © 2016-2024 Graylog, Inc.
// Package logger-go from resurface.io provides tools to log API requests and responses from different Golang web frameworks to a complete API system of record. (https://resurface.io)
package logger
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"log"
"net/http"
"os"
"strings"
)
// Options struct is passed to a "NewLogger" function to specify the desired configuration of the logger to be created.
type Options struct {
//Rules defines the rules that will be applied to the logger.
Rules string
//Url defines the Url the logger will send the logs to.
Url string
//Enabled defines the state of the logger; enabled or disabled.
Enabled interface{}
//Queue is a slice of strings used to store logs; exclusively for testing purposes.
//Queue must be nil for the logger to properly function.
Queue []string
}
const httpLoggerAgent string = "HttpLogger.go"
// HttpLogger is the struct contains a pointer to a baseLogger instance and a set of rules used to define the behaviour of the logger.
type HttpLogger struct {
*baseLogger
rules *HttpRules
}
// NewHttpLogger returns a pointer to a new HttpLogger object, with the given options applied, and an error
func NewHttpLogger(options Options) (*HttpLogger, error) {
baseLogger := newBaseLogger(httpLoggerAgent, options.Url, options.Enabled, options.Queue)
loggerRules, err := newHttpRules(options.Rules)
if err != nil {
return nil, err
}
logger := &HttpLogger{
baseLogger,
loggerRules,
}
logger.skipCompression = loggerRules.skipCompression
logger.skipSubmission = loggerRules.skipSubmission
if (logger.url != "") && (strings.HasPrefix(logger.url, "http:") && !logger.rules.allowHttpUrl) {
logger.enableable = false
logger.enabled = false
}
return logger, nil
}
func (logger *HttpLogger) submitIfPassing(msg [][]string, customFields map[string]string) {
msg = logger.rules.apply(msg)
if msg == nil {
return
}
for key, val := range customFields {
msg = append(msg, []string{"custom_field:" + strings.ToLower(key), strings.ToLower(val)})
}
msg = append(msg, []string{"host", logger.host})
byteStr, _ := json.Marshal(msg)
msgString := string(byteStr)
msgString = strings.Replace(msgString, "\\u003c", "<", -1)
msgString = strings.Replace(msgString, "\\u003e", ">", -1)
logger.ndjsonHandler(msgString)
}
// global client to avoid opening a new connection for every request
var httpLoggerClient *http.Client
func init() {
usageLoggers, _ := GetUsageLoggers()
config := usageLoggers.TLSConfigByDefault()
tc := &tls.Config{InsecureSkipVerify: config.insecure}
if config.customCert != "" {
certPool, err := x509.SystemCertPool()
if err != nil {
certPool = x509.NewCertPool()
}
pem, err := os.ReadFile(config.customCert)
if err == nil {
certPool.AppendCertsFromPEM(pem)
tc.RootCAs = certPool
}
}
tr := &http.Transport{
MaxIdleConnsPerHost: 10000,
TLSHandshakeTimeout: config.timeout,
TLSClientConfig: tc,
}
httpLoggerClient = &http.Client{Transport: tr}
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
func (logger *HttpLogger) Stop() {
logger.stopDispatcher()
}