Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 13, 03:00 UTC
logging: Soft start for net writer (close #5520)
If enabled and there is an error when opening the net writer, ignore the error and report it along with subsequent logs to stderr.
Matthew Holt committed
May 4, 2023 at 16:29 UTC
f3e8b9d95fefc81c347ec38d913c9ccd9edb626a
1 file changed
+26
-6
modules/logging/netwriter.go
+26
-6
@@ -40,6 +40,11 @@ type NetWriter struct {
40
// The timeout to wait while connecting to the socket.
41
DialTimeout caddy.Duration `json:"dial_timeout,omitempty"`
42
43
+ // If enabled, allow connections errors when first opening the
44
+ // writer. The error and subsequent log entries will be reported
45
+ // to stderr instead until a connection can be re-established.
46
+ SoftStart bool `json:"soft_start,omitempty"`
47
+
48
addr caddy.NetworkAddress
49
}
50
@@ -92,7 +97,9 @@ func (nw NetWriter) OpenWriter() (io.WriteCloser, error) {
97
}
98
conn, err := reconn.dial()
99
if err != nil {
95
- return nil, err
100
+ // don't block config load if remote is down or some other external problem;
101
+ // we can dump logs to stderr for now (see issue #5520)
102
+ fmt.Fprintf(os.Stderr, "[ERROR] net log writer failed to connect: %v (will retry connection and print errors here in the meantime)\n", err)
103
}
104
reconn.connMu.Lock()
105
reconn.Conn = conn
@@ -104,6 +111,7 @@ func (nw NetWriter) OpenWriter() (io.WriteCloser, error) {
111
//
112
// net <address> {
113
// dial_timeout <duration>
114
+// soft_start
115
// }
116
func (nw *NetWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
117
for d.Next() {
@@ -128,6 +136,12 @@ func (nw *NetWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
136
return d.ArgErr()
137
}
138
nw.DialTimeout = caddy.Duration(timeout)
139
+
140
+ case "soft_start":
141
+ if d.NextArg() {
142
+ return d.ArgErr()
143
+ }
144
+ nw.SoftStart = true
145
}
146
}
147
}
@@ -151,8 +165,10 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) {
165
reconn.connMu.RLock()
166
conn := reconn.Conn
167
reconn.connMu.RUnlock()
154
- if n, err = conn.Write(b); err == nil {
155
- return
168
+ if conn != nil {
169
+ if n, err = conn.Write(b); err == nil {
170
+ return
171
+ }
172
}
173
174
// problem with the connection - lock it and try to fix it
@@ -161,8 +177,10 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) {
177
178
// if multiple concurrent writes failed on the same broken conn, then
179
// one of them might have already re-dialed by now; try writing again
164
- if n, err = reconn.Conn.Write(b); err == nil {
165
- return
180
+ if reconn.Conn != nil {
181
+ if n, err = reconn.Conn.Write(b); err == nil {
182
+ return
183
+ }
184
}
185
186
// there's still a problem, so try to re-attempt dialing the socket
@@ -178,7 +196,9 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) {
196
return
197
}
198
if n, err = conn2.Write(b); err == nil {
181
- reconn.Conn.Close()
199
+ if reconn.Conn != nil {
200
+ reconn.Conn.Close()
201
+ }
202
reconn.Conn = conn2
203
}
204
} else {