gnu: waybar: Fix build.
[jackhill/guix/guix.git] / gnu / services / monitoring.scm
CommitLineData
693b52df
SB
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2018 Sou Bunnbu <iyzsong@member.fsf.org>
0f9bbd32 3;;; Copyright © 2018, 2019 Gábor Boskovits <boskovits@gmail.com>
e44de1d2 4;;; Copyright © 2018, 2019 Oleg Pykhalov <go.wigust@gmail.com>
693b52df
SB
5;;;
6;;; This file is part of GNU Guix.
7;;;
8;;; GNU Guix is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; GNU Guix is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21(define-module (gnu services monitoring)
22 #:use-module (gnu services)
6b1c4179 23 #:use-module (gnu services configuration)
693b52df 24 #:use-module (gnu services shepherd)
85c07cff 25 #:use-module (gnu services web)
693b52df
SB
26 #:use-module (gnu packages admin)
27 #:use-module (gnu packages monitoring)
28 #:use-module (gnu system shadow)
29 #:use-module (guix gexp)
6b1c4179 30 #:use-module (guix packages)
693b52df 31 #:use-module (guix records)
e44de1d2
OP
32 #:use-module (guix utils)
33 #:use-module ((guix ui) #:select (display-hint G_))
693b52df 34 #:use-module (ice-9 match)
85c07cff 35 #:use-module (ice-9 rdelim)
6b1c4179 36 #:use-module (srfi srfi-26)
0485717e 37 #:use-module (srfi srfi-35)
693b52df 38 #:export (darkstat-configuration
a33652ee
GB
39 prometheus-node-exporter-configuration
40 darkstat-service-type
6b1c4179
OP
41 prometheus-node-exporter-service-type
42
43 zabbix-server-configuration
6106d7ca
OP
44 zabbix-server-service-type
45 zabbix-agent-configuration
85c07cff
OP
46 zabbix-agent-service-type
47 zabbix-front-end-configuration
48 zabbix-front-end-service-type
49 %zabbix-front-end-configuration-nginx))
693b52df
SB
50
51\f
52;;;
53;;; darkstat
54;;;
55
56(define-record-type* <darkstat-configuration>
57 darkstat-configuration make-darkstat-configuration darkstat-configuration?
58 (package darkstat-configuration-package
59 (default darkstat))
60 (interface darkstat-configuration-interface)
61 (port darkstat-configuration-port
62 (default "667"))
63 (bind-address darkstat-configuration-bind-address
64 (default "127.0.0.1"))
65 (base darkstat-configuration-base
66 (default "/")))
67
68(define %darkstat-accounts
69 (list (user-account
70 (name "darkstat")
71 (group "darkstat")
72 (system? #t)
73 (comment "darkstat daemon user")
74 (home-directory "/var/lib/darkstat")
75 (shell (file-append shadow "/sbin/nologin")))
76 (user-group
77 (name "darkstat")
78 (system? #t))))
79
80(define darkstat-shepherd-service
81 (match-lambda
82 (($ <darkstat-configuration>
83 package interface port bind-address base)
84 (shepherd-service
85 (documentation "Network statistics gatherer.")
86 (provision '(darkstat))
87 (requirement '(networking))
88 (start #~(make-forkexec-constructor
89 (list #$(file-append package "/sbin/darkstat")
90 "-i" #$interface
91 "-p" #$port
92 "-b" #$bind-address
93 "--base" #$base
94 "--syslog" "--no-daemon"
95 "--chroot" "/var/lib/darkstat"
96 "--user" "darkstat"
97 "--import" "darkstat.db"
98 "--export" "darkstat.db")))
99 (stop #~(make-kill-destructor))))))
100
101(define darkstat-service-type
102 (service-type
103 (name 'darkstat)
104 (description
f3a2c297 105 "Run @command{darkstat} to serve network traffic statistics reports over
693b52df
SB
106HTTP.")
107 (extensions
108 (list (service-extension account-service-type
109 (const %darkstat-accounts))
110 (service-extension shepherd-root-service-type
111 (compose list darkstat-shepherd-service))))))
a33652ee
GB
112
113(define-record-type* <prometheus-node-exporter-configuration>
114 prometheus-node-exporter-configuration
115 make-prometheus-node-exporter-configuration
116 prometheus-node-exporter-configuration?
117 (package prometheus-node-exporter-configuration-package
118 (default go-github-com-prometheus-node-exporter))
119 (web-listen-address prometheus-node-exporter-web-listen-address
120 (default ":9100")))
121
122(define prometheus-node-exporter-shepherd-service
123 (match-lambda
124 (( $ <prometheus-node-exporter-configuration>
125 package web-listen-address)
126 (shepherd-service
127 (documentation "Prometheus node exporter.")
128 (provision '(prometheus-node-exporter))
129 (requirement '(networking))
130 (start #~(make-forkexec-constructor
131 (list #$(file-append package "/bin/node_exporter")
132 "--web.listen-address" #$web-listen-address)))
133 (stop #~(make-kill-destructor))))))
134
135(define prometheus-node-exporter-service-type
136 (service-type
137 (name 'prometheus-node-exporter)
138 (description
139 "Run @command{node_exporter} to serve hardware and OS metrics to
140prometheus.")
141 (extensions
142 (list (service-extension
143 shepherd-root-service-type
4074ee4e
GB
144 (compose list prometheus-node-exporter-shepherd-service))))
145 (default-value (prometheus-node-exporter-configuration))))
6b1c4179
OP
146
147\f
148;;;
149;;; Zabbix server
150;;;
151
152(define (uglify-field-name field-name)
153 (apply string-append
154 (map (lambda (str)
155 (if (member (string->symbol str) '(ca db ssl))
156 (string-upcase str)
157 (string-capitalize str)))
158 (string-split (string-delete #\?
159 (symbol->string field-name))
160 #\-))))
161
162(define (serialize-field field-name val)
163 (format #t "~a=~a~%" (uglify-field-name field-name) val))
164
165(define (serialize-number field-name val)
166 (serialize-field field-name (number->string val)))
167
168(define (serialize-list field-name val)
169 (if (null? val) "" (serialize-field field-name (string-join val ","))))
170
171(define (serialize-string field-name val)
172 (if (and (string? val) (string=? val ""))
173 ""
174 (serialize-field field-name val)))
175
176(define group? string?)
177
178(define serialize-group
179 (const ""))
180
181(define include-files? list?)
182
183(define (serialize-include-files field-name val)
184 (if (null? val) "" (for-each (cut serialize-field 'include <>) val)))
185
186(define extra-options? string?)
187
188(define (serialize-extra-options field-name val)
189 (if (null? val) "" (display val)))
190
85c07cff
OP
191(define (nginx-server-configuration-list? val)
192 (and (list? val) (and-map nginx-server-configuration? val)))
193
194(define (serialize-nginx-server-configuration-list field-name val)
195 "")
196
6b1c4179
OP
197(define-configuration zabbix-server-configuration
198 (zabbix-server
199 (package zabbix-server)
200 "The zabbix-server package.")
201 (user
202 (string "zabbix")
203 "User who will run the Zabbix server.")
204 (group ;for zabbix-server-account procedure
205 (group "zabbix")
206 "Group who will run the Zabbix server.")
207 (db-host
208 (string "127.0.0.1")
209 "Database host name.")
210 (db-name
211 (string "zabbix")
212 "Database name.")
213 (db-user
214 (string "zabbix")
215 "Database user.")
216 (db-password
217 (string "")
218 "Database password. Please, use @code{include-files} with
219@code{DBPassword=SECRET} inside a specified file instead.")
220 (db-port
221 (number 5432)
222 "Database port.")
223 (log-type
224 (string "")
225 "Specifies where log messages are written to:
226@itemize
227@item @code{system} - syslog.
228@item @code{file} - file specified with @code{log-file} parameter.
229@item @code{console} - standard output.
230@end itemize\n")
231 (log-file
232 (string "/var/log/zabbix/server.log")
233 "Log file name for @code{log-type} @code{file} parameter.")
234 (pid-file
235 (string "/var/run/zabbix/zabbix_server.pid")
236 "Name of PID file.")
237 (ssl-ca-location
238 (string "/etc/ssl/certs/ca-certificates.crt")
239 "The location of certificate authority (CA) files for SSL server
240certificate verification.")
241 (ssl-cert-location
242 (string "/etc/ssl/certs")
243 "Location of SSL client certificates.")
244 (extra-options
245 (extra-options "")
246 "Extra options will be appended to Zabbix server configuration file.")
247 (include-files
248 (include-files '())
249 "You may include individual files or all files in a directory in the
250configuration file."))
251
252(define (zabbix-server-account config)
253 "Return the user accounts and user groups for CONFIG."
254 (let ((zabbix-user (zabbix-server-configuration-user config))
255 (zabbix-group (zabbix-server-configuration-group config)))
256 (list (user-group (name zabbix-group) (system? #t))
257 (user-account
258 (name zabbix-user)
259 (system? #t)
260 (group zabbix-group)
261 (comment "zabbix privilege separation user")
262 (home-directory (string-append "/var/run/" zabbix-user))
56a93cb9 263 (shell (file-append shadow "/sbin/nologin"))))))
6b1c4179
OP
264
265(define (zabbix-server-config-file config)
266 "Return the zabbix-server configuration file corresponding to CONFIG."
267 (computed-file
268 "zabbix_server.conf"
269 #~(begin
270 (call-with-output-file #$output
271 (lambda (port)
272 (display "# Generated by 'zabbix-server-service'.\n" port)
273 (display #$(with-output-to-string
274 (lambda ()
275 (serialize-configuration
276 config zabbix-server-configuration-fields)))
277 port)
278 #t)))))
279
280(define (zabbix-server-activation config)
281 "Return the activation gexp for CONFIG."
282 (with-imported-modules '((guix build utils)
283 (ice-9 rdelim))
284 #~(begin
285 (use-modules (guix build utils)
286 (ice-9 rdelim))
287 (let ((user (getpw #$(zabbix-server-configuration-user config))))
288 (for-each (lambda (file)
289 (let ((directory (dirname file)))
290 (mkdir-p directory)
291 (chown directory (passwd:uid user) (passwd:gid user))
292 (chmod directory #o755)))
293 (list #$(zabbix-server-configuration-log-file config)
294 #$(zabbix-server-configuration-pid-file config)
295 "/etc/zabbix/maintenance.inc.php"))))))
296
297(define (zabbix-server-shepherd-service config)
298 "Return a <shepherd-service> for Zabbix server with CONFIG."
299 (list (shepherd-service
300 (provision '(zabbix-server))
301 (documentation "Run Zabbix server daemon.")
302 (start #~(make-forkexec-constructor
303 (list #$(file-append (zabbix-server-configuration-zabbix-server config)
304 "/sbin/zabbix_server")
305 "--config" #$(zabbix-server-config-file config)
306 "--foreground")
307 #:user #$(zabbix-server-configuration-user config)
308 #:group #$(zabbix-server-configuration-group config)
309 #:pid-file #$(zabbix-server-configuration-pid-file config)
310 #:environment-variables
311 (list "SSL_CERT_DIR=/run/current-system/profile\
312/etc/ssl/certs"
313 "SSL_CERT_FILE=/run/current-system/profile\
314/etc/ssl/certs/ca-certificates.crt")))
315 (stop #~(make-kill-destructor)))))
316
317(define zabbix-server-service-type
318 (service-type
319 (name 'zabbix-server)
320 (extensions
321 (list (service-extension shepherd-root-service-type
322 zabbix-server-shepherd-service)
323 (service-extension account-service-type
324 zabbix-server-account)
325 (service-extension activation-service-type
326 zabbix-server-activation)))
327 (default-value (zabbix-server-configuration))))
328
329(define (generate-zabbix-server-documentation)
330 (generate-documentation
331 `((zabbix-server-configuration
332 ,zabbix-server-configuration-fields))
333 'zabbix-server-configuration))
6106d7ca
OP
334
335(define-configuration zabbix-agent-configuration
336 (zabbix-agent
337 (package zabbix-agentd)
338 "The zabbix-agent package.")
339 (user
340 (string "zabbix")
341 "User who will run the Zabbix agent.")
342 (group
343 (group "zabbix")
344 "Group who will run the Zabbix agent.")
345 (hostname
346 (string "Zabbix server")
347 "Unique, case sensitive hostname which is required for active checks and
348must match hostname as configured on the server.")
349 (log-type
350 (string "")
351 "Specifies where log messages are written to:
352@itemize
353@item @code{system} - syslog.
354@item @code{file} - file specified with @code{log-file} parameter.
355@item @code{console} - standard output.
356@end itemize\n")
357 (log-file
358 (string "/var/log/zabbix/agent.log")
359 "Log file name for @code{log-type} @code{file} parameter.")
360 (pid-file
361 (string "/var/run/zabbix/zabbix_agent.pid")
362 "Name of PID file.")
363 (server
364 (list '("127.0.0.1"))
365 "List of IP addresses, optionally in CIDR notation, or hostnames of Zabbix
366servers and Zabbix proxies. Incoming connections will be accepted only from
367the hosts listed here.")
368 (server-active
369 (list '("127.0.0.1"))
370 "List of IP:port (or hostname:port) pairs of Zabbix servers and Zabbix
371proxies for active checks. If port is not specified, default port is used.
372If this parameter is not specified, active checks are disabled.")
373 (extra-options
85c07cff 374 (extra-options "")
6106d7ca
OP
375 "Extra options will be appended to Zabbix server configuration file.")
376 (include-files
377 (include-files '())
378 "You may include individual files or all files in a directory in the
379configuration file."))
380
381(define (zabbix-agent-account config)
382 "Return the user accounts and user groups for CONFIG."
383 (let ((zabbix-user "zabbix")
384 (zabbix-group "zabbix"))
385 (list (user-group (name zabbix-group) (system? #t))
386 (user-account
387 (name zabbix-user)
388 (system? #t)
389 (group zabbix-group)
390 (comment "zabbix privilege separation user")
391 (home-directory (string-append "/var/run/" zabbix-user))
56a93cb9 392 (shell (file-append shadow "/sbin/nologin"))))))
6106d7ca
OP
393
394(define (zabbix-agent-activation config)
395 "Return the activation gexp for CONFIG."
396 (with-imported-modules '((guix build utils)
397 (ice-9 rdelim))
398 #~(begin
399 (use-modules (guix build utils)
400 (ice-9 rdelim))
401 (let ((user
402 (getpw #$(zabbix-agent-configuration-user config))))
403 (for-each (lambda (file)
404 (let ((directory (dirname file)))
405 (mkdir-p directory)
406 (chown directory (passwd:uid user) (passwd:gid user))
407 (chmod directory #o755)))
408 (list #$(zabbix-agent-configuration-log-file config)
409 #$(zabbix-agent-configuration-pid-file config)))))))
410
411(define (zabbix-agent-config-file config)
412 "Return the zabbix-agent configuration file corresponding to CONFIG."
413 (computed-file
414 "zabbix_agent.conf"
415 #~(begin
416 (call-with-output-file #$output
417 (lambda (port)
418 (display "# Generated by 'zabbix-agent-service'.\n" port)
419 (display #$(with-output-to-string
420 (lambda ()
421 (serialize-configuration
422 config zabbix-agent-configuration-fields)))
423 port)
424 #t)))))
425
426(define (zabbix-agent-shepherd-service config)
427 "Return a <shepherd-service> for Zabbix agent with CONFIG."
428 (list (shepherd-service
429 (provision '(zabbix-agent))
430 (documentation "Run Zabbix agent daemon.")
431 (start #~(make-forkexec-constructor
432 (list #$(file-append (zabbix-agent-configuration-zabbix-agent config)
433 "/sbin/zabbix_agentd")
434 "--config" #$(zabbix-agent-config-file config)
435 "--foreground")
436 #:user #$(zabbix-agent-configuration-user config)
437 #:group #$(zabbix-agent-configuration-group config)
438 #:pid-file #$(zabbix-agent-configuration-pid-file config)
439 #:environment-variables
440 (list "SSL_CERT_DIR=/run/current-system/profile\
441/etc/ssl/certs"
442 "SSL_CERT_FILE=/run/current-system/profile\
443/etc/ssl/certs/ca-certificates.crt")))
444 (stop #~(make-kill-destructor)))))
445
446(define zabbix-agent-service-type
447 (service-type
448 (name 'zabbix-agent)
449 (extensions
450 (list (service-extension shepherd-root-service-type
451 zabbix-agent-shepherd-service)
452 (service-extension account-service-type
453 zabbix-agent-account)
454 (service-extension activation-service-type
455 zabbix-agent-activation)))
456 (default-value (zabbix-agent-configuration))))
457
458(define (generate-zabbix-agent-documentation)
459 (generate-documentation
460 `((zabbix-agent-configuration
461 ,zabbix-agent-configuration-fields))
462 'zabbix-agent-configuration))
85c07cff
OP
463
464(define %zabbix-front-end-configuration-nginx
465 (nginx-server-configuration
466 (root #~(string-append #$zabbix-server:front-end "/share/zabbix/php"))
467 (index '("index.php"))
468 (locations
469 (let ((php-location (nginx-php-location)))
470 (list (nginx-location-configuration
471 (inherit php-location)
472 (body (append (nginx-location-configuration-body php-location)
473 (list "
474fastcgi_param PHP_VALUE \"post_max_size = 16M
475 max_execution_time = 300\";
13f0414e
OP
476")))))))
477 (listen '("80"))))
85c07cff
OP
478
479(define-configuration zabbix-front-end-configuration
480 ;; TODO: Specify zabbix front-end package.
481 ;; (zabbix-
482 ;; (package zabbix-front-end)
483 ;; "The zabbix-front-end package.")
484 (nginx
485 (nginx-server-configuration-list
486 (list %zabbix-front-end-configuration-nginx))
487 "NGINX configuration.")
488 (db-host
489 (string "localhost")
490 "Database host name.")
491 (db-port
492 (number 5432)
493 "Database port.")
494 (db-name
495 (string "zabbix")
496 "Database name.")
497 (db-user
498 (string "zabbix")
499 "Database user.")
500 (db-password
501 (string "")
502 "Database password. Please, use @code{db-secret-file} instead.")
503 (db-secret-file
504 (string "")
505 "Secret file which will be appended to @file{zabbix.conf.php} file. This
506file contains credentials for use by Zabbix front-end. You are expected to
507create it manually.")
508 (zabbix-host
509 (string "localhost")
510 "Zabbix server hostname.")
511 (zabbix-port
512 (number 10051)
513 "Zabbix server port."))
514
e44de1d2
OP
515(define (zabbix-front-end-config config)
516 (match-record config <zabbix-front-end-configuration>
517 (%location db-host db-port db-name db-user db-password db-secret-file
518 zabbix-host zabbix-port)
519 (mixed-text-file "zabbix.conf.php"
520 "\
85c07cff
OP
521<?php
522// Zabbix GUI configuration file.
523global $DB;
524
525$DB['TYPE'] = 'POSTGRESQL';
526$DB['SERVER'] = '" db-host "';
527$DB['PORT'] = '" (number->string db-port) "';
528$DB['DATABASE'] = '" db-name "';
529$DB['USER'] = '" db-user "';
e44de1d2
OP
530$DB['PASSWORD'] = '" (let ((file (location-file %location))
531 (line (location-line %location))
532 (column (location-column %location)))
533 (if (string-null? db-password)
534 (if (string-null? db-secret-file)
535 (raise (make-compound-condition
536 (condition
537 (&message
538 (message
539 (format #f "no '~A' or '~A' field in your '~A' record"
540 'db-secret-file 'db-password
541 'zabbix-front-end-configuration))))
542 (condition
543 (&error-location
544 (location %location)))))
545 (string-trim-both
546 (with-input-from-file db-secret-file
547 read-string)))
548 (begin
549 (display-hint (format #f (G_ "~a:~a:~a: ~a:
550Consider using @code{db-secret-file} instead of @code{db-password} for better
551security.") file line column 'zabbix-front-end-configuration))
552 db-password))) "';
85c07cff
OP
553
554// Schema name. Used for IBM DB2 and PostgreSQL.
555$DB['SCHEMA'] = '';
556
557$ZBX_SERVER = '" zabbix-host "';
558$ZBX_SERVER_PORT = '" (number->string zabbix-port) "';
559$ZBX_SERVER_NAME = '';
560
561$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
e44de1d2 562")))
85c07cff
OP
563
564(define %maintenance.inc.php
565 ;; Empty php file to allow us move zabbix-frontend configs to ‘/etc/zabbix’
566 ;; directory. See ‘install-front-end’ phase in
567 ;; (@ (gnu packages monitoring) zabbix-server) package.
568 "\
569<?php
570")
571
572(define (zabbix-front-end-activation config)
573 "Return the activation gexp for CONFIG."
574 #~(begin
575 (use-modules (guix build utils))
576 (mkdir-p "/etc/zabbix")
577 (call-with-output-file "/etc/zabbix/maintenance.inc.php"
578 (lambda (port)
579 (display #$%maintenance.inc.php port)))
580 (copy-file #$(zabbix-front-end-config config)
581 "/etc/zabbix/zabbix.conf.php")))
582
583(define zabbix-front-end-service-type
584 (service-type
585 (name 'zabbix-front-end)
586 (extensions
587 (list (service-extension activation-service-type
588 zabbix-front-end-activation)
589 (service-extension nginx-service-type
590 zabbix-front-end-configuration-nginx)
591 ;; Make sure php-fpm is instantiated.
592 (service-extension php-fpm-service-type
593 (const #t))))
594 (default-value (zabbix-front-end-configuration))
595 (description
596 "Run the zabbix-front-end web interface, which allows users to interact
597with Zabbix server.")))
598
599(define (generate-zabbix-front-end-documentation)
600 (generate-documentation
601 `((zabbix-front-end-configuration
602 ,zabbix-front-end-configuration-fields))
603 'zabbix-front-end-configuration))