Skip to content

Commit 6f844ed

Browse files
authored
[receiver/haproxy] fix the show stat command (#32366)
**Description:** Fix an issue where we called `show stats` instead of `show stat`. This also fixes the situation where no records are present by properly trimming the data. **Link to tracking Issue:** Fixes #32291 **Testing:** Added a unit test.
1 parent ba91f69 commit 6f844ed

File tree

4 files changed

+75
-6
lines changed

4 files changed

+75
-6
lines changed

.chloggen/haproxy_stat.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: haproxyreceiver
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Fix show stat command on unix socket
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [32291]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

receiver/haproxyreceiver/scraper.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
)
2929

3030
var (
31-
showStatsCommand = []byte("show stats\n")
31+
showStatsCommand = []byte("show stat\n")
3232
)
3333

3434
type scraper struct {
@@ -71,13 +71,14 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
7171
return pmetric.NewMetrics(), err
7272
}
7373
buf := make([]byte, 4096)
74-
_, err = c.Read(buf)
74+
n, err := c.Read(buf)
7575
if err != nil {
7676
return pmetric.NewMetrics(), err
7777
}
78+
buf = buf[0:n]
7879
records, err = s.readStats(buf)
7980
if err != nil {
80-
return pmetric.NewMetrics(), err
81+
return pmetric.NewMetrics(), fmt.Errorf("error reading stats: %w", err)
8182
}
8283
}
8384

@@ -262,7 +263,7 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
262263
}
263264

264265
func (s *scraper) readStats(buf []byte) ([]map[string]string, error) {
265-
reader := csv.NewReader(bytes.NewReader(buf))
266+
reader := csv.NewReader(bytes.NewReader(bytes.TrimSpace(buf)))
266267
headers, err := reader.Read()
267268
if err != nil {
268269
return nil, err

receiver/haproxyreceiver/scraper_test.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func Test_scraper_readStats(t *testing.T) {
3636

3737
data := string(buf[0:nr])
3838
switch data {
39-
case "show stats\n":
39+
case "show stat\n":
4040
stats, err2 := os.ReadFile(filepath.Join("testdata", "stats.txt"))
4141
require.NoError(t, err2)
4242
_, err2 = c.Write(stats)
@@ -79,7 +79,7 @@ func Test_scraper_readStatsWithIncompleteValues(t *testing.T) {
7979

8080
data := string(buf[0:nr])
8181
switch data {
82-
case "show stats\n":
82+
case "show stat\n":
8383
stats, err2 := os.ReadFile(filepath.Join("testdata", "30252_stats.txt"))
8484
require.NoError(t, err2)
8585
_, err2 = c.Write(stats)
@@ -103,3 +103,41 @@ func Test_scraper_readStatsWithIncompleteValues(t *testing.T) {
103103
pmetrictest.IgnoreTimestamp(), pmetrictest.IgnoreResourceAttributeValue("haproxy.addr"),
104104
pmetrictest.IgnoreResourceMetricsOrder()))
105105
}
106+
107+
func Test_scraper_readStatsWithNoValues(t *testing.T) {
108+
f, err := os.MkdirTemp("", "haproxytest")
109+
require.NoError(t, err)
110+
socketAddr := filepath.Join(f, "testhaproxy.sock")
111+
l, err := net.Listen("unix", socketAddr)
112+
require.NoError(t, err)
113+
defer l.Close()
114+
115+
go func() {
116+
c, err2 := l.Accept()
117+
require.NoError(t, err2)
118+
119+
buf := make([]byte, 512)
120+
nr, err2 := c.Read(buf)
121+
require.NoError(t, err2)
122+
123+
data := string(buf[0:nr])
124+
switch data {
125+
case "show stat\n":
126+
stats, err2 := os.ReadFile(filepath.Join("testdata", "empty_stats.txt"))
127+
require.NoError(t, err2)
128+
_, err2 = c.Write(stats)
129+
require.NoError(t, err2)
130+
default:
131+
require.Fail(t, fmt.Sprintf("invalid message: %v", data))
132+
}
133+
}()
134+
135+
haProxyCfg := newDefaultConfig().(*Config)
136+
haProxyCfg.Endpoint = socketAddr
137+
s := newScraper(haProxyCfg, receivertest.NewNopCreateSettings())
138+
m, err := s.scrape(context.Background())
139+
require.NoError(t, err)
140+
require.NotNil(t, m)
141+
142+
require.Equal(t, 0, m.MetricCount())
143+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime,agent_status,agent_code,agent_duration,check_desc,agent_desc,check_rise,check_fall,check_health,agent_rise,agent_fall,agent_health,addr,cookie,mode,algo,conn_rate,conn_rate_max,conn_tot,intercepted,dcon,dses,wrew,connect,reuse,cache_lookups,cache_hits,srv_icur,src_ilim,qtime_max,ctime_max,rtime_max,ttime_max,eint,idle_conn_cur,safe_conn_cur,used_conn_cur,need_conn_est,uweight,agg_server_status,agg_server_check_status,agg_check_status,srid,sess_other,h1sess,h2sess,h3sess,req_other,h1req,h2req,h3req,proto,-,ssl_sess,ssl_reused_sess,ssl_failed_handshake,h2_headers_rcvd,h2_data_rcvd,h2_settings_rcvd,h2_rst_stream_rcvd,h2_goaway_rcvd,h2_detected_conn_protocol_errors,h2_detected_strm_protocol_errors,h2_rst_stream_resp,h2_goaway_resp,h2_open_connections,h2_backend_open_streams,h2_total_connections,h2_backend_total_streams,h1_open_connections,h1_open_streams,h1_total_connections,h1_total_streams,h1_bytes_in,h1_bytes_out,
2+
3+

0 commit comments

Comments
 (0)