forked from heroku/log-shuttle
/
config.go
154 lines (136 loc) · 5.47 KB
/
config.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package main
import (
"flag"
"fmt"
"log"
"net/url"
"os"
"time"
"github.com/pebbe/util"
)
var LogplexUrl = os.Getenv("LOGPLEX_URL")
const (
INPUT_FORMAT_RAW = iota
INPUT_FORMAT_RFC3164 = iota
)
const (
DEFAULT_INPUT_FORMAT = INPUT_FORMAT_RAW
DEFAULT_FRONT_BUFF = 1000
DEFAULT_BACK_BUFF = 50
DEFAULT_STATS_BUFF = 5000
DEFAULT_STATS_ADDR = ""
DEFAULT_TIMEOUT = 5 * time.Second
DEFAULT_WAIT_DURATION = 250 * time.Millisecond
DEFAULT_MAX_ATTEMPTS = 3
DEFAULT_STATS_INTERVAL = 0 * time.Second
DEFAULT_STATS_SOURCE = ""
)
const (
errDrop errType = iota
errLost
)
type errType int
type errData struct {
count int
since time.Time
eType errType
}
type ShuttleConfig struct {
BackBuff int
FrontBuff int
StatsBuff int
BatchSize int
NumBatchers int
NumOutlets int
InputFormat int
MaxAttempts int
LogsURL string
Prival string
Version string
Procid string
Hostname string
Appname string
Msgid string
StatsAddr string
StatsSource string
SkipHeaders bool
SkipVerify bool
PrintVersion bool
Verbose bool
LogToSyslog bool
WaitDuration time.Duration
Timeout time.Duration
StatsInterval time.Duration
lengthPrefixedSyslogFrameHeaderSize int
syslogFrameHeaderFormat string
}
func (c *ShuttleConfig) ParseFlags() {
flag.BoolVar(&c.PrintVersion, "version", false, "Print log-shuttle version.")
flag.BoolVar(&c.Verbose, "verbose", false, "Enable verbose debug info.")
flag.BoolVar(&c.SkipHeaders, "skip-headers", false, "Skip the prepending of rfc5424 headers.")
flag.BoolVar(&c.SkipVerify, "skip-verify", false, "Skip the verification of HTTPS server certificate.")
flag.StringVar(&c.Prival, "prival", "190", "The primary value of the rfc5424 header.")
flag.StringVar(&c.Version, "syslog-version", "1", "The version of syslog.")
flag.StringVar(&c.Procid, "procid", "shuttle", "The procid field for the syslog header.")
flag.StringVar(&c.Appname, "appname", "", "The app-name field for the syslog header.")
flag.StringVar(&c.Appname, "logplex-token", "token", "Secret logplex token.")
flag.StringVar(&c.Hostname, "hostname", "shuttle", "The hostname field for the syslog header.")
flag.StringVar(&c.Msgid, "msgid", "- -", "The msgid field for the syslog header.")
flag.StringVar(&c.LogsURL, "logs-url", "", "The receiver of the log data.")
flag.StringVar(&c.StatsAddr, "stats-addr", DEFAULT_STATS_ADDR, "Where to expose stats.")
flag.StringVar(&c.StatsSource, "stats-source", DEFAULT_STATS_SOURCE, "When emitting stats, add source=<stats-source> to the stats.")
flag.DurationVar(&c.StatsInterval, "stats-interval", time.Duration(DEFAULT_STATS_INTERVAL), "How often to emit/reset stats.")
flag.IntVar(&c.MaxAttempts, "max-attempts", DEFAULT_MAX_ATTEMPTS, "Max number of retries.")
flag.IntVar(&c.InputFormat, "input-format", DEFAULT_INPUT_FORMAT, "0=raw (default), 1=rfc3164 (syslog(3))")
flag.IntVar(&c.NumBatchers, "num-batchers", 2, "The number of batchers to run.")
flag.IntVar(&c.NumOutlets, "num-outlets", 4, "The number of outlets to run.")
flag.DurationVar(&c.WaitDuration, "wait", time.Duration(DEFAULT_WAIT_DURATION), "Duration to wait to flush messages to logplex")
flag.IntVar(&c.BatchSize, "batch-size", 500, "Number of messages to pack into a logplex http request.")
flag.IntVar(&c.FrontBuff, "front-buff", DEFAULT_FRONT_BUFF, "Number of messages to buffer in log-shuttle's input chanel.")
flag.IntVar(&c.BackBuff, "back-buff", DEFAULT_BACK_BUFF, "Number of batches to buffer before dropping.")
flag.IntVar(&c.StatsBuff, "stats-buff", DEFAULT_STATS_BUFF, "Number of stats to buffer.")
flag.DurationVar(&c.Timeout, "timeout", time.Duration(DEFAULT_TIMEOUT), "Duration to wait for a response from Logplex.")
flag.BoolVar(&c.LogToSyslog, "log-to-syslog", false, "Log to syslog instead of stderr")
flag.Parse()
if c.MaxAttempts < 1 {
log.Fatalf("-max-attempts must be >= 1")
}
// This is here to pre-comute this so other's don't have to later
c.lengthPrefixedSyslogFrameHeaderSize = len(c.Prival) + len(c.Version) + len(LOGPLEX_BATCH_TIME_FORMAT) +
len(c.Hostname) + len(c.Appname) + len(c.Procid) + len(c.Msgid) + 8 // spaces, < & >
c.syslogFrameHeaderFormat = fmt.Sprintf("%s <%s>%s %s %s %s %s %s ",
"%d",
c.Prival,
c.Version,
"%s", // The time should be put here
c.Hostname,
c.Appname,
c.Procid,
c.Msgid)
}
func (c *ShuttleConfig) OutletURL() string {
var err error
var oUrl *url.URL
if len(c.LogsURL) > 0 {
oUrl, err = url.Parse(c.LogsURL)
if err != nil {
log.Fatalf("Unable to parse logs-url")
}
}
if len(LogplexUrl) > 0 {
oUrl, err = url.Parse(LogplexUrl)
if err != nil {
log.Fatalf("Unable to parse $LOGPLEX_URL")
}
}
if oUrl == nil {
log.Fatalf("Must set -logs-url or $LOGPLEX_URL.")
}
if oUrl.User == nil {
oUrl.User = url.UserPassword("token", c.Appname)
}
return oUrl.String()
}
func (c *ShuttleConfig) UseStdin() bool {
return !util.IsTerminal(os.Stdin)
}