Skip to content

Commit f3ef8be

Browse files
authored
[BUG] do not output error message for connections closed due to timeout (#241)
* do not output error log for connection closed
1 parent 5ba501c commit f3ef8be

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

transport/logging.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func LoggingDialer(d Dialer, logger *logp.Logger) Dialer {
4747

4848
func (l *loggingConn) Read(b []byte) (int, error) {
4949
n, err := l.Conn.Read(b)
50-
if err != nil && !errors.Is(err, io.EOF) {
50+
if err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, net.ErrClosed) {
5151
l.logger.Debugf("Error reading from connection: %v", err)
5252
}
5353
return n, err

transport/logging_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package transport
19+
20+
import (
21+
"fmt"
22+
"io"
23+
"net/http"
24+
"net/http/httptest"
25+
"testing"
26+
"time"
27+
28+
"github.com/elastic/elastic-agent-libs/logp"
29+
"github.com/stretchr/testify/assert"
30+
"github.com/stretchr/testify/require"
31+
)
32+
33+
func TestCloseConnectionError(t *testing.T) {
34+
// observe all logs
35+
if err := logp.DevelopmentSetup(logp.ToObserverOutput()); err != nil {
36+
t.Fatalf("cannot initialise logger on development mode: %+v", err)
37+
}
38+
39+
// Set up a test HTTP server
40+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
41+
fmt.Fprintln(w, `{"status": "ok"}`)
42+
}))
43+
defer server.Close()
44+
45+
logger := logp.NewLogger("test")
46+
// Set IdleConnTimeout to 2 seconds and a custom dialer
47+
transport := &http.Transport{
48+
IdleConnTimeout: 2 * time.Second,
49+
// uses our implementation of custom dialer
50+
DialContext: LoggingDialer(NetDialer(10*time.Second), logger).DialContext,
51+
}
52+
53+
client := &http.Client{
54+
Transport: transport,
55+
}
56+
57+
// First request to the test server
58+
resp, err := client.Get(server.URL) //nolint:noctx // It is a test
59+
require.NoError(t, err, "first request failed")
60+
_, _ = io.ReadAll(resp.Body)
61+
resp.Body.Close()
62+
63+
// Wait for a duration longer than IdleConnTimeout
64+
waitTime := 6 * time.Second
65+
time.Sleep(waitTime)
66+
67+
// Second request to the test server after idle timeout
68+
resp, err = client.Get(server.URL) //nolint:noctx // It is a test
69+
require.NoError(t, err, "second request failed")
70+
_, _ = io.ReadAll(resp.Body)
71+
resp.Body.Close()
72+
73+
logs := logp.ObserverLogs().FilterMessageSnippet("Error reading from connection:").TakeAll()
74+
assert.Equal(t, 0, len(logs), "did not ignore use of closed connection error")
75+
76+
}

0 commit comments

Comments
 (0)