Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
NetData
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Ansible
Roles
NetData
Commits
fc66bc93
Commit
fc66bc93
authored
8 years ago
by
jurgenhaas
Browse files
Options
Downloads
Patches
Plain Diff
[WIP] improved haproxy chart script]
parent
c6563f9a
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
files/haproxy.chart.py
+72
-134
72 additions, 134 deletions
files/haproxy.chart.py
with
72 additions
and
134 deletions
files/haproxy.chart.py
+
72
−
134
View file @
fc66bc93
# -*- coding: utf-8 -*-
# Description: haproxy netdata python.d module
# Author:
Pawel Krupa (paulfantom)
# Author:
l2isbad
from
base
import
SocketService
,
UrlService
import
csv
from
base
import
UrlService
# default module values (can be overridden per job in `config`)
# update_every = 2
...
...
@@ -11,162 +10,101 @@ priority = 60000
retries
=
60
# charts order (can be overridden if you want less charts, or different order)
ORDER
=
[
'
qcur
'
,
'
scur
'
,
'
bin
'
,
'
bout
'
]
POSITION
=
[
'
2
'
,
'
4
'
,
'
8
'
,
'
9
'
]
ORDER
=
[
'
fbin
'
,
'
fbout
'
,
'
fscur
'
,
'
fqcur
'
,
'
bbin
'
,
'
bbout
'
,
'
bscur
'
,
'
bqcur
'
]
CHARTS
=
{
'
qcur
'
:
{
'
options
'
:
[
""
,
"
Current queue
"
,
'
per sec
'
,
''
,
''
,
'
line
'
],
'
fbin
'
:
{
'
options
'
:
[
None
,
"
Bytes in
"
,
"
bytes/s
"
,
'
Frontend
'
,
'
f.bin
'
,
'
line
'
],
'
lines
'
:
[
]},
'
fbout
'
:
{
'
options
'
:
[
None
,
"
Bytes out
"
,
"
bytes/s
"
,
'
Frontend
'
,
'
f.bout
'
,
'
line
'
],
'
lines
'
:
[
]},
'
fscur
'
:
{
'
options
'
:
[
None
,
"
Sessions active
"
,
"
sessions
"
,
'
Frontend
'
,
'
f.scur
'
,
'
line
'
],
'
lines
'
:
[
]},
'
fqcur
'
:
{
'
options
'
:
[
None
,
"
Session in queue
"
,
"
sessions
"
,
'
Frontend
'
,
'
f.qcur
'
,
'
line
'
],
'
lines
'
:
[
[
'
name
'
,
None
,
'
incremental
'
]
]},
'
scur
'
:
{
'
options
'
:
[
""
,
"
Current session rate
"
,
'
per sec
'
,
''
,
'
'
,
'
line
'
],
'
bbin
'
:
{
'
options
'
:
[
None
,
"
Bytes in
"
,
"
bytes/s
"
,
'
Backend
'
,
'
b.bin
'
,
'
line
'
],
'
lines
'
:
[
[
'
name
'
,
None
,
'
incremental
'
]
]},
'
b
in
'
:
{
'
options
'
:
[
""
,
"
Bytes
in
"
,
'
kilo
bytes/s
'
,
'
'
,
'
'
,
'
line
'
],
'
b
bout
'
:
{
'
options
'
:
[
None
,
"
Bytes
out
"
,
"
bytes/s
"
,
'
Backend
'
,
'
b.bout
'
,
'
line
'
],
'
lines
'
:
[
[
'
name
'
,
None
,
'
incremental
'
,
1
,
1024
]
]},
'
b
out
'
:
{
'
options
'
:
[
""
,
"
Bytes out
"
,
'
kilobytes/s
'
,
''
,
'
'
,
'
line
'
],
'
b
scur
'
:
{
'
options
'
:
[
None
,
"
Sessions active
"
,
"
sessions
"
,
'
Backend
'
,
'
b.scur
'
,
'
line
'
],
'
lines
'
:
[
[
'
name
'
,
None
,
'
incremental
'
,
1
,
1024
]
]},
'
bqcur
'
:
{
'
options
'
:
[
None
,
"
Sessions in queue
"
,
"
sessions
"
,
'
Backend
'
,
'
b.qcur
'
,
'
line
'
],
'
lines
'
:
[
]}
}
class
Service
(
SocketService
,
UrlService
):
class
Service
(
UrlService
):
def
__init__
(
self
,
configuration
=
None
,
name
=
None
):
self
.
use_socket
=
'
unix_socket
'
in
configuration
if
self
.
use_socket
:
SocketService
.
__init__
(
self
,
configuration
=
configuration
,
name
=
name
)
self
.
request
=
"
show stat
\r\n
"
else
:
UrlService
.
__init__
(
self
,
configuration
=
configuration
,
name
=
name
)
if
not
self
.
url
.
endswith
(
"
/;csv;norefresh
"
):
self
.
url
+=
"
/;csv;norefresh
"
# self.order and self.definitions are created with _create_definitions method
# self.order = ORDER
# self.definitions = CHARTS
self
.
order
=
[]
self
.
definitions
=
{}
UrlService
.
__init__
(
self
,
configuration
=
configuration
,
name
=
name
)
self
.
url
=
"
http://127.0.0.1:7000/haproxy_stats;csv
"
self
.
order
=
ORDER
self
.
order_front
=
[
_
for
_
in
ORDER
if
_
.
startswith
(
'
f
'
)]
self
.
order_back
=
[
_
for
_
in
ORDER
if
_
.
startswith
(
'
b
'
)]
self
.
definitions
=
CHARTS
self
.
charts
=
True
def
create_charts
(
self
,
front_ends
,
back_ends
):
for
chart
in
self
.
order_front
:
for
_
in
range
(
len
(
front_ends
)):
self
.
definitions
[
chart
][
'
lines
'
].
append
([
'
_
'
.
join
([
chart
,
front_ends
[
_
][
'
# pxname
'
]]),
front_ends
[
_
][
'
# pxname
'
],
'
incremental
'
if
chart
.
startswith
(
(
'
fb
'
,
'
bb
'
))
else
'
absolute
'
])
for
chart
in
self
.
order_back
:
for
_
in
range
(
len
(
back_ends
)):
self
.
definitions
[
chart
][
'
lines
'
].
append
([
'
_
'
.
join
([
chart
,
back_ends
[
_
][
'
# pxname
'
]]),
back_ends
[
_
][
'
# pxname
'
],
'
incremental
'
if
chart
.
startswith
(
(
'
fb
'
,
'
bb
'
))
else
'
absolute
'
])
def
_get_
parsed_
data
(
self
):
def
_get_data
(
self
):
"""
Retrieve and parse raw data
Format data received from http request
:return: dict
"""
try
:
if
self
.
use_socket
:
raw
=
SocketService
.
_get_raw_data
(
self
)
else
:
raw
=
UrlService
.
_get_raw_data
(
self
)
except
(
ValueError
,
AttributeError
):
return
None
if
raw
is
None
:
return
None
if
self
.
url
[
-
4
:]
!=
'
;csv
'
:
self
.
url
+=
'
;csv
'
self
.
info
(
'
Url rewritten to %s
'
%
self
.
url
)
try
:
# return [row for row in csv.reader(raw.splitlines(), delimiter=',')]
return
list
(
csv
.
reader
(
raw
.
splitlines
(),
delimiter
=
'
,
'
))
raw_data
=
self
.
_get_raw_data
().
splitlines
()
except
Exception
as
e
:
self
.
debug
(
str
(
e
))
self
.
error
(
str
(
e
))
return
None
def
_get_data
(
self
):
"""
Format data
:return: dict
"""
parsed
=
self
.
_get_parsed_data
()
# if parsed is None or len(parsed) == 0:
if
not
parsed
:
return
None
all_instances
=
[
dict
(
zip
(
raw_data
[
0
].
split
(
'
,
'
),
raw_data
[
_
].
split
(
'
,
'
)))
for
_
in
range
(
1
,
len
(
raw_data
))]
data
=
{}
for
node
in
parsed
[
1
:]:
try
:
prefix
=
node
[
0
]
+
"
_
"
+
node
[
1
]
+
"
_
"
except
IndexError
:
continue
for
i
in
range
(
len
(
ORDER
)):
try
:
data
[
prefix
+
ORDER
[
i
]]
=
int
(
node
[
int
(
POSITION
[
i
])])
except
ValueError
:
pass
back_ends
=
[
backend
for
backend
in
all_instances
if
backend
[
'
svname
'
]
==
'
BACKEND
'
and
backend
[
'
# pxname
'
]
!=
'
stats
'
]
front_ends
=
[
frontend
for
frontend
in
all_instances
if
frontend
[
'
svname
'
]
==
'
FRONTEND
'
and
frontend
[
'
# pxname
'
]
!=
'
stats
'
]
# if len(data) == 0:
if
not
data
:
return
None
return
data
if
self
.
charts
:
self
.
create_charts
(
front_ends
,
back_ends
)
self
.
charts
=
False
def
_check_raw_data
(
self
,
data
):
# FIXME
return
True
to_netdata
=
dict
()
def
_create_definitions
(
self
):
try
:
data
=
self
.
_get_parsed_data
()[
1
:]
except
TypeError
:
return
False
# create order
all_pxnames
=
[]
all_svnames
=
{}
last_pxname
=
""
for
node
in
data
:
try
:
pxname
=
node
[
0
]
svname
=
node
[
1
]
except
IndexError
:
continue
if
pxname
!=
last_pxname
:
all_pxnames
.
append
(
pxname
)
all_svnames
[
pxname
]
=
[
svname
]
for
key
in
ORDER
:
# order entry consists of pxname, "_", and column name (like qcur)
self
.
order
.
append
(
pxname
+
"
_
"
+
key
)
else
:
all_svnames
[
pxname
].
append
(
svname
)
last_pxname
=
pxname
# create definitions
for
pxname
in
all_pxnames
:
for
name
in
ORDER
:
options
=
list
(
CHARTS
[
name
][
'
options
'
])
options
[
3
]
=
pxname
options
[
4
]
=
pxname
+
"
.
"
+
name
line_template
=
CHARTS
[
name
][
'
lines
'
][
0
]
lines
=
[]
# omit_first = False
# if len(all_svnames[pxname]) > 1:
# omit_first = True
for
svname
in
all_svnames
[
pxname
]:
# if omit_first:
# omit_first = False
# continue
tmp
=
list
(
line_template
)
# tmp[0] = pxname + "_" + svname + "_" + name
tmp
[
0
]
=
"
_
"
.
join
([
pxname
,
svname
,
name
])
tmp
[
1
]
=
svname
lines
.
append
(
tmp
)
self
.
definitions
[
pxname
+
"
_
"
+
name
]
=
{
'
options
'
:
options
,
'
lines
'
:
lines
}
for
frontend
in
front_ends
:
for
_
in
self
.
order_front
:
to_netdata
.
update
({
'
_
'
.
join
([
_
,
frontend
[
'
# pxname
'
]]):
int
(
frontend
[
_
[
1
:]])
if
frontend
.
get
(
_
[
1
:])
else
0
})
return
True
for
backend
in
back_ends
:
for
_
in
self
.
order_back
:
to_netdata
.
update
({
'
_
'
.
join
([
_
,
backend
[
'
# pxname
'
]]):
int
(
backend
[
_
[
1
:]])
if
backend
.
get
(
_
[
1
:])
else
0
})
def
check
(
self
):
if
self
.
use_socket
:
SocketService
.
check
(
self
)
else
:
UrlService
.
check
(
self
)
try
:
return
self
.
_create_definitions
()
except
Exception
as
e
:
self
.
debug
(
str
(
e
))
return
False
return
to_netdata
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment