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
f7248f2d
Commit
f7248f2d
authored
8 years ago
by
jurgenhaas
Browse files
Options
Downloads
Patches
Plain Diff
Improved version of haproxy charts
parent
fc66bc93
No related branches found
Branches containing commit
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
+85
-30
85 additions, 30 deletions
files/haproxy.chart.py
with
85 additions
and
30 deletions
files/haproxy.chart.py
+
85
−
30
View file @
f7248f2d
...
...
@@ -2,7 +2,7 @@
# Description: haproxy netdata python.d module
# Author: l2isbad
from
base
import
UrlService
from
base
import
UrlService
,
SocketService
# default module values (can be overridden per job in `config`)
# update_every = 2
...
...
@@ -10,14 +10,14 @@ priority = 60000
retries
=
60
# charts order (can be overridden if you want less charts, or different order)
ORDER
=
[
'
fbin
'
,
'
fbout
'
,
'
fscur
'
,
'
fqcur
'
,
'
bbin
'
,
'
bbout
'
,
'
bscur
'
,
'
bqcur
'
]
ORDER
=
[
'
fbin
'
,
'
fbout
'
,
'
fscur
'
,
'
fqcur
'
,
'
bbin
'
,
'
bbout
'
,
'
bscur
'
,
'
bqcur
'
,
'
health_down
'
]
CHARTS
=
{
'
fbin
'
:
{
'
options
'
:
[
None
,
"
B
ytes in
"
,
"
bytes/s
"
,
'
Frontend
'
,
'
f.bin
'
,
'
line
'
],
'
options
'
:
[
None
,
"
Kilob
ytes in
"
,
"
kilo
bytes
in
/s
"
,
'
Frontend
'
,
'
f.bin
'
,
'
line
'
],
'
lines
'
:
[
]},
'
fbout
'
:
{
'
options
'
:
[
None
,
"
B
ytes out
"
,
"
bytes/s
"
,
'
Frontend
'
,
'
f.bout
'
,
'
line
'
],
'
options
'
:
[
None
,
"
Kilob
ytes out
"
,
"
kilo
bytes
out
/s
"
,
'
Frontend
'
,
'
f.bout
'
,
'
line
'
],
'
lines
'
:
[
]},
'
fscur
'
:
{
...
...
@@ -29,11 +29,11 @@ CHARTS = {
'
lines
'
:
[
]},
'
bbin
'
:
{
'
options
'
:
[
None
,
"
B
ytes in
"
,
"
bytes/s
"
,
'
Backend
'
,
'
b.bin
'
,
'
line
'
],
'
options
'
:
[
None
,
"
Kilob
ytes in
"
,
"
kilo
bytes
in
/s
"
,
'
Backend
'
,
'
b.bin
'
,
'
line
'
],
'
lines
'
:
[
]},
'
bbout
'
:
{
'
options
'
:
[
None
,
"
B
ytes out
"
,
"
bytes/s
"
,
'
Backend
'
,
'
b.bout
'
,
'
line
'
],
'
options
'
:
[
None
,
"
Kilob
ytes out
"
,
"
kilo
bytes
out
/s
"
,
'
Backend
'
,
'
b.bout
'
,
'
line
'
],
'
lines
'
:
[
]},
'
bscur
'
:
{
...
...
@@ -43,55 +43,74 @@ CHARTS = {
'
bqcur
'
:
{
'
options
'
:
[
None
,
"
Sessions in queue
"
,
"
sessions
"
,
'
Backend
'
,
'
b.qcur
'
,
'
line
'
],
'
lines
'
:
[
]},
'
health_down
'
:
{
'
options
'
:
[
None
,
"
Servers in DOWN state
"
,
"
failed servers
"
,
'
Health
'
,
'
h.down
'
,
'
line
'
],
'
lines
'
:
[
]}
}
class
Service
(
UrlService
):
class
Service
(
UrlService
,
SocketService
):
def
__init__
(
self
,
configuration
=
None
,
name
=
None
):
UrlService
.
__init__
(
self
,
configuration
=
configuration
,
name
=
name
)
self
.
url
=
"
http://127.0.0.1:7000/haproxy_stats;csv
"
SocketService
.
__init__
(
self
,
configuration
=
configuration
,
name
=
name
)
self
.
user
=
self
.
configuration
.
get
(
'
user
'
)
self
.
password
=
self
.
configuration
.
get
(
'
pass
'
)
self
.
request
=
'
show stat
\n
'
self
.
poll_method
=
(
UrlService
,
SocketService
)
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
check
(
self
):
if
self
.
configuration
.
get
(
'
url
'
):
self
.
poll_method
=
self
.
poll_method
[
0
]
url
=
self
.
configuration
.
get
(
'
url
'
)
if
not
url
.
endswith
(
'
;csv;norefresh
'
):
self
.
error
(
'
Bad url(%s). Must be http://<ip.address>:<port>/<url>;csv;norefresh
'
%
url
)
return
False
elif
self
.
configuration
.
get
(
'
socket
'
):
self
.
poll_method
=
self
.
poll_method
[
1
]
else
:
self
.
error
(
'
No configuration is specified
'
)
return
False
if
self
.
poll_method
.
check
(
self
):
self
.
info
(
'
Plugin was started succesfully. We are using %s.
'
%
self
.
poll_method
.
__name__
)
return
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
'
])
for
_
in
range
(
len
(
front_ends
))
:
self
.
definitions
[
'
fbin
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
fbin
'
,
front_ends
[
_
][
'
# pxname
'
]]),
front_ends
[
_
][
'
# pxname
'
],
'
incremental
'
,
1
,
1024
])
self
.
definitions
[
'
fbout
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
fbout
'
,
front_ends
[
_
][
'
# pxname
'
]]),
front_ends
[
_
][
'
# pxname
'
],
'
incremental
'
,
1
,
1024
])
self
.
definitions
[
'
fscur
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
fscur
'
,
front_ends
[
_
][
'
# pxname
'
]]),
front_ends
[
_
][
'
# pxname
'
],
'
absolute
'
])
self
.
definitions
[
'
fqcur
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
fqcur
'
,
front_ends
[
_
][
'
# pxname
'
]]),
front_ends
[
_
][
'
# pxname
'
],
'
absolute
'
])
for
_
in
range
(
len
(
back_ends
))
:
self
.
definitions
[
'
bbin
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
bbin
'
,
back_ends
[
_
][
'
# pxname
'
]]),
back_ends
[
_
][
'
# pxname
'
],
'
incremental
'
,
1
,
1024
])
self
.
definitions
[
'
bbout
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
bbout
'
,
back_ends
[
_
][
'
# pxname
'
]])
,
back_ends
[
_
][
'
# pxname
'
]
,
'
incremental
'
,
1
,
1024
])
self
.
definitions
[
'
bscur
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
bscur
'
,
back_ends
[
_
][
'
# pxname
'
]]),
back_ends
[
_
][
'
# pxname
'
],
'
absolute
'
])
self
.
definitions
[
'
bqcur
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
bqcur
'
,
back_ends
[
_
][
'
# pxname
'
]]),
back_ends
[
_
][
'
# pxname
'
],
'
absolute
'
])
self
.
definitions
[
'
health_down
'
][
'
lines
'
].
append
([
'
_
'
.
join
([
'
hdown
'
,
back_ends
[
_
][
'
# pxname
'
]]),
back_ends
[
_
][
'
# pxname
'
],
'
absolute
'
])
def
_get_data
(
self
):
"""
Format data received from http request
:return: dict
"""
if
self
.
url
[
-
4
:]
!=
'
;csv
'
:
self
.
url
+=
'
;csv
'
self
.
info
(
'
Url rewritten to %s
'
%
self
.
url
)
try
:
raw_data
=
self
.
_get_raw_data
().
splitlines
()
raw_data
=
self
.
poll_method
.
_get_raw_data
(
self
).
splitlines
()
except
Exception
as
e
:
self
.
error
(
str
(
e
))
return
None
all_instances
=
[
dict
(
zip
(
raw_data
[
0
].
split
(
'
,
'
),
raw_data
[
_
].
split
(
'
,
'
)))
for
_
in
range
(
1
,
len
(
raw_data
))]
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
'
]
back_ends
=
list
(
filter
(
is_backend
,
all_instances
))
front_ends
=
list
(
filter
(
is_frontend
,
all_instances
))
servers
=
list
(
filter
(
is_server
,
all_instances
))
if
self
.
charts
:
self
.
create_charts
(
front_ends
,
back_ends
)
...
...
@@ -107,4 +126,40 @@ class Service(UrlService):
for
_
in
self
.
order_back
:
to_netdata
.
update
({
'
_
'
.
join
([
_
,
backend
[
'
# pxname
'
]]):
int
(
backend
[
_
[
1
:]])
if
backend
.
get
(
_
[
1
:])
else
0
})
for
_
in
range
(
len
(
back_ends
)):
to_netdata
.
update
({
'
_
'
.
join
([
'
hdown
'
,
back_ends
[
_
][
'
# pxname
'
]]):
len
([
server
for
server
in
servers
if
is_server_down
(
server
,
back_ends
,
_
)])})
return
to_netdata
def
_check_raw_data
(
self
,
data
):
"""
Check if all data has been gathered from socket
:param data: str
:return: boolean
"""
return
not
bool
(
data
)
def
is_backend
(
backend
):
try
:
return
backend
[
'
svname
'
]
==
'
BACKEND
'
and
backend
[
'
# pxname
'
]
!=
'
stats
'
except
Exception
:
return
False
def
is_frontend
(
frontend
):
try
:
return
frontend
[
'
svname
'
]
==
'
FRONTEND
'
and
frontend
[
'
# pxname
'
]
!=
'
stats
'
except
Exception
:
return
False
def
is_server
(
server
):
try
:
return
not
server
[
'
svname
'
].
startswith
((
'
FRONTEND
'
,
'
BACKEND
'
))
except
Exception
:
return
False
def
is_server_down
(
server
,
back_ends
,
_
):
try
:
return
server
[
'
# pxname
'
]
==
back_ends
[
_
][
'
# pxname
'
]
and
server
[
'
status
'
]
!=
'
UP
'
except
Exception
:
return
False
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