Project

General

Profile

lighttpd2_munin.py

icy, 2010-06-12 17:05

 
1
#!/usr/bin/python
2
"""
3
Munin plugin to monitor lighttpd 2.x statistics
4
Plugin Version 1.1
5

6
Install:
7
Copy this script to the directory of your other munin plugins
8
(e.g. /usr/share/munin/plugins) and make it executeable (chmod +x).
9
Then issue any of the following commands to enable the graphs:
10
ln -s path_to_this_script /etc/munin/plugins/lighttpd_requests
11
ln -s path_to_this_script /etc/munin/plugins/lighttpd_connections
12
ln -s path_to_this_script /etc/munin/plugins/lighttpd_traffic
13
ln -s path_to_this_script /etc/munin/plugins/lighttpd_statuscodes
14

15
Also ensure that lighttpd has mod_status enabled and that your
16
config contains a status.info action.
17
Adjust the STATUS_URL below if needed.
18
Example lighttpd 2.x config: if req.path == "/status" { status.info; }
19

20
Copyright (c) 2009-2010 Thomas Porzelt
21

22
Permission is hereby granted, free of charge, to any person obtaining a copy
23
of this software and associated documentation files (the "Software"), to deal
24
in the Software without restriction, including without limitation the rights
25
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26
copies of the Software, and to permit persons to whom the Software is
27
furnished to do so, subject to the following conditions:
28

29
The above copyright notice and this permission notice shall be included in
30
all copies or substantial portions of the Software.
31

32
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38
THE SOFTWARE.
39
"""
40

    
41
import os, sys, urllib2
42

    
43
STATUS_URL = os.environ.get('statusurl', 'http://127.0.0.1/status?format=plain')
44

    
45

    
46
def print_config(param):
47
        # generates and returns a munin config for a given chart
48
        if param == 'requests':
49
                print 'graph_title lighttpd: requests'
50
                print 'graph_category lighttpd'
51
                print 'graph_vlabel requests / s'
52
                print 'graph_info Requests per second'
53
                print 'requests.label requests / s'
54
                print 'requests.type DERIVE'
55
                print 'requests.min 0'
56
        elif param == 'traffic':
57
                print 'graph_title lighttpd: traffic'
58
                print 'graph_category lighttpd'
59
                print 'graph_vlabel bytes / s'
60
                print 'graph_info Traffic in bytes per second'
61
                print 'traffic_in.label incoming'
62
                print 'traffic_in.type DERIVE'
63
                print 'traffic_in.min 0'
64
                print 'traffic_out.label outgoing'
65
                print 'traffic_out.type DERIVE'
66
                print 'traffic_out.min 0'
67
        elif param == 'connections':
68
                print 'graph_title lighttpd: connections'
69
                print 'graph_category lighttpd'
70
                print 'graph_vlabel connections'
71
                print 'graph_info Connections'
72
                print 'con_start.type GAUGE'
73
                print 'con_start.label start'
74
                print 'con_read_header.label read header'
75
                print 'con_handle_request.label handle request'
76
                print 'con_write_response.label write response'
77
                print 'con_keepalive.label keep alive'
78
                print 'con_total.label total'
79
        elif param == 'statuscodes':
80
                print 'graph_title lighttpd: status codes'
81
                print 'graph_category lighttpd'
82
                print 'graph_vlabel status codes'
83
                print 'graph_info Response status codes'
84
                print 'status_1xx.label 1xx (info)'
85
                print 'status_1xx.type DERIVE'
86
                print 'status_1xx.min 0'
87
                print 'status_2xx.label 2xx (success)'
88
                print 'status_2xx.type DERIVE'
89
                print 'status_2xx.min 0'
90
                print 'status_3xx.label 3xx (redirect)'
91
                print 'status_3xx.type DERIVE'
92
                print 'status_3xx.min 0'
93
                print 'status_4xx.label 4xx (client error)'
94
                print 'status_4xx.type DERIVE'
95
                print 'status_4xx.min 0'
96
                print 'status_5xx.label 5xx (server error)'
97
                print 'status_5xx.type DERIVE'
98
                print 'status_5xx.min 0'
99

    
100
def print_status(param):
101
        global STATUS_URL
102
        statuslist = urllib2.urlopen(STATUS_URL).readlines()
103

    
104
        for entry in statuslist:
105
                if len(entry) == 1 or entry[0] == '#':
106
                        continue
107
                key, value = entry.split(': ')
108
                if param == 'requests' and key == 'requests_abs':
109
                        print 'requests.value %s' % (value)
110
                elif param == 'traffic':
111
                        if key == 'traffic_out_abs':
112
                                print 'traffic_out.value %s' % (value)
113
                        elif key == 'traffic_in_abs':
114
                                print 'traffic_in.value %s' % (value)
115
                elif param == 'connections':
116
                        if key == 'connections_abs':
117
                                print 'con_total.value %s' % (value)
118
                        if key == 'connection_state_start':
119
                                print 'con_start.value %s' % (value)
120
                        elif key == 'connection_state_read_header':
121
                                print 'con_read_header.value %s' % (value)
122
                        elif key == 'connection_state_handle_request':
123
                                print 'con_handle_request.value %s' % (value)
124
                        elif key == 'connection_state_write_response':
125
                                print 'con_write_response.value %s' % (value)
126
                        elif key == 'connection_state_keep_alive':
127
                                print 'con_keepalive.value %s' % (value)
128
                elif param == 'statuscodes':
129
                        if key == 'status_1xx':
130
                                print 'status_1xx.value %s' % (value)
131
                        elif key == 'status_2xx':
132
                                print 'status_2xx.value %s' % (value)
133
                        elif key == 'status_3xx':
134
                                print 'status_3xx.value %s' % (value)
135
                        elif key == 'status_4xx':
136
                                print 'status_4xx.value %s' % (value)
137
                        elif key == 'status_5xx':
138
                                print 'status_5xx.value %s' % (value)
139

    
140
if __name__ == '__main__':
141
        try:
142
                param = os.path.split(sys.argv[0])[-1].split('_')[1]
143
        except IndexError:
144
                param = 'requests'
145

    
146
        if param not in ['requests', 'traffic', 'connections', 'statuscodes']:
147
                print 'unknown parameter %s' % (param)
148
                sys.exit(1)
149

    
150
        if len(sys.argv) > 1:
151
                if sys.argv[1] == 'autoconf':
152
                        print 'yes'
153
                        sys.exit(0)
154
                elif sys.argv[1] == 'config':
155
                        print_config(param)
156
                        sys.exit(0)
157

    
158
        print_status(param)